[OFBiz] SVN: r6882 - in trunk/applications/order: script/org/ofbiz/order/order src/org/ofbiz/order/order
sichen@svn.ofbiz.org
sichen at svn.ofbiz.org
Wed Mar 1 18:54:30 CST 2006
Author: sichen
Date: 2006-03-01 18:54:19 -0600 (Wed, 01 Mar 2006)
New Revision: 6882
Modified:
trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml
trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java
Log:
Update to create return invoices and payment applications for those invoices. When a return is received, an invoice for it will autmoatically be created and then payment applications will be allocated. This feature now works and is ready for the next phase of development.
Modified: trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml
===================================================================
--- trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml 2006-03-02 00:25:51 UTC (rev 6881)
+++ trunk/applications/order/script/org/ofbiz/order/order/OrderReturnServices.xml 2006-03-02 00:54:19 UTC (rev 6882)
@@ -166,6 +166,7 @@
</call-service>
<log level="info" message="Available amount for return on order #${returnItem.orderId} is [${availableReturnTotal}] (orderTotal = [${orderTotal}] - returnTotal = [${returnTotal}]"/>
+ <!-- TODO: we need to replace this eventually with BigDecimal math -->
<if-compare field-name="availableReturnTotal" operator="less" value="-0.01" type="Double">
<add-error><fail-property resource="OrderErrorUiLabels" property="OrderReturnPriceCannotExceedTheOrderTotal"/></add-error>
</if-compare>
@@ -453,6 +454,7 @@
<remove-value value-name="returnAdjustment"/>
</if-not-empty>
</simple-method>
+ <!-- note that this service is designed to be called once for each shipment receipt that is created -->
<simple-method method-name="updateReturnStatusFromReceipt" short-description="Update Return Status From ShipmentReceipt">
<check-permission permission="ORDERMGR" action="_UPDATE"><fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunUpdateReturnHeader"/></check-permission>
<check-errors/>
@@ -476,13 +478,6 @@
<set from-field="receipt.returnItemSeqId" field="newLookupMap.returnItemSeqId"/>
<find-by-primary-key entity-name="ReturnItem" map-name="newLookupMap" value-name="returnItem"/>
<if-compare-field field-name="returnQuantity" map-name="returnItem" operator="greater-equals" to-field-name="${receipt.returnItemSeqId}" to-map-name="totalsMap" type="Double">
- <!-- Set the shipment status to PURCH_SHIP_RECEIVED if it isn't already, that way the invoices get generated here along with whatever else needs to be -->
- <get-related-one relation-name="Shipment" value-name="receipt" to-value-name="shipment"/>
- <if-compare field-name="statusId" map-name="shipment" operator="not-equals" value="RETURN_RECEIVED">
- <set field="serviceInput.shipmentId" from-field="shipment.shipmentId"/>
- <set field="serviceInput.statusId" value="PURCH_SHIP_RECEIVED"/>
- <call-service service-name="updateShipment" in-map-name="serviceInput"/>
- </if-compare>
<!-- update the status for the item -->
<set field="returnItem.statusId" value="RETURN_RECEIVED"/>
<store-value value-name="returnItem"/>
@@ -513,7 +508,22 @@
</if-not-empty>
</if-compare>
</iterate>
+
+ <!-- if the items are all received, then update the return header, store the status history change, and set the shipment to received -->
<if-compare field-name="allReceived" operator="equals" value="true">
+
+ <!-- Go through all the items yet again and set their shipment status to PURCH_SHIP_RECEIVED (if it isn't already)
+ This activates SECAS such as creating return invoices. This MUST be done before updating the return header so that
+ the ReturnItemBillings are created and then whatever SECA binds to the return header update will have them. . -->
+ <iterate list-name="shipmentReceipts" entry-name="receipt">
+ <get-related-one relation-name="Shipment" value-name="receipt" to-value-name="shipment"/>
+ <if-compare field-name="statusId" map-name="shipment" operator="not-equals" value="RETURN_RECEIVED">
+ <set field="serviceInput.shipmentId" from-field="shipment.shipmentId"/>
+ <set field="serviceInput.statusId" value="PURCH_SHIP_RECEIVED"/>
+ <call-service service-name="updateShipment" in-map-name="serviceInput"/>
+ </if-compare>
+ </iterate>
+
<!-- update the return header -->
<set field="returnHeaderCtx.statusId" value="RETURN_RECEIVED"/>
<set from-field="returnHeader.returnId" field="returnHeaderCtx.returnId"/>
Modified: trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java
===================================================================
--- trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java 2006-03-02 00:25:51 UTC (rev 6881)
+++ trunk/applications/order/src/org/ofbiz/order/order/OrderReturnServices.java 2006-03-02 00:54:19 UTC (rev 6882)
@@ -902,6 +902,8 @@
GenericDelegator delegator = dctx.getDelegator();
GenericValue userLogin = (GenericValue) context.get("userLogin");
+ // the strategy for this service is to get a list of return invoices via the return items -> return item billing relationships
+ // then split up the responseAmount among the invoices evenly
String responseId = (String) context.get("returnItemResponseId");
String errorMsg = "Failed to create payment applications for return item response [" + responseId + "]. ";
try {
@@ -909,47 +911,60 @@
if (response == null) {
return ServiceUtil.returnError(errorMsg + "Return Item Response not found with ID [" + responseId + "].");
}
- BigDecimal maxAmount = response.getBigDecimal("responseAmount").setScale(decimals, rounding);
+ BigDecimal responseAmount = response.getBigDecimal("responseAmount").setScale(decimals, rounding);
String paymentId = response.getString("paymentId");
- // for each return item in the response, get the list of return item billings
- BigDecimal runningTotal = ZERO;
+ // for each return item in the response, get the list of return item billings and then a list of invoices
+ Map returnInvoices = FastMap.newInstance(); // key is invoiceId, value is Invoice GenericValue
List items = response.getRelated("ReturnItem");
for (Iterator itemIter = items.iterator(); itemIter.hasNext(); ) {
GenericValue item = (GenericValue) itemIter.next();
-
List billings = item.getRelated("ReturnItemBilling");
for (Iterator billIter = billings.iterator(); billIter.hasNext(); ) {
GenericValue billing = (GenericValue) billIter.next();
+ GenericValue invoice = billing.getRelatedOne("Invoice");
- // the amount to apply is the billing amount * quantity
- BigDecimal amountApplied = billing.getBigDecimal("amount").multiply(billing.getBigDecimal("quantity")).setScale(decimals, rounding);
-
- // if the total plus the amount applied exceeds the maxAmount, then apply what we can
- if (runningTotal.add(amountApplied).compareTo(maxAmount) == 1) {
- amountApplied = maxAmount.subtract(runningTotal);
- if (Debug.verboseOn()) { Debug.logInfo("Exceeded responseAmount, capping off the PaymentApplication.ammountApplied with remainder.", module); }
+ // put the invoice in the map if it doesn't already exist (a very loopy way of doing group by invoiceId without creating a view)
+ if (returnInvoices.get(invoice.getString("invoiceId")) == null) {
+ returnInvoices.put(invoice.getString("invoiceId"), invoice);
}
+ }
+ }
- // create a payment application for the billing
- Map input = UtilMisc.toMap("paymentId", paymentId, "invoiceId", billing.getString("invoiceId"),
- "invoiceItemSeqId", billing.getString("invoiceItemSeqId"));
- input.put("amountApplied", new Double(amountApplied.doubleValue()));
- input.put("userLogin", userLogin);
- Map serviceResults = dispatcher.runSync("createPaymentApplication", input);
- if (ServiceUtil.isError(serviceResults)) {
- return ServiceUtil.returnError(errorMsg, null, null, serviceResults);
- }
- if (Debug.verboseOn()) { Debug.logInfo("Created PaymentApplication for response with amountApplied " + amountApplied.toString(), module); }
+ // for each return invoice found, sum up the related billings
+ Map invoiceTotals = FastMap.newInstance(); // key is invoiceId, value is the sum of all billings for that invoice
+ BigDecimal grandTotal = ZERO; // The sum of all return invoice totals
+ for (Iterator iter = returnInvoices.values().iterator(); iter.hasNext(); ) {
+ GenericValue invoice = (GenericValue) iter.next();
- // keep a running total
- runningTotal = runningTotal.add(amountApplied);
+ List billings = invoice.getRelated("ReturnItemBilling");
+ BigDecimal runningTotal = ZERO;
+ for (Iterator billIter = billings.iterator(); billIter.hasNext(); ) {
+ GenericValue billing = (GenericValue) billIter.next();
+ runningTotal = runningTotal.add(billing.getBigDecimal("amount").multiply(billing.getBigDecimal("quantity")).setScale(decimals, rounding));
+ }
- // we're done if we have no more to apply
- if (runningTotal.compareTo(maxAmount) == 1) {
- return ServiceUtil.returnSuccess();
- }
+ invoiceTotals.put(invoice.getString("invoiceId"), runningTotal);
+ grandTotal = grandTotal.add(runningTotal);
+ }
+
+ // now allocate responseAmount * invoiceTotal / grandTotal to each invoice
+ for (Iterator iter = returnInvoices.values().iterator(); iter.hasNext(); ) {
+ GenericValue invoice = (GenericValue) iter.next();
+ String invoiceId = invoice.getString("invoiceId");
+ BigDecimal invoiceTotal = (BigDecimal) invoiceTotals.get(invoiceId);
+
+ BigDecimal amountApplied = responseAmount.multiply(invoiceTotal).divide(grandTotal, decimals, rounding).setScale(decimals, rounding);
+
+ // create a payment application for the invoice
+ Map input = UtilMisc.toMap("paymentId", paymentId, "invoiceId", invoice.getString("invoiceId"));
+ input.put("amountApplied", new Double(amountApplied.doubleValue()));
+ input.put("userLogin", userLogin);
+ Map serviceResults = dispatcher.runSync("createPaymentApplication", input);
+ if (ServiceUtil.isError(serviceResults)) {
+ return ServiceUtil.returnError(errorMsg, null, null, serviceResults);
}
+ if (Debug.verboseOn()) { Debug.logInfo("Created PaymentApplication for response with amountApplied " + amountApplied.toString(), module); }
}
} catch (GenericServiceException e) {
Debug.logError(e, errorMsg + e.getMessage(), module);
More information about the Svn
mailing list