Author: sichen
Date: Tue Jun 26 10:01:45 2007
New Revision: 550858

URL: http://svn.apache.org/viewvc?view=rev&rev=550858
Log:
Adding the getOrderItemInvoicedAmountAndQuantity service as a replacement for 
the getOrderItemValue service, and refactoring the 
getShipmentPackageValueFromOrders service to use 
getOrderItemInvoicedAmountAndQuantity. Essentially we're deriving the amount 
and quantity ever invoiced for a given order item and then prorating the 
invoiced amount by the proportion of issued quantity to invoiced quantity. This 
should result in order item values which are very close to the invoice item 
amounts related to the order item, aggregated across all invoices.

Modified:
    ofbiz/trunk/applications/order/servicedef/services.xml
    ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java
    ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml
    ofbiz/trunk/applications/product/servicedef/services_shipment.xml
    
ofbiz/trunk/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java

Modified: ofbiz/trunk/applications/order/servicedef/services.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/servicedef/services.xml?view=diff&rev=550858&r1=550857&r2=550858
==============================================================================
--- ofbiz/trunk/applications/order/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/order/servicedef/services.xml Tue Jun 26 10:01:45 
2007
@@ -675,14 +675,17 @@
         <attribute name="facilityId" type="String" mode="IN" optional="false"/>
     </service>
 
