Hi,

We had a problem with creating invoices for orders with cancelled items. The 
pro-rating of the order adjustments didn't work as expected. 

In the createInvoiceForOrder the billingQuantity passed to the service takes 
into account the cancelQuantity, whereas the quantity from the original order 
item used to prorate the order adjustment amount does not. The following patch 
changes this. It also calls OrderReadHelper.getOrderItemQuantity() like done 
for the billItem orderItem now to consider the cancelQuantity. 

I'm not quite sure this doesn't break anything else. Maybe there was a reason 
not to take the cancelQuantity into account here.
What do you think?

Martin



Index: 
applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java
===================================================================
--- 
applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java   
    (Revision 1084088)
+++ 
applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceServices.java   
    (Arbeitskopie)
@@ -522,27 +522,30 @@
                         continue;
                     }
 
+                    BigDecimal originalOrderItemQuantity = 
OrderReadHelper.getOrderItemQuantity(originalOrderItem);
                     BigDecimal amount = ZERO;
-                    if (adj.get("amount") != null) {
-                        // pro-rate the amount
-                        // set decimals = 100 means we don't round this 
intermediate value, which is very important
-                        amount = 
adj.getBigDecimal("amount").divide(originalOrderItem.getBigDecimal("quantity"), 
100, ROUNDING);
-                        amount = amount.multiply(billingQuantity);
-                        // Tax needs to be rounded differently from other 
order adjustments
-                        if 
(adj.getString("orderAdjustmentTypeId").equals("SALES_TAX")) {
-                            amount = amount.setScale(TAX_DECIMALS, 
TAX_ROUNDING);
-                        } else {
+                    if (originalOrderItemQuantity.signum() != 0) {
+                        if (adj.get("amount") != null) {
+                            // pro-rate the amount
+                            // set decimals = 100 means we don't round this 
intermediate value, which is very important
+                            amount = 
adj.getBigDecimal("amount").divide(originalOrderItemQuantity, 100, ROUNDING);
+                            amount = amount.multiply(billingQuantity);
+                            // Tax needs to be rounded differently from other 
order adjustments
+                            if 
(adj.getString("orderAdjustmentTypeId").equals("SALES_TAX")) {
+                                amount = amount.setScale(TAX_DECIMALS, 
TAX_ROUNDING);
+                            } else {
+                                amount = amount.setScale(invoiceTypeDecimals, 
ROUNDING);
+                            }
+                        } else if (adj.get("sourcePercentage") != null) {
+                            // pro-rate the amount
+                            // set decimals = 100 means we don't round this 
intermediate value, which is very important
+                            BigDecimal percent = 
adj.getBigDecimal("sourcePercentage");
+                            percent = percent.divide(new BigDecimal(100), 100, 
ROUNDING);
+                            amount = billingAmount.multiply(percent);
+                            amount = amount.divide(originalOrderItemQuantity, 
100, ROUNDING);
+                            amount = amount.multiply(billingQuantity);
                             amount = amount.setScale(invoiceTypeDecimals, 
ROUNDING);
                         }
-                    } else if (adj.get("sourcePercentage") != null) {
-                        // pro-rate the amount
-                        // set decimals = 100 means we don't round this 
intermediate value, which is very important
-                        BigDecimal percent = 
adj.getBigDecimal("sourcePercentage");
-                        percent = percent.divide(new BigDecimal(100), 100, 
ROUNDING);
-                        amount = billingAmount.multiply(percent);
-                        amount = 
amount.divide(originalOrderItem.getBigDecimal("quantity"), 100, ROUNDING);
-                        amount = amount.multiply(billingQuantity);
-                        amount = amount.setScale(invoiceTypeDecimals, 
ROUNDING);
                     }
                     if (amount.signum() != 0) {
                         Map<String, Object> createInvoiceItemAdjContext = 
FastMap.newInstance();

Reply via email to