svn commit: r1839914 - in /ofbiz/ofbiz-framework/trunk/applications: datamodel/entitydef/ order/config/ order/groovyScripts/entry/ order/servicedef/ order/src/main/java/org/apache/ofbiz/order/order/ order/src/main/java/org/apache/ofbiz/order/shoppingca...

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

svn commit: r1839914 - in /ofbiz/ofbiz-framework/trunk/applications: datamodel/entitydef/ order/config/ order/groovyScripts/entry/ order/servicedef/ order/src/main/java/org/apache/ofbiz/order/order/ order/src/main/java/org/apache/ofbiz/order/shoppingca...

jleroux@apache.org
Author: jleroux
Date: Mon Sep  3 08:15:08 2018
New Revision: 1839914

URL: http://svn.apache.org/viewvc?rev=1839914&view=rev
Log:
Implemented: 'Reserve After Date' for order items
(OFBIZ-10534)

While creating orders from the backend, we have the option to set parameters
like 'Ship After Date' and 'Ship Before Date' to manage the fulfilment cycle
more efficiently.

Inventory gets reserved for the product based on a FIFO basis. Sometimes the
fulfilment time for the order is high and inventory unnecessarily gets locked
for some time period.
 
We can introduce a new parameter (at order item level) 'Reserve After Date'
which will indicate the date only after which reservation can happen.
In this way, we can manage the stock availability more efficiently.
 
This issue relates to OFBIZ-10518

Thanks: Deepak Nigam  for the effort, Deepak Dixit for a review and suggestions

Modified:
    ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/order-entitymodel.xml
    ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml
    ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/CheckoutReview.groovy
    ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartEvents.java
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartHelper.java
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartServices.java
    ofbiz/ofbiz-framework/trunk/applications/order/template/entry/OrderAgreements.ftl
    ofbiz/ofbiz-framework/trunk/applications/order/template/entry/cart/ShowCart.ftl
    ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/OrderHeaderInfo.ftl
    ofbiz/ofbiz-framework/trunk/applications/order/template/order/EditOrderItems.ftl
    ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderItems.ftl

Modified: ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/order-entitymodel.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/order-entitymodel.xml?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/order-entitymodel.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/order-entitymodel.xml Mon Sep  3 08:15:08 2018
@@ -547,6 +547,7 @@ under the License.
       <field name="dontCancelSetUserLogin" type="id-vlong"></field>
       <field name="shipBeforeDate" type="date-time"></field>
       <field name="shipAfterDate" type="date-time"></field>
+      <field name="reserveAfterDate" type="date-time"></field>
       <field name="cancelBackOrderDate" type="date-time"><description>Used to cancel all orders from suppliers when its in past</description></field>
       <field name="overrideGlAccountId" type="id"><description>Used to specify the override or actual glAccountId used for the adjustment, avoids problems if configuration changes after initial posting, etc.</description></field>
       <field name="salesOpportunityId" type="id"></field>
@@ -2973,6 +2974,5 @@ under the License.
             <key-map field-name="workEffortId"/>
         </relation>
     </entity>
-
  </entitymodel>
 

Modified: ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/config/OrderUiLabels.xml Mon Sep  3 08:15:08 2018
@@ -12023,6 +12023,22 @@
         <value xml:lang="zh">要求使用促销代码。</value>
         <value xml:lang="zh-TW">要求使用促銷代碼.</value>
     </property>
+    <property key="OrderReserveAfterDate">
+         <value xml:lang="en">Reserve After Date</value>
+         <value xml:lang="fr">Réserver après cette date</value>
+    </property>
+    <property key="OrderReserveAfterDateDefault">
+         <value xml:lang="en">Default Reserve After Date</value>
+         <value xml:lang="fr">Date de réservation par défaut</value>
+    </property>
+    <property key="OrderReserveAfterDate">
+         <value xml:lang="en">Reserve After Date</value>
+         <value xml:lang="fr">Réserver après cette date</value>
+    </property>
+    <property key="OrderReserveAfterDateDefault">
+         <value xml:lang="en">Default Reserve After Date</value>
+         <value xml:lang="fr">Date de réservation par défaut</value>
+    </property>
     <property key="OrderReturnAccept">
         <value xml:lang="ar">الموافقة للمسترجع</value>
         <value xml:lang="de">Retoure annehmen</value>

