You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by si...@apache.org on 2007/02/27 20:51:53 UTC
svn commit: r512373 - in /ofbiz/trunk/applications: order/config/
order/src/org/ofbiz/order/shoppingcart/
order/webapp/ordermgr/WEB-INF/actions/entry/ product/data/
Author: sichen
Date: Tue Feb 27 11:51:52 2007
New Revision: 512373
URL: http://svn.apache.org/viewvc?view=rev&rev=512373
Log:
Implementing logic to handle automatic creation of drop ship groups during checkout
- If a product is set to always drop ship (Product.requirementMethodEnumId == 'PRODRQM_DS').
- If a product is set to drop ship when inventory is low (Product.requirementMethodEnumId == 'PRODRQM_DSATP'). In this case, item quantities > ATP will be drop shipped.
- Items are reassigned to ship groups based on supplier.
- Ship groups are created if necessary.
- Suppliers are determined using by ProductSupplier.canDropShip == Y, and ProductSupplier.supplierPrefOrderId - main suppliers are used in preference to alternate suppliers.
- Changing Enumeration.enumId PRODRQM_DSQOH to PRODRQM_DSATP in ProductTypeData.xml.
Modified:
ofbiz/trunk/applications/order/config/OrderErrorUiLabels.properties
ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/CheckOutEvents.java
ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java
ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java
ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/checkoutoptions.bsh
ofbiz/trunk/applications/product/data/ProductTypeData.xml
Modified: ofbiz/trunk/applications/order/config/OrderErrorUiLabels.properties
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/config/OrderErrorUiLabels.properties?view=diff&rev=512373&r1=512372&r2=512373
==============================================================================
--- ofbiz/trunk/applications/order/config/OrderErrorUiLabels.properties (original)
+++ ofbiz/trunk/applications/order/config/OrderErrorUiLabels.properties Tue Feb 27 11:51:52 2007
@@ -172,6 +172,7 @@
OrderProblemGettingItemShipAfterDateFor=Problem getting itemShipAfterDate for ${productId}
OrderProblemGettingItemShipBeforeDateFor=Problem getting itemShipBeforeDate for ${productId}
OrderProblemGettingOrderItemRecords=Problem getting OrderItem records
+OrderProblemGettingProductStoreRecords=Problem getting ProductStore records
OrderProblemGettingTheRecordIterator=Problem getting the Record Iterator
OrderProblemOccurredInTaxService=Problem occurred in tax service
OrderProblemSendingEmail=Problem sending email
@@ -207,6 +208,7 @@
OrderReturnTotalCannotLessThanZero=Return total [${returnTotalAmount}] can not less than zero.
OrderReturnQuantityCannotExceedTheOrderedQuantity=Return quantity [ ${parameters.returnQuantity} ] cannot exceed the ordered quantity [ ${orderItem.quantity} ].
OrderRunServiceGetSuppliersForProductError=Run service [getSuppliersForProduct] error :
+OrderRunServiceGetInventoryAvailableByFacilityError=Run service [getInventoryAvailableByFacility] error :
OrderSecurityErrorToRunForAnotherParty=Security Error : to run ${parentMethodName} for another party you must have the PARTYMGR_${permissionAction} or PARTYMGR_ADMIN permission
OrderSecurityErrorToRunAutoUpdateQuotePrice=Security Error : to run autoUpdateQuotePrice you must have the ORDERMGR_CREATE or ORDERMGR_ADMIN permission
OrderSecurityErrorToRunCheckCreateOrderRequirementCommitment=Security Error: to run createOrderRequirementCommitment you must have ORDERMGR_CREATE or ORDERMGR_ADMIN permission
Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/CheckOutEvents.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/CheckOutEvents.java?view=diff&rev=512373&r1=512372&r2=512373
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/CheckOutEvents.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/CheckOutEvents.java Tue Feb 27 11:51:52 2007
@@ -630,6 +630,15 @@
}
}
+ // Reassign items requiring drop-shipping to new or existing drop-ship groups
+ if ("init".equals(mode) || "default".equals(mode)) {
+ try {
+ cart.createDropShipGroups(dispatcher);
+ } catch (CartItemModifyException e) {
+ Debug.logError(e, module);
+ }
+ }
+
// set the customer info
if (mode != null && mode.equals("default")) {
cart.setDefaultCheckoutOptions(dispatcher);
Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java?view=diff&rev=512373&r1=512372&r2=512373
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java Tue Feb 27 11:51:52 2007
@@ -21,18 +21,7 @@
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import javolution.util.FastList;
import javolution.util.FastMap;
@@ -3612,6 +3601,164 @@
return result;
}
+ public Map getShipGroupsBySupplier(String supplierPartyId) {
+ Map shipGroups = new TreeMap();
+ for (int i = 0; i < this.shipInfo.size(); i++) {
+ CartShipInfo csi = (CartShipInfo) shipInfo.get(i);
+ if ((csi.supplierPartyId == null && supplierPartyId == null) ||
+ (UtilValidate.isNotEmpty(csi.supplierPartyId) && csi.supplierPartyId.equals(supplierPartyId))) {
+ shipGroups.put(new Integer(i), csi);
+ }
+ }
+ return shipGroups;
+ }
+
+ /**
+ * Examine each item of each ship group and create new ship groups if the item should be drop shipped
+ * @param dispatcher
+ * @throws CartItemModifyException
+ */
+ public void createDropShipGroups(LocalDispatcher dispatcher) throws CartItemModifyException {
+
+ // Retrieve the facilityId from the cart's productStoreId because ShoppingCart.setFacilityId() doesn't seem to be used anywhere
+ String facilityId = null;
+ if (UtilValidate.isNotEmpty(this.getProductStoreId())) {
+ try {
+ GenericValue productStore = delegator.findByPrimaryKeyCache("ProductStore", UtilMisc.toMap("productStoreId", this.getProductStoreId()));
+ facilityId = productStore.getString("inventoryFacilityId");
+ } catch (Exception e) {
+ Debug.logError(UtilProperties.getMessage(resource_error,"OrderProblemGettingProductStoreRecords", locale) + e.getMessage(), module);
+ return;
+ }
+ }
+
+ List shipGroups = getShipGroups();
+ if (shipGroups == null) return;
+
+ // Intermediate structure supplierPartyId -> { ShoppingCartItem = { originalShipGroupIndex = dropShipQuantity } } to collect drop-shippable items
+ Map dropShipItems = new HashMap();
+
+ for (int shipGroupIndex = 0; shipGroupIndex < shipGroups.size(); shipGroupIndex++) {
+
+ CartShipInfo shipInfo = (CartShipInfo) shipGroups.get(shipGroupIndex);
+
+ // Ignore ship groups that are already drop shipped
+ String shipGroupSupplierPartyId = shipInfo.getSupplierPartyId();
+ if (UtilValidate.isNotEmpty(shipGroupSupplierPartyId)) continue;
+
+ // Ignore empty ship groups
+ Set shipItems = shipInfo.getShipItems();
+ if (UtilValidate.isEmpty(shipItems)) continue;
+
+ Iterator siit = shipItems.iterator();
+ while (siit.hasNext()) {
+
+ ShoppingCartItem cartItem = (ShoppingCartItem) siit.next();
+
+ double itemQuantity = cartItem.getQuantity();
+ double dropShipQuantity = 0;
+
+ GenericValue product = cartItem.getProduct();
+ String productId = product.getString("productId");
+ String requirementMethodEnumId = product.getString("requirementMethodEnumId");
+
+ if ("PRODRQM_DS".equals(requirementMethodEnumId)) {
+
+ // Drop ship the full quantity if the product is marked drop-ship only
+ dropShipQuantity = itemQuantity;
+
+ } else if ("PRODRQM_DSATP".equals(requirementMethodEnumId)) {
+
+ // Drop ship the quantity not available in inventory if the product is marked drop-ship on low inventory
+ try {
+
+ // Get ATP for the product
+ Map getProductInventoryAvailableResult = dispatcher.runSync("getInventoryAvailableByFacility", UtilMisc.toMap("productId", productId, "facilityId", facilityId));
+ double availableToPromise = ((Double) getProductInventoryAvailableResult.get("availableToPromiseTotal")).doubleValue();
+
+ if (itemQuantity <= availableToPromise) {
+ dropShipQuantity = 0;
+ } else {
+ dropShipQuantity = itemQuantity - availableToPromise;
+ }
+
+ } catch (Exception e) {
+ Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderRunServiceGetInventoryAvailableByFacilityError", locale) + e.getMessage(), module);
+ }
+ } else {
+
+ // Don't drop ship anything if the product isn't so marked
+ dropShipQuantity = 0;
+ }
+
+ if (dropShipQuantity <= 0) continue;
+
+ // Find a supplier for the product
+ String supplierPartyId = null;
+ try {
+ Map getSuppliersForProductResult = dispatcher.runSync("getSuppliersForProduct", UtilMisc.toMap("productId", productId, "quantity", new Double(dropShipQuantity), "canDropShip", "Y", "currencyUomId", getCurrency()));
+ List supplierProducts = (List) getSuppliersForProductResult.get("supplierProducts");
+
+ // Order suppliers by supplierPrefOrderId so that preferred suppliers are used first
+ supplierProducts = EntityUtil.orderBy(supplierProducts, UtilMisc.toList("supplierPrefOrderId"));
+ GenericValue supplierProduct = EntityUtil.getFirst(supplierProducts);
+ if (! UtilValidate.isEmpty(supplierProduct)) {
+ supplierPartyId = supplierProduct.getString("partyId");
+ }
+ } catch (Exception e) {
+ Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderRunServiceGetSuppliersForProductError", locale) + e.getMessage(), module);
+ }
+
+ // Leave the items untouched if we couldn't find a supplier
+ if (UtilValidate.isEmpty(supplierPartyId)) continue;
+
+ if (! dropShipItems.containsKey(supplierPartyId)) dropShipItems.put(supplierPartyId, new HashMap());
+ Map supplierCartItems = (Map) dropShipItems.get(supplierPartyId);
+
+ if (! supplierCartItems.containsKey(cartItem)) supplierCartItems.put(cartItem, new HashMap());
+ Map cartItemGroupQuantities = (Map) supplierCartItems.get(cartItem);
+
+ cartItemGroupQuantities.put(new Integer(shipGroupIndex), new Double(dropShipQuantity));
+ }
+ }
+
+ // Reassign the drop-shippable item quantities to new or existing drop-ship groups
+ Iterator dsit = dropShipItems.keySet().iterator();
+ while (dsit.hasNext()) {
+ String supplierPartyId = (String) dsit.next();
+
+ CartShipInfo shipInfo = null;
+ int newShipGroupIndex = -1 ;
+
+ // Attempt to get the first ship group for the supplierPartyId
+ TreeMap supplierShipGroups = (TreeMap) this.getShipGroupsBySupplier(supplierPartyId);
+ if (! UtilValidate.isEmpty(supplierShipGroups)) {
+ newShipGroupIndex = ((Integer) supplierShipGroups.firstKey()).intValue();
+ shipInfo = (CartShipInfo) supplierShipGroups.get(supplierShipGroups.firstKey());
+ }
+ if (newShipGroupIndex == -1) {
+ newShipGroupIndex = addShipInfo();
+ shipInfo = (CartShipInfo) this.shipInfo.get(newShipGroupIndex);
+ }
+ shipInfo.supplierPartyId = supplierPartyId;
+
+ Map supplierCartItems = (Map) dropShipItems.get(supplierPartyId);
+ Iterator itit = supplierCartItems.keySet().iterator();
+ while (itit.hasNext()) {
+
+ ShoppingCartItem cartItem = (ShoppingCartItem) itit.next();
+ Map cartItemGroupQuantities = (Map) supplierCartItems.get(cartItem);
+ Iterator cigit = cartItemGroupQuantities.keySet().iterator();
+ while (cigit.hasNext()) {
+
+ Integer previousShipGroupIndex = (Integer) cigit.next();
+ double dropShipQuantity = ((Double) cartItemGroupQuantities.get(previousShipGroupIndex)).doubleValue();
+ positionItemToGroup(cartItem, dropShipQuantity, previousShipGroupIndex.intValue(), newShipGroupIndex, true);
+ }
+ }
+ }
+ }
+
static class BasePriceOrderComparator implements Comparator, Serializable {
private boolean ascending = false;
Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java?view=diff&rev=512373&r1=512372&r2=512373
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java Tue Feb 27 11:51:52 2007
@@ -928,6 +928,11 @@
// set the item ship group
if (resetShipGroup) {
cart.clearItemShipInfo(this);
+
+ /*
+
+ // Deprecated in favour of ShoppingCart.createDropShipGroups(), called during checkout
+
int shipGroupIndex = -1;
if ("PURCHASE_ORDER".equals(cart.getOrderType())) {
shipGroupIndex = 0;
@@ -963,7 +968,6 @@
Debug.logWarning("Error calling getSuppliersForProduct service, result is: " + supplierProductsResult, module);
}
}
- // TODO: implement auto drop-ship on low qoh
if (shipGroupIndex == -1) {
List shipGroups = cart.getShipGroups();
@@ -981,6 +985,8 @@
}
}
cart.setItemShipGroupQty(this, quantity, shipGroupIndex);
+ */
+ cart.setItemShipGroupQty(this, quantity, 0);
}
}
Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/checkoutoptions.bsh
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/checkoutoptions.bsh?view=diff&rev=512373&r1=512372&r2=512373
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/checkoutoptions.bsh (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/checkoutoptions.bsh Tue Feb 27 11:51:52 2007
@@ -38,6 +38,11 @@
context.put("carrierShipmentMethodList", shippingEstWpr.getShippingMethods());
}
+// Reassign items requiring drop-shipping to new or existing drop-ship groups
+if (shoppingCart != null) {
+ shoppingCart.createDropShipGroups(dispatcher);
+}
+
profiledefs = delegator.findByPrimaryKey("PartyProfileDefault", UtilMisc.toMap("partyId", userLogin.getString("partyId"), "productStoreId", productStoreId));
context.put("profiledefs", profiledefs);
Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?view=diff&rev=512373&r1=512372&r2=512373
==============================================================================
--- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
+++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Tue Feb 27 11:51:52 2007
@@ -412,7 +412,7 @@
<!-- PRODRQM_DS: a drop ship group is created to trigger automatic creation of a purchase order (drop shipment) every time a sales order is created-->
<Enumeration description="Drop-ship only" enumCode="DROPS" enumId="PRODRQM_DS" sequenceId="06" enumTypeId="PROD_REQ_METHOD"/>
<!-- PRODRQM_DSQOH: auto drop ship on low quantity on hand -->
- <Enumeration description="Auto drop-ship on low quantity" enumCode="DROPS_QOH" enumId="PRODRQM_DSQOH" sequenceId="07" enumTypeId="PROD_REQ_METHOD"/>
+ <Enumeration description="Auto drop-ship on low quantity" enumCode="DROPS_ATP" enumId="PRODRQM_DSATP" sequenceId="07" enumTypeId="PROD_REQ_METHOD"/>
<!-- inventory item status -->
<StatusType description="Inventory Item" hasTable="N" parentTypeId="" statusTypeId="INVENTORY_ITEM_STTS"/>