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"/> |
Free forum by Nabble | Edit this page |