Modified: ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/CheckoutReview.groovy
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/CheckoutReview.groovy?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/CheckoutReview.groovy (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/CheckoutReview.groovy Mon Sep  3 08:15:08 2018
@@ -115,6 +115,7 @@ context.giftMessage = cart.getGiftMessag
 context.isGift = cart.getIsGift()
 context.shipBeforeDate = cart.getShipBeforeDate()
 context.shipAfterDate = cart.getShipAfterDate()
+context.defaultReserveAfterDate = cart.getDefaultReserveAfterDate()
 
 shipmentMethodType = from("ShipmentMethodType").where("shipmentMethodTypeId", cart.getShipmentMethodTypeId()).queryOne()
 if (shipmentMethodType) context.shipMethDescription = shipmentMethodType.description

Modified: ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml Mon Sep  3 08:15:08 2018
@@ -311,6 +311,7 @@ under the License.
         <attribute name="itemAttributesMap" type="Map" mode="IN" string-map-prefix="iam_" optional="true"/>
         <attribute name="itemShipDateMap" type="Map" mode="IN" string-map-prefix="isdm_" optional="true"/>
         <attribute name="itemDeliveryDateMap" type="Map" mode="IN" string-map-prefix="iddm_" optional="true"/>
+        <attribute name="itemReserveAfterDateMap" type="Map" mode="IN" string-map-prefix="iradm_" optional="true"/>
         <attribute name="shoppingCart" type="org.apache.ofbiz.order.shoppingcart.ShoppingCart" mode="OUT" optional="false"/>
     </service>
     <service name="loadCartForUpdate" engine="java" auth="true"

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java Mon Sep  3 08:15:08 2018
@@ -1198,6 +1198,13 @@ public class OrderServices {
                         continue;
                     }
                     GenericValue orderItem = itemValuesBySeqId.get(orderItemShipGroupAssoc.get("orderItemSeqId"));
+                    if ("SALES_ORDER".equals(orderTypeId) && orderItem != null) {
+                        //If the 'reserveAfterDate' is not yet come don't reserve the inventory
+                        Timestamp reserveAfterDate = orderItem.getTimestamp("reserveAfterDate");
+                        if (UtilValidate.isNotEmpty(reserveAfterDate) && reserveAfterDate.after(UtilDateTime.nowTimestamp())) {
+                            continue;
+                        }
+                    }
                     GenericValue orderItemShipGroup = orderItemShipGroupAssoc.getRelatedOne("OrderItemShipGroup", false);
                     String shipGroupFacilityId = orderItemShipGroup.getString("facilityId");
                     String itemStatus = orderItem.getString("statusId");
@@ -3666,6 +3673,7 @@ public class OrderServices {
         Map<String, String> itemAttributesMap = UtilGenerics.checkMap(context.get("itemAttributesMap"));
         Map<String, String> itemEstimatedShipDateMap = UtilGenerics.checkMap(context.get("itemShipDateMap"));
         Map<String, String> itemEstimatedDeliveryDateMap = UtilGenerics.checkMap(context.get("itemDeliveryDateMap"));
+        Map<String, String> itemReserveAfterDateMap = UtilGenerics.checkMap(context.get("itemReserveAfterDateMap"));
         Boolean calcTax = (Boolean) context.get("calcTax");
         if (calcTax == null) {
             calcTax = Boolean.TRUE;
@@ -3838,6 +3846,21 @@ public class OrderServices {
                     }
                 }
             }
+        }
+        //Update Reserve After Date
+        if (null != itemReserveAfterDateMap) {
+            for (Map.Entry<String, String> entry : itemReserveAfterDateMap.entrySet()) {
+                String itemSeqId =  entry.getKey();
+                // ignore internationalised variant of dates
+                if (!itemSeqId.endsWith("_i18n")) {
+                    String reserveAfterDateStr = entry.getValue();
+                    if (UtilValidate.isNotEmpty(reserveAfterDateStr)) {
+                        Timestamp reserveAfterDate = Timestamp.valueOf(reserveAfterDateStr);
+                        ShoppingCartItem cartItem = cart.findCartItem(itemSeqId);
+                        cartItem.setReserveAfterDate(reserveAfterDate);
+                    }
+                }
+            }
         }
 
         // update the group amounts

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCart.java Mon Sep  3 08:15:08 2018
@@ -151,6 +151,7 @@ public class ShoppingCart implements Ite
     /** these are defaults for all ship groups */
     private Timestamp defaultShipAfterDate = null;
     private Timestamp defaultShipBeforeDate = null;