-    <service name="getOrderItemValue" engine="java"
-            location="org.ofbiz.order.order.OrderServices" 
invoke="getOrderItemValue" auth="true">
-        <description>Calculates the value of a given orderItem by totalling 
the item subtotal, any adjustments for that item, and
-            the item's share of any order-level adjustments (which is 
calculated by applying the percentage of the items total that the
-            item represents to the order-level adjustments total.</description>
+    <service name="getOrderItemInvoicedAmountAndQuantity" engine="java"
+            location="org.ofbiz.order.order.OrderServices" 
invoke="getOrderItemInvoicedAmountAndQuantity" auth="true">
+        <description>Determines the total amount invoiced for a given order 
item over all invoices by totalling the item
+            subtotal (via OrderItemBilling), any adjustments for that item 
(via OrderAdjustmentBilling), and the item's 
+            share of any order-level adjustments (that calculated by applying 
the percentage of the items total that the item represents
+            to the order-level adjustments total (also via 
OrderAdjustmentBilling). Also returns the quantity invoiced for the item over
+            all invoices, to aid in prorating.</description>
         <attribute name="orderId" type="String" mode="IN" optional="false"/>
         <attribute name="orderItemSeqId" type="String" mode="IN" 
optional="false"/>
-        <attribute name="orderItemValue" type="BigDecimal" mode="OUT" 
optional="true"/>
+        <attribute name="invoicedAmount" type="BigDecimal" mode="OUT" 
optional="false"/>
+        <attribute name="invoicedQuantity" type="BigDecimal" mode="OUT" 
optional="false"/>
     </service>
 
     <!-- order lookup services -->

Modified: 
ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java?view=diff&rev=550858&r1=550857&r2=550858
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java 
(original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/order/OrderServices.java 
Tue Jun 26 10:01:45 2007
@@ -4223,14 +4223,15 @@
     }
 
     /**
-     * Calculates the value of a given orderItem by totalling the item 
subtotal, any adjustments for that item, and
-     *  the item's share of any order-level adjustments (that calculated by 
applying the percentage of the items total that the
-     *  item represents to the order-level adjustments total.
+     * Determines the total amount invoiced for a given order item over all 
invoices by totalling the item subtotal (via OrderItemBilling),
+     *  any adjustments for that item (via OrderAdjustmentBilling), and the 
item's share of any order-level adjustments (that calculated 
+     *  by applying the percentage of the items total that the item represents 
to the order-level adjustments total (also via
+     *  OrderAdjustmentBilling). Also returns the quantity invoiced for the 
item over all invoices, to aid in prorating.
      * @param dctx DispatchContext
      * @param context Map
      * @return Map
      */
-    public static Map getOrderItemValue(DispatchContext dctx, Map context) {
+    public static Map getOrderItemInvoicedAmountAndQuantity(DispatchContext 
dctx, Map context) {
         GenericDelegator delegator = dctx.getDelegator();
         Locale locale = (Locale) context.get("locale");
         
@@ -4238,7 +4239,9 @@
         String orderItemSeqId = (String) context.get("orderItemSeqId");
 
         GenericValue orderHeader = null;
-        GenericValue orderItem = null;
+        GenericValue orderItemToCheck = null;
+        BigDecimal orderItemTotalValue = ZERO;
+        BigDecimal invoicedQuantity = ZERO; // Quantity invoiced for the 
target order item
         try {
 
             orderHeader = delegator.findByPrimaryKey("OrderHeader", 
UtilMisc.toMap("orderId", orderId));
@@ -4247,37 +4250,114 @@
                 Debug.logError(errorMessage, module);
                 return ServiceUtil.returnError(errorMessage);
             }
-            
-            orderItem = delegator.findByPrimaryKey("OrderItem", 
UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId));
-            if (UtilValidate.isEmpty(orderItem)) {
+            orderItemToCheck = delegator.findByPrimaryKey("OrderItem", 
UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId));
+            if (UtilValidate.isEmpty(orderItemToCheck)) {
                 String errorMessage = 
UtilProperties.getMessage(resource_error, "OrderErrorOrderItemNotFound", 
context, locale);
                 Debug.logError(errorMessage, module);
                 return ServiceUtil.returnError(errorMessage);
             }
             
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-            return ServiceUtil.returnError(e.getMessage());
+            BigDecimal orderItemsSubtotal = ZERO; // Aggregated value of order 
items, non-tax and non-shipping item-level adjustments
+            BigDecimal invoicedTotal = ZERO; // Amount invoiced for the target 
order item
+            BigDecimal itemAdjustments = ZERO; // Item-level tax- and 
shipping-adjustments
+
+            // Aggregate the order items subtotal
+            List orderItems = orderHeader.getRelated("OrderItem", 
UtilMisc.toList("orderItemSeqId"));
+            Iterator oit = orderItems.iterator();
+            while (oit.hasNext()) {
+                GenericValue orderItem = (GenericValue) oit.next();
+                
+                // Look at the orderItemBillings to discover the amount and 
quantity ever invoiced for this order item
+                List orderItemBillings = 
delegator.findByAnd("OrderItemBilling", UtilMisc.toMap("orderId", orderId, 
"orderItemSeqId", orderItem.get("orderItemSeqId")));
+                Iterator oibit = orderItemBillings.iterator();
+                while (oibit.hasNext()) {
+                    GenericValue orderItemBilling = (GenericValue) 
oibit.next();
+                    BigDecimal quantity = 
orderItemBilling.getBigDecimal("quantity");
+                    BigDecimal amount = 
orderItemBilling.getBigDecimal("amount").setScale(orderDecimals, orderRounding);
+                    if (UtilValidate.isEmpty(invoicedQuantity) || 
UtilValidate.isEmpty(amount)) continue;
+
+                    // Add the item base amount to the subtotal
+                    orderItemsSubtotal = 
orderItemsSubtotal.add(quantity.multiply(amount));
+                    
+                    // If the item is the target order item, add the invoiced 
quantity and amount to their respective totals
+                    if 
(orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) {
+                        invoicedQuantity = invoicedQuantity.add(quantity);
+                        invoicedTotal = 
invoicedTotal.add(quantity.multiply(amount));
         }
+                }
 
-        OrderReadHelper orh = new OrderReadHelper(orderHeader);
+                // Retrieve the adjustments for this item
+                List orderAdjustments = delegator.findByAnd("OrderAdjustment", 
UtilMisc.toMap("orderId", orderId, "orderItemSeqId", 
orderItem.get("orderItemSeqId")));
+                Iterator oait = orderAdjustments.iterator();
+                while (oait.hasNext()) {
+                    GenericValue orderAdjustment = (GenericValue) oait.next();
+                    String orderAdjustmentTypeId = 
orderAdjustment.getString("orderAdjustmentTypeId");
         
-        // How much of the order items total does this orderItem represent? 
(Includes item-level adjustments but not order-level adjustments)
-        BigDecimal orderItemTotal = orh.getOrderItemTotalBd(orderItem);
-        BigDecimal orderItemsTotal = orh.getOrderItemsTotalBd();
-        BigDecimal proportionOfOrderItemsTotal = 
orderItemTotal.divide(orderItemsTotal, orderRounding);
-        BigDecimal portionOfOrderItemsTotal = 
proportionOfOrderItemsTotal.multiply(orderItemsTotal).setScale(orderDecimals, 
orderRounding);
+                    // Look at the orderAdjustmentBillings to discove the 
amount ever invoiced for this order adjustment
+                    List orderAdjustmentBillings = 
delegator.findByAnd("OrderAdjustmentBilling", 
UtilMisc.toMap("orderAdjustmentId", orderAdjustment.get("orderAdjustmentId")));
+                    Iterator oabit = orderAdjustmentBillings.iterator();
+                    while (oabit.hasNext()) {
+                        GenericValue orderAjustmentBilling = (GenericValue) 
oabit.next();
+                        BigDecimal amount = 
orderAjustmentBilling.getBigDecimal("amount").setScale(orderDecimals, 
orderRounding);
+                        if (UtilValidate.isEmpty(amount)) continue;
         
-        // How much of the order-level adjustments total does this orderItem 
represent? The assumption is: the same
-        //  proportion of the adjustments as of the item to the items total
-        BigDecimal orderAdjustmentsTotal = orh.getOrderAdjustmentsTotalBd();
-        BigDecimal portionOfOrderAdjustmentsTotal = 
proportionOfOrderItemsTotal.multiply(orderAdjustmentsTotal).setScale(orderDecimals,
 orderRounding);
+                        if ("SALES_TAX".equals(orderAdjustmentTypeId) || 
"SHIPPING_CHARGES".equals(orderAdjustmentTypeId)) {
+                            if 
(orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) {
         
-        // The total value of the item is the value of the item itself plus 
its adjustments, and the item's share of the order-level adjustments
-        BigDecimal orderItemTotalValue = 
portionOfOrderItemsTotal.add(portionOfOrderAdjustmentsTotal);
+                                // Add tax- and shipping-adjustment amounts to 
the total adjustments for the target order item
+                                itemAdjustments = itemAdjustments.add(amount);
+                            }
+                        } else {
+
+                            // Add non-tax and non-shipping adjustment amounts 
to the order items subtotal 
+                            orderItemsSubtotal = 
orderItemsSubtotal.add(amount);
+                            if 
(orderItemSeqId.equals(orderItem.get("orderItemSeqId"))) {
+                                
+                                // If the item is the target order item, add 
non-tax and non-shipping adjustment amounts to the invoiced total
+                                invoicedTotal = invoicedTotal.add(amount);
+                            }
+                        }
+                    }
+                }
+            }
+
+            // Total the order-header-level adjustments for the order
+            BigDecimal orderHeaderAdjustmentsTotalValue = ZERO;
+            List orderHeaderAdjustments = 
delegator.findByAnd("OrderAdjustment", UtilMisc.toMap("orderId", orderId, 
"orderItemSeqId", "_NA_"));
+            Iterator ohait = orderHeaderAdjustments.iterator();
+            while (ohait.hasNext()) {
+                GenericValue orderHeaderAdjustment = (GenericValue) 
ohait.next();
+                List orderHeaderAdjustmentBillings = 
delegator.findByAnd("OrderAdjustmentBilling", 
UtilMisc.toMap("orderAdjustmentId", 
orderHeaderAdjustment.get("orderAdjustmentId")));
+                Iterator ohabit = orderHeaderAdjustmentBillings.iterator();
+                while (ohabit.hasNext()) {
+                    GenericValue orderHeaderAdjustmentBilling = (GenericValue) 
ohabit.next();
+                    BigDecimal amount = 
orderHeaderAdjustmentBilling.getBigDecimal("amount").setScale(orderDecimals, 
orderRounding);
+                    if (UtilValidate.isEmpty(amount)) continue;
+                    orderHeaderAdjustmentsTotalValue = 
orderHeaderAdjustmentsTotalValue.add(amount);
+                }
+            }
+
+            // How much of the order-level adjustments total does the target 
order item represent? The assumption is: the same
+            //  proportion of the adjustments as of the invoiced total for the 
item to the invoiced total for all items. These
+            //  figures don't take tax- and shipping- adjustments into 
account, so as to be in accordance with the code in InvoiceServices
+            BigDecimal invoicedAmountProportion = ZERO;
+            if (orderItemsSubtotal.signum() != 0) {
+                invoicedAmountProportion = 
invoicedTotal.divide(orderItemsSubtotal, 5, orderRounding);
+            }
+            BigDecimal orderItemHeaderAjustmentAmount = 
orderHeaderAdjustmentsTotalValue.multiply(invoicedAmountProportion);
+            orderItemTotalValue = 
invoicedTotal.add(orderItemHeaderAjustmentAmount);
+
+            // Add back the tax- and shipping- item-level adjustments for the 
order item
+            orderItemTotalValue = orderItemTotalValue.add(itemAdjustments);
+
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+            return ServiceUtil.returnError(e.getMessage());
+        }
 
         Map result = ServiceUtil.returnSuccess();
-        result.put("orderItemValue", orderItemTotalValue);
+        result.put("invoicedAmount", 
orderItemTotalValue.setScale(orderDecimals, orderRounding));
+        result.put("invoicedQuantity", 
invoicedQuantity.setScale(orderDecimals, orderRounding));
         return result;
     }
 }

