svn commit: r550858 - in /ofbiz/trunk/applications: order/servicedef/ order/src/org/ofbiz/order/order/ product/entitydef/ product/servicedef/ product/src/org/ofbiz/shipment/shipment/

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r550858 - in /ofbiz/trunk/applications: order/servicedef/ order/src/org/ofbiz/order/order/ product/entitydef/ product/servicedef/ product/src/org/ofbiz/shipment/shipment/

sichen
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");