+    private Timestamp defaultReserveAfterDate = null;
 
     /** Contains a List for each productPromoId (key) containing a productPromoCodeId (or empty string for no code) for each use of the productPromoId */
     private List<ProductPromoUseInfo> productPromoUseInfoList = new LinkedList<>();
@@ -226,6 +227,7 @@ public class ShoppingCart implements Ite
         this.viewCartOnAdd = cart.viewCartOnAdd();
         this.defaultShipAfterDate = cart.getDefaultShipAfterDate();
         this.defaultShipBeforeDate = cart.getDefaultShipBeforeDate();
+        this.defaultReserveAfterDate = cart.getDefaultReserveAfterDate();
         this.cancelBackOrderDate = cart.getCancelBackOrderDate();
 
         this.terminalId = cart.getTerminalId();
@@ -514,14 +516,23 @@ public class ShoppingCart implements Ite
     public int addOrIncreaseItem(String productId, BigDecimal selectedAmount, BigDecimal quantity, Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons,
                String accommodationMapId, String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate, Map<String, GenericValue> features, Map<String, Object> attributes,
                String prodCatalogId, ProductConfigWrapper configWrapper, String itemType, String itemGroupNumber, String parentProductId, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
-            return addOrIncreaseItem(productId, selectedAmount, quantity, reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, features, attributes, null, prodCatalogId, configWrapper, itemType, itemGroupNumber, parentProductId, dispatcher);
+        return addOrIncreaseItem(productId, selectedAmount, quantity, reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, features, attributes, null, prodCatalogId, configWrapper, itemType, itemGroupNumber, parentProductId, dispatcher);
     }
 
     /** add rental (with accommodation) item to cart and order item attributes*/
     // TODO change method signature, this one is really scary, above are not bad too :/ !
     public int addOrIncreaseItem(String productId, BigDecimal selectedAmount, BigDecimal quantity, Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons,
-               String accommodationMapId, String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate, Map<String, GenericValue> features, Map<String,
-               Object> attributes, Map<String, String> orderItemAttributes, String prodCatalogId, ProductConfigWrapper configWrapper, String itemType, String itemGroupNumber,
+               String accommodationMapId, String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate, Map<String, GenericValue> features, Map<String,Object> attributes,
+               Map<String, String> orderItemAttributes, String prodCatalogId, ProductConfigWrapper configWrapper, String itemType, String itemGroupNumber,
+               String parentProductId, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
+        return addOrIncreaseItem(productId, selectedAmount, quantity, reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, null, features, attributes, null, prodCatalogId, configWrapper, itemType, itemGroupNumber, parentProductId, dispatcher);
+    }
+
+    /** add rental (with accommodation) item to cart and order item attributes*/
+    // TODO change method signature, this one is really scary, above are not bad too :/ !
+    public int addOrIncreaseItem(String productId, BigDecimal selectedAmount, BigDecimal quantity, Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons,
+               String accommodationMapId, String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate, Timestamp reserveAfterDate, Map<String, GenericValue> features, Map<String,Object> attributes,
+               Map<String, String> orderItemAttributes, String prodCatalogId, ProductConfigWrapper configWrapper, String itemType, String itemGroupNumber,
                String parentProductId, LocalDispatcher dispatcher) throws CartItemModifyException, ItemNotFoundException {
         if (isReadOnlyCart()) {
            throw new CartItemModifyException("Cart items cannot be changed");
@@ -596,7 +607,7 @@ public class ShoppingCart implements Ite
                 Debug.logError(e, module);
             }
             item = ShoppingCartItem.makeItem(0, productId, selectedAmount, quantity, null,
-                    reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate,
+                    reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, reserveAfterDate,
                     features, attributes, prodCatalogId, configWrapper, itemType, itemGroup, dispatcher,
                     this, Boolean.TRUE, Boolean.TRUE, parentProductId, Boolean.FALSE, Boolean.FALSE);
         }