Modified: ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml?view=diff&rev=550858&r1=550857&r2=550858
==============================================================================
--- ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml 
(original)
+++ ofbiz/trunk/applications/product/entitydef/entitymodel_shipment.xml Tue Jun 
26 10:01:45 2007
@@ -1291,6 +1291,7 @@
       <alias entity-alias="SPC" name="shipmentId"/>
       <alias entity-alias="SPC" name="shipmentPackageSeqId"/>
       <alias entity-alias="SPC" name="packedQuantity" field="quantity"/>
+      <alias entity-alias="II" name="issuedQuantity" field="quantity"/>
       <alias entity-alias="OI" name="orderId"/>
       <alias entity-alias="OI" name="orderItemSeqId"/>
       <alias entity-alias="OI" name="orderedQuantity" field="quantity"/>

Modified: ofbiz/trunk/applications/product/servicedef/services_shipment.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/services_shipment.xml?view=diff&rev=550858&r1=550857&r2=550858
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/services_shipment.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/services_shipment.xml Tue Jun 
26 10:01:45 2007
@@ -653,8 +653,8 @@
 
     <service name="getShipmentPackageValueFromOrders" engine="java"
             location="org.ofbiz.shipment.shipment.ShipmentServices" 
invoke="getShipmentPackageValueFromOrders" auth="true" use-transaction="false">
-        <description>Calculates the total value of a shipment package by 
totalling the results of the getOrderItemValue service
-            for the orderItem related to each ShipmentPackageContent, prorated 
by the quantity of the orderItem packed in the 
+        <description>Calculates the total value of a shipment package by 
totalling the results of the getOrderItemInvoicedAmountAndQuantity
+            service for the orderItem related to each ShipmentPackageContent, 
prorated by the quantity of the orderItem issued to the 
             ShipmentPackageContent. Value is converted according to the 
incoming currencyUomId.</description>
         <attribute name="shipmentId" type="String" mode="IN" optional="false"/>
         <attribute name="shipmentPackageSeqId" type="String" mode="IN" 
optional="false"/>

Modified: 
ofbiz/trunk/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java?view=diff&rev=550858&r1=550857&r2=550858
==============================================================================
--- 
ofbiz/trunk/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java
 (original)
+++ 
ofbiz/trunk/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java
 Tue Jun 26 10:01:45 2007
@@ -975,8 +975,8 @@
     }
 
     /**
-     * Calculates the total value of a shipment package by totalling the 
results of the getOrderItemValue service
-     *  for the orderItem related to each ShipmentPackageContent, prorated by 
the quantity of the orderItem packed in the 
+     * Calculates the total value of a shipment package by totalling the 
results of the getOrderItemInvoicedAmountAndQuantity
+     *  service for the orderItem related to each ShipmentPackageContent, 
prorated by the quantity of the orderItem issued to the 
      *  ShipmentPackageContent. Value is converted according to the incoming 
currencyUomId.
      * @param dctx DispatchContext
      * @param context Map
@@ -1019,18 +1019,18 @@
                 String orderId = packageContent.getString("orderId");
                 String orderItemSeqId = 
packageContent.getString("orderItemSeqId");
             
-                // Get the value of the orderItem by calling the 
getOrderItemValue service
-                Map getOrderItemValueResult = 
dispatcher.runSync("getOrderItemValue", UtilMisc.toMap("orderId", orderId, 
"orderItemSeqId", orderItemSeqId, "userLogin", userLogin, "locale", locale));
+                // Get the value of the orderItem by calling the 
getOrderItemInvoicedAmountAndQuantity service
+                Map getOrderItemValueResult = 
dispatcher.runSync("getOrderItemInvoicedAmountAndQuantity", 
UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, 
"userLogin", userLogin, "locale", locale));
                 if (ServiceUtil.isError(getOrderItemValueResult)) return 
getOrderItemValueResult;
-                BigDecimal orderItemTotalValue = (BigDecimal) 
getOrderItemValueResult.get("orderItemValue");
+                BigDecimal invoicedAmount = (BigDecimal) 
getOrderItemValueResult.get("invoicedAmount");
+                BigDecimal invoicedQuantity = (BigDecimal) 
getOrderItemValueResult.get("invoicedQuantity");
             
-                // How much of the orderItem does the packed item represent?
-                BigDecimal packedQuantity = 
packageContent.getBigDecimal("packedQuantity");
-                BigDecimal orderedQuantity = 
packageContent.getBigDecimal("orderedQuantity");
-                BigDecimal proportionOfOrderedQuantity = 
packedQuantity.divide(orderedQuantity, 10, rounding);
+                // How much of the invoiced quantity does the issued quantity 
represent?
+                BigDecimal issuedQuantity = 
packageContent.getBigDecimal("issuedQuantity");
+                BigDecimal proportionOfInvoicedQuantity = 
invoicedQuantity.signum() == 0 ? ZERO : issuedQuantity.divide(invoicedQuantity, 
10, rounding);
             
-                // Prorate the orderItem's value by that proportion
-                BigDecimal packageContentValue = 
proportionOfOrderedQuantity.multiply(orderItemTotalValue).setScale(decimals, 
rounding);
+                // Prorate the orderItem's invoiced amount by that proportion
+                BigDecimal packageContentValue = 
proportionOfInvoicedQuantity.multiply(invoicedAmount).setScale(decimals, 
rounding);
             
                 // Convert the value to the shipment currency, if necessary
                 GenericValue orderHeader = 
packageContent.getRelatedOne("OrderHeader");


Reply via email to