@@ -1246,6 +1257,14 @@ public class ShoppingCart implements Ite
    public Timestamp getDefaultShipAfterDate() {
        return this.defaultShipAfterDate != null ? (Timestamp) this.defaultShipAfterDate.clone() : null;
    }
+  
+   public void setDefaultReserveAfterDate(Timestamp defaultReserveAfterDate) {
+       this.defaultReserveAfterDate = defaultReserveAfterDate != null ? (Timestamp) defaultReserveAfterDate.clone() : null;
+   }
+
+   public Timestamp getDefaultReserveAfterDate() {
+       return this.defaultReserveAfterDate != null ? (Timestamp) this.defaultReserveAfterDate.clone() : null;
+   }
 
     public String getOrderPartyId() {
         return this.orderPartyId != null ? this.orderPartyId : this.getPartyId();
@@ -3735,6 +3754,7 @@ public class ShoppingCart implements Ite
 
                 orderItem.set("shipBeforeDate", item.getShipBeforeDate());
                 orderItem.set("shipAfterDate", item.getShipAfterDate());
+                orderItem.set("reserveAfterDate", item.getReserveAfterDate());
                 orderItem.set("estimatedShipDate", item.getEstimatedShipDate());
                 orderItem.set("cancelBackOrderDate", item.getCancelBackOrderDate());
                 if (this.getUserLogin() != null) {

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartEvents.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartEvents.java?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartEvents.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartEvents.java Mon Sep  3 08:15:08 2018
@@ -199,8 +199,10 @@ public class ShoppingCartEvents {
         String accommodationSpotId = null;
         String shipBeforeDateStr = null;
         String shipAfterDateStr = null;
+        String reserveAfterDateStr = null;
         Timestamp shipBeforeDate = null;
         Timestamp shipAfterDate = null;
+        Timestamp reserveAfterDate = null;
         String numberOfDay = null;
 
         // not used right now: Map attributes = null;
@@ -542,6 +544,20 @@ public class ShoppingCartEvents {
             }
         }
 
+        // get the reserve after date (handles both yyyy-mm-dd input and full timestamp)
+        reserveAfterDateStr = (String) paramMap.remove("reserveAfterDate");
+        if (UtilValidate.isNotEmpty(reserveAfterDateStr)) {
+            if (reserveAfterDateStr.length() == 10) {
+                reserveAfterDateStr += " 00:00:00.000";
+            }
+            try {
+                reserveAfterDate = java.sql.Timestamp.valueOf(reserveAfterDateStr);
+            } catch (IllegalArgumentException e) {
+                Debug.logWarning(e, "Bad reserveAfterDate input: " + e.getMessage(), module);
+                reserveAfterDate = null;
+            }
+        }
+
         // check for an add-to cart survey
         List<String> surveyResponses = null;
         if (productId != null) {
@@ -648,7 +664,7 @@ public class ShoppingCartEvents {
         result = cartHelper.addToCart(catalogId, shoppingListId, shoppingListItemSeqId, productId, productCategoryId,
                 itemType, itemDescription, price, amount, quantity, reservStart, reservLength, reservPersons,
                 accommodationMapId, accommodationSpotId,
-                shipBeforeDate, shipAfterDate, configWrapper, itemGroupNumber, paramMap, parentProductId);
+                shipBeforeDate, shipAfterDate, reserveAfterDate, configWrapper, itemGroupNumber, paramMap, parentProductId);
         controlDirective = processResult(result, request);
 
         Integer itemId = (Integer)result.get("itemId");
@@ -1911,6 +1927,7 @@ public class ShoppingCartEvents {
         String workEffortId = request.getParameter("workEffortId");
         String shipBeforeDateStr = request.getParameter("shipBeforeDate");
         String shipAfterDateStr = request.getParameter("shipAfterDate");
+        String reserveAfterDateStr = request.getParameter("reserveAfterDate");
         String cancelBackOrderDateStr = request.getParameter("cancelBackOrderDate");
         String orderId = request.getParameter("orderId");
         String orderName = request.getParameter("orderName");
@@ -1969,6 +1986,12 @@ public class ShoppingCartEvents {
                 }
                 cart.setDefaultShipAfterDate(java.sql.Timestamp.valueOf(shipAfterDateStr));
             }
+            if (UtilValidate.isNotEmpty(reserveAfterDateStr)) {
+                if (reserveAfterDateStr.length() == 10) {
+                    reserveAfterDateStr += " 00:00:00.000";
+                }
+                cart.setDefaultReserveAfterDate(java.sql.Timestamp.valueOf(reserveAfterDateStr));
+            }
             if (UtilValidate.isNotEmpty(cancelBackOrderDateStr)) {
                 if (cancelBackOrderDateStr.length() == 10) {
                     cancelBackOrderDateStr += " 00:00:00.000";

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartHelper.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartHelper.java?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartHelper.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartHelper.java Mon Sep  3 08:15:08 2018
@@ -113,13 +113,27 @@ public class ShoppingCartHelper {
                 configWrapper,itemGroupNumber,context,parentProductId);
     }
 
-    /** Event to add an item to the shopping cart with accommodation. */
+    /** Overriden for reserveAfterDate. */
     public Map<String, Object> addToCart(String catalogId, String shoppingListId, String shoppingListItemSeqId, String productId,
             String productCategoryId, String itemType, String itemDescription,
             BigDecimal price, BigDecimal amount, BigDecimal quantity,
             java.sql.Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons, String accommodationMapId,String accommodationSpotId,
             java.sql.Timestamp shipBeforeDate, java.sql.Timestamp shipAfterDate,
             ProductConfigWrapper configWrapper, String itemGroupNumber, Map<String, ? extends Object> context, String parentProductId) {
+
+        return addToCart(catalogId,shoppingListId,shoppingListItemSeqId,productId,
+                productCategoryId,itemType,itemDescription,price,amount,quantity,
+                reservStart,reservLength,reservPersons,null,null,shipBeforeDate,shipAfterDate,null,
+                configWrapper,itemGroupNumber,context,parentProductId);
+    }
+
+    /** Event to add an item to the shopping cart with accommodation. */
+    public Map<String, Object> addToCart(String catalogId, String shoppingListId, String shoppingListItemSeqId, String productId,
+            String productCategoryId, String itemType, String itemDescription,
+            BigDecimal price, BigDecimal amount, BigDecimal quantity,
+            java.sql.Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons, String accommodationMapId,String accommodationSpotId,
+            java.sql.Timestamp shipBeforeDate, java.sql.Timestamp shipAfterDate, java.sql.Timestamp reserveAfterDate,
+            ProductConfigWrapper configWrapper, String itemGroupNumber, Map<String, ? extends Object> context, String parentProductId) {
         Map<String, Object> result = null;
         Map<String, Object> attributes = null;
         String pProductId = null;
@@ -242,7 +256,7 @@ public class ShoppingCartHelper {
             if (productId != null) {
 
                        itemId = cart.addOrIncreaseItem(productId, amount, quantity, reservStart, reservLength,
-                                                reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, additionalFeaturesMap, attributes,
+                                                reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, reserveAfterDate, additionalFeaturesMap, attributes,
                                                 orderItemAttributes, catalogId, configWrapper, itemType, itemGroupNumber, pProductId, dispatcher);
 
             } else {

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartItem.java Mon Sep  3 08:15:08 2018
@@ -137,6 +137,7 @@ public class ShoppingCartItem implements
     private Locale locale = null;
     private Timestamp shipBeforeDate = null;
     private Timestamp shipAfterDate = null;
+    private Timestamp reserveAfterDate = null;
     private Timestamp estimatedShipDate = null;
     private Timestamp cancelBackOrderDate = null;
 
@@ -295,20 +296,36 @@ public class ShoppingCartItem implements
             throws CartItemModifyException, ItemNotFoundException {
 
         return makeItem(cartLocation,productId,selectedAmount,quantity,unitPrice,
-                reservStart,reservLength,reservPersons,null,null,shipBeforeDate,shipAfterDate,
+                reservStart,reservLength,reservPersons,null,null,shipBeforeDate,shipAfterDate, null,
                 additionalProductFeatureAndAppls,attributes,prodCatalogId,configWrapper,
                 itemType,itemGroup,dispatcher,cart,triggerExternalOpsBool,triggerPriceRulesBool,
                 parentProductId,skipInventoryChecks,skipProductChecks);
 
     }
 
+    /*
+     * Makes a ShoppingCartItem and adds it to the cart.
+     * @param reserveAfterDate Optional.
+    */
+    public static ShoppingCartItem makeItem(Integer cartLocation, String productId, BigDecimal selectedAmount, BigDecimal quantity, BigDecimal unitPrice,
+            Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons,String accommodationMapId,String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate,
+            Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes, String prodCatalogId, ProductConfigWrapper configWrapper,
+            String itemType, ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher, ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, String parentProductId, Boolean skipInventoryChecks, Boolean skipProductChecks)
+            throws CartItemModifyException, ItemNotFoundException {
+        return makeItem(cartLocation, productId, selectedAmount, quantity, unitPrice,
+                        reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, null,
+                        additionalProductFeatureAndAppls, attributes, prodCatalogId, configWrapper,
+                        itemType, itemGroup, dispatcher, cart, triggerExternalOpsBool, triggerPriceRulesBool,
+                        parentProductId, skipInventoryChecks, skipProductChecks);
+    }
+
     /**
      * Makes a ShoppingCartItem and adds it to the cart.
      * @param accommodationMapId Optional. reservations add into workeffort
      * @param accommodationSpotId Optional. reservations add into workeffort
      */
     public static ShoppingCartItem makeItem(Integer cartLocation, String productId, BigDecimal selectedAmount, BigDecimal quantity, BigDecimal unitPrice,
-            Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons,String accommodationMapId,String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate,
+            Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons,String accommodationMapId,String accommodationSpotId, Timestamp shipBeforeDate, Timestamp shipAfterDate, Timestamp reserveAfterDate,
             Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes, String prodCatalogId, ProductConfigWrapper configWrapper,
             String itemType, ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher, ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, String parentProductId, Boolean skipInventoryChecks, Boolean skipProductChecks)
             throws CartItemModifyException, ItemNotFoundException {
@@ -326,7 +343,7 @@ public class ShoppingCartItem implements
             }
         }
         return makeItem(cartLocation, product, selectedAmount, quantity, unitPrice,
-                reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate,
+                reservStart, reservLength, reservPersons, accommodationMapId, accommodationSpotId, shipBeforeDate, shipAfterDate, reserveAfterDate,
                 additionalProductFeatureAndAppls, attributes, prodCatalogId, configWrapper,
                 itemType, itemGroup, dispatcher, cart, triggerExternalOpsBool, triggerPriceRulesBool, parentProduct, skipInventoryChecks, skipProductChecks);
     }
@@ -368,7 +385,7 @@ public class ShoppingCartItem implements
 
         return makeItem(cartLocation,product,selectedAmount,
                quantity,unitPrice,reservStart,reservLength,reservPersons,
-               null,null,shipBeforeDate,shipAfterDate,additionalProductFeatureAndAppls,attributes,
+               null,null,shipBeforeDate,shipAfterDate, null, additionalProductFeatureAndAppls,attributes,
                prodCatalogId,configWrapper,itemType,itemGroup,dispatcher,cart,
                triggerExternalOpsBool,triggerPriceRulesBool,parentProduct,skipInventoryChecks,skipProductChecks);
     }
@@ -381,7 +398,7 @@ public class ShoppingCartItem implements
     public static ShoppingCartItem makeItem(Integer cartLocation, GenericValue product, BigDecimal selectedAmount,
             BigDecimal quantity, BigDecimal unitPrice, Timestamp reservStart, BigDecimal reservLength, BigDecimal reservPersons,
             String accommodationMapId,String accommodationSpotId,
-            Timestamp shipBeforeDate, Timestamp shipAfterDate, Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes,
+            Timestamp shipBeforeDate, Timestamp shipAfterDate, Timestamp reserveAfterDate, Map<String, GenericValue> additionalProductFeatureAndAppls, Map<String, Object> attributes,
             String prodCatalogId, ProductConfigWrapper configWrapper, String itemType, ShoppingCart.ShoppingCartItemGroup itemGroup, LocalDispatcher dispatcher,
             ShoppingCart cart, Boolean triggerExternalOpsBool, Boolean triggerPriceRulesBool, GenericValue parentProduct, Boolean skipInventoryChecks, Boolean skipProductChecks) throws CartItemModifyException {
 
@@ -466,6 +483,7 @@ public class ShoppingCartItem implements
         // set the ship before and after dates (defaults to cart ship before/after dates)
         newItem.setShipBeforeDate(shipBeforeDate != null ? shipBeforeDate : cart.getDefaultShipBeforeDate());
         newItem.setShipAfterDate(shipAfterDate != null ? shipAfterDate : cart.getDefaultShipAfterDate());
+        newItem.setReserveAfterDate(reserveAfterDate != null ? reserveAfterDate : cart.getDefaultReserveAfterDate());
 
         // set the product unit price as base price
         // if triggerPriceRules is true this price will be overriden
@@ -1494,6 +1512,16 @@ public class ShoppingCartItem implements
         return this.shipAfterDate != null ? (Timestamp) this.shipAfterDate.clone() : null;
     }
 
+    /** Sets the date to ship after */
+    public void setReserveAfterDate(Timestamp date) {
+        this.reserveAfterDate = date != null ? (Timestamp) date.clone() : null;
+    }
+
+    /** Returns the date to ship after */
+    public Timestamp getReserveAfterDate() {
+        return this.reserveAfterDate != null ? (Timestamp) this.reserveAfterDate.clone() : null;
+    }
+
     /** Sets the cancel back order date */
     public void setCancelBackOrderDate(Timestamp date) {
         this.cancelBackOrderDate = date != null ? (Timestamp) date.clone() : null;

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartServices.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartServices.java?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartServices.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartServices.java Mon Sep  3 08:15:08 2018
@@ -521,6 +521,7 @@ public class ShoppingCartServices {
                 cartItem.setDesiredDeliveryDate(item.getTimestamp("estimatedDeliveryDate"));
                 cartItem.setShipBeforeDate(item.getTimestamp("shipBeforeDate"));
                 cartItem.setShipAfterDate(item.getTimestamp("shipAfterDate"));
+                cartItem.setReserveAfterDate(item.getTimestamp("reserveAfterDate"));
                 cartItem.setShoppingList(item.getString("shoppingListId"), item.getString("shoppingListItemSeqId"));
                 cartItem.setIsModifiedPrice("Y".equals(item.getString("isModifiedPrice")));
                 cartItem.setName(item.getString("itemDescription"));

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/entry/OrderAgreements.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/entry/OrderAgreements.ftl?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/entry/OrderAgreements.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/entry/OrderAgreements.ftl Mon Sep  3 08:15:08 2018
@@ -175,6 +175,15 @@ under the License.
         </td>
       </tr>
 
+      <tr>
+        <td class="label">
+            <label>${uiLabelMap.OrderReserveAfterDateDefault}</label>
+        </td>
+        <td>
+            <@htmlTemplate.renderDateTimeField name="reserveAfterDate" event="" action="" value="" className="" alert="" title="Format: yyyy-MM-dd HH:mm:ss.SSS" size="25" maxlength="30" id="reserveAfterDate1" dateType="date" shortDateInput=false timeDropdownParamName="" defaultDateTimeString="" localizedIconTitle="" timeDropdown="" timeHourName="" classString="" hour1="" hour2="" timeMinutesName="" minutes="" isTwelveHour="" ampmName="" amSelected="" pmSelected="" compositeType="" formName=""/>
+        </td>
+      </tr>
+
       <#if "PURCHASE_ORDER" == cart.getOrderType()>
         <tr>
           <td class="label">

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/entry/cart/ShowCart.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/entry/cart/ShowCart.ftl?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/entry/cart/ShowCart.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/entry/cart/ShowCart.ftl Mon Sep  3 08:15:08 2018
@@ -135,6 +135,14 @@ under the License.
                     </div>
                   </td>
                 </tr>
+                <tr>
+                  <td align="right"><div>${uiLabelMap.OrderReserveAfterDate} :</div></td>
+                  <td>
+                    <div>
+                      <@htmlTemplate.renderDateTimeField name="reserveAfterDate" value="${shoppingCart.getDefaultReserveAfterDate()!''}" className="" alert="" title="Format: yyyy-MM-dd HH:mm:ss.SSS" size="25" maxlength="30" id="item4" dateType="date" shortDateInput=false timeDropdownParamName="" defaultDateTimeString="" localizedIconTitle="" timeDropdown="" timeHourName="" classString="" hour1="" hour2="" timeMinutesName="" minutes="" isTwelveHour="" ampmName="" amSelected="" pmSelected="" compositeType="" formName=""/>
+                    </div>
+                  </td>
+                </tr>
                 <#if "PURCHASE_ORDER" == shoppingCart.getOrderType()>
                 <tr>
                   <td align="right"><div>${uiLabelMap.OrderOrderItemType} :</div></td>

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/OrderHeaderInfo.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/OrderHeaderInfo.ftl?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/OrderHeaderInfo.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/OrderHeaderInfo.ftl Mon Sep  3 08:15:08 2018
@@ -184,6 +184,17 @@ under the License.
                 </td>
             </tr>
         </#if>
+        <#if defaultReserveAfterDate?has_content>
+            <tr>
+                <td align="right" valign="top" width="15%">
+                    <div>&nbsp;<b>${uiLabelMap.OrderReserveAfterDate}</b></div>
+                </td>
+                <td width="5">&nbsp;</td>
+                <td valign="top" width="80%">
+                  <div>${defaultReserveAfterDate}</div>
+                </td>
+            </tr>
+        </#if>
         </table>
     </div>
 </div>

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/order/EditOrderItems.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/order/EditOrderItems.ftl?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/order/EditOrderItems.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/order/EditOrderItems.ftl Mon Sep  3 08:15:08 2018
@@ -116,6 +116,16 @@ under the License.
                               <#-- now show status details per line item -->
                               <#assign currentItemStatus = orderItem.getRelatedOne("StatusItem", false)>
                               <td>
+                                  <table>
+                                      <tr>
+                                          <td class="label">
+                                              <span class="label">${uiLabelMap.OrderReserveAfterDate}</span>
+                                          </td>
+                                          <td>
+                                              <@htmlTemplate.renderDateTimeField name="iradm_${orderItem.orderItemSeqId!}" event="" action="" value="${orderItem.reserveAfterDate!}" className="" alert="" title="Format: yyyy-MM-dd HH:mm:ss.SSS" size="25" maxlength="30" id="reserveAfterDate_${orderItem.orderItemSeqId!}" dateType="date" shortDateInput=false timeDropdownParamName="" defaultDateTimeString="" localizedIconTitle="" timeDropdown="" timeHourName="" classString="" hour1="" hour2="" timeMinutesName="" minutes="" isTwelveHour="" ampmName="" amSelected="" pmSelected="" compositeType="" formName=""/>
+                                          </td>
+                                      </tr>
+                                  </table>
                                   ${uiLabelMap.CommonCurrent}&nbsp;${currentItemStatus.get("description",locale)?default(currentItemStatus.statusId)}<br />
                                   <#assign orderItemStatuses = orderReadHelper.getOrderItemStatuses(orderItem)>
                                   <#list orderItemStatuses as orderItemStatus>

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderItems.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderItems.ftl?rev=1839914&r1=1839913&r2=1839914&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderItems.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderItems.ftl Mon Sep  3 08:15:08 2018
@@ -182,6 +182,17 @@ under the License.
                                 <#-- now show status details per line item -->
                                 <#assign currentItemStatus = orderItem.getRelatedOne("StatusItem", false)>
                                 <td colspan="1" valign="top">
+                                    <table>
+                                        <tr>
+                                            <td class="label">
+                                                <span class="label">${uiLabelMap.OrderReserveAfterDate}</span>
+                                            </td>
+                                            <td>
+                                                ${orderItem.reserveAfterDate!}
+                                            </td>
+                                        </tr>
+                                    </table>
+
                                     <div class="screenlet order-item-status-list<#if currentItemStatus.statusCode?has_content> ${currentItemStatus.statusCode}</#if>">
                                         <div class="screenlet-body">
                                             <div class="current-status">