svn commit: r1825002 - in /ofbiz/ofbiz-framework/trunk/applications: datamodel/data/demo/ datamodel/entitydef/ order/groovyScripts/entry/ order/minilang/order/ order/servicedef/ order/src/main/java/org/apache/ofbiz/order/order/ order/src/main/java/org/...

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

svn commit: r1825002 - in /ofbiz/ofbiz-framework/trunk/applications: datamodel/data/demo/ datamodel/entitydef/ order/groovyScripts/entry/ order/minilang/order/ order/servicedef/ order/src/main/java/org/apache/ofbiz/order/order/ order/src/main/java/org/...

nmalin
Author: nmalin
Date: Wed Feb 21 20:40:53 2018
New Revision: 1825002

URL: http://svn.apache.org/viewvc?rev=1825002&view=rev
Log:
Implemented: Use agreement on drop shipment process (OFBIZ-10227)

Extend the drop shipment process to manage an agreement for the supplier related to the order context.
For a supplier we have different agreements with same products but on different prices

Agreement A
  GIZMO-1 100€
  GIZMO-1 110$
Agreement B
  GIZMO-1 90€
Agreement C
  GIZMO-1 600¥

During sales order process we resolve the purchase agreement that match the case and put on OrderItemShipGroup related to the supplier. Like that when the drop shipment process run it to resolve the product price for the agreement present on the OrderItemShipGroup. With this implementation we have an adaptable system to manage complex case.

Properly this patch implemented :
  an attribute on entity OrderItemShipGroup.supplierAgreementId
  an attribute on entity OrderHeader.agreementId (necessary when you update the order to keep the price)
  update the service caculatePurchasePrice for resolve the price from a agreement if it's present
  update the shoppingCart to insert a purchase agreement

Modified:
    ofbiz/ofbiz-framework/trunk/applications/datamodel/data/demo/OrderDemoData.xml
    ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/order-entitymodel.xml
    ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/ShipSettings.groovy
    ofbiz/ofbiz-framework/trunk/applications/order/minilang/order/OrderServices.xml
    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/CheckOutEvents.java
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutHelper.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/ShoppingCartItem.java
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/ShoppingCartServices.java
    ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
    ofbiz/ofbiz-framework/trunk/applications/order/template/entry/ShipSettings.ftl
    ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/ShipGroupConfirmSummary.ftl
    ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderInfo.ftl
    ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderShippingInfo.ftl
    ofbiz/ofbiz-framework/trunk/applications/product/config/ProductUiLabels.xml
    ofbiz/ofbiz-framework/trunk/applications/product/servicedef/services_pricepromo.xml
    ofbiz/ofbiz-framework/trunk/applications/product/src/main/java/org/apache/ofbiz/product/price/PriceServices.java

Modified: ofbiz/ofbiz-framework/trunk/applications/datamodel/data/demo/OrderDemoData.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/datamodel/data/demo/OrderDemoData.xml?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/datamodel/data/demo/OrderDemoData.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/datamodel/data/demo/OrderDemoData.xml Wed Feb 21 20:40:53 2018
@@ -869,6 +869,24 @@ under the License.
     <ContentAssoc contentId="SV-1001-ALT" contentIdTo="CSV-1001-ALTEN" contentAssocTypeId="ALTERNATE_LOCALE" fromDate="2011-08-02 12:00:00.0"/>
     <ProductContent productId="SV-1001" contentId="SV-1001-ALT" productContentTypeId="ALTERNATIVE_URL" fromDate="2011-08-02 12:00:00.0"/>
 
+    <!-- test for product shipped from drop shipment and with agreement to resolve the purchase price
+       To test: create a sales order for DemoCustomer with the product DS-100
+       On shipping plan, select DemoSupplier as supplier and agreement DS-1000-PURCH as supplier agreement
+       When the order will be create, the purchase order create will be haave unit price 8 instead 9.
+    -->
+    <Product productId="DS-1000" productTypeId="FINISHED_GOOD" primaryProductCategoryId="PROMOTIONS" productName="Drop ship product" internalName="drop ship" description="product shipped from drop shipment and with agreement to resolve the purchase price" taxable="Y" chargeShipping="N" autoCreateKeywords="Y" isVirtual="N" isVariant="N" requirementMethodEnumId="PRODRQM_DS"/>
+    <ProductPrice productId="DS-1000" productPricePurposeId="PURCHASE" productPriceTypeId="DEFAULT_PRICE" currencyUomId="USD" productStoreGroupId="_NA_" fromDate="2011-08-02 12:00:00.0" price="10" />
+    <SupplierProduct partyId="DemoSupplier" minimumOrderQuantity="0" currencyUomId="USD" productId="DS-1000" lastPrice="9.0" supplierProductId="DS-1000_A" supplierProductName="Drop SP" availableFromDate="2005-01-01 00:00:00.000" canDropShip="Y"/>
+    <ProductCategoryMember productCategoryId="200" productId="DS-1000" fromDate="2011-08-02 12:00:00.0"/>
+    <ProductCategoryMember productCategoryId="CATALOG1_SEARCH" productId="SV-1001" fromDate="2011-08-02 12:00:00.0"/>
+    <PartyRole partyId="DemoCustomer" roleTypeId="CUSTOMER"/>
+    <Agreement agreementId="DS-1000-SALES" agreementTypeId="SALES_AGREEMENT" description="Agreement with DemoCustomer for drop ship" partyIdFrom="DemoCustomer" partyIdTo="Company" roleTypeIdFrom="CUSTOMER" roleTypeIdTo="INTERNAL_ORGANIZATIO" fromDate="2011-08-02 12:00:00.0"/>
+    <AgreementItem agreementId="DS-1000-SALES" agreementItemSeqId="00001" agreementItemTypeId="AGREEMENT_PRICING_PR" currencyUomId="USD"/>
+    <AgreementProductAppl agreementId="DS-1000-SALES" agreementItemSeqId="00001" price="12" productId="DS-1000"/>
+    <Agreement agreementId="DS-1000-PURCH" agreementTypeId="PURCHASE_AGREEMENT" description="Agreement with DemoSupplier" partyIdFrom="Company" partyIdTo="DemoSupplier" fromDate="2011-08-02 12:00:00.0"/>
+    <AgreementItem agreementId="DS-1000-PURCH" agreementItemSeqId="00001" agreementItemTypeId="AGREEMENT_PRICING_PR" currencyUomId="USD"/>
+    <AgreementProductAppl agreementId="DS-1000-PURCH" agreementItemSeqId="00001" price="8" productId="DS-1000"/>
+
     <!-- test for the configurable product type which is received to- and shipped from inventory-->
     <Product productId="CFSV1001" productTypeId="AGGREGATED_SERVICE" primaryProductCategoryId="SERV-001" productName="Scanning book service" internalName="The configurable product type which is received to- and shipped from inventory" description="The configurable product type which is received to- and shipped from inventory for demonstration use" taxable="Y" chargeShipping="N" autoCreateKeywords="Y" isVirtual="N" isVariant="N" createdDate="2008-12-02 12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2008-12-02 12:00:00.0" lastModifiedByUserLogin="admin"/>
     <Product productId="SCAN_TYPE" productTypeId="SERVICE_PRODUCT" productName="Scanning Type" internalName="Scanning Type" description="Scanning Type" isVirtual="Y" isVariant="N" billOfMaterialLevel="0" createdDate="2004-08-20 12:50:54.794" createdByUserLogin="admin"/>

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=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/order-entitymodel.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/order-entitymodel.xml Wed Feb 21 20:40:53 2018
@@ -388,6 +388,7 @@ under the License.
       <field name="originFacilityId" type="id"></field>
       <field name="webSiteId" type="id"></field>
       <field name="productStoreId" type="id"></field>
+      <field name="agreementId" type="id"/>
       <field name="terminalId" type="id-long"></field>
       <field name="transactionId" type="id-long"></field>
       <field name="autoOrderShoppingListId" type="id"></field>
@@ -859,6 +860,7 @@ under the License.
       <field name="shipGroupSeqId" type="id"></field>
       <field name="shipmentMethodTypeId" type="id" enable-audit-log="true"></field>
       <field name="supplierPartyId" type="id"></field>
+      <field name="supplierAgreementId" type="id"/>
       <field name="vendorPartyId" type="id"><description>For use with multi-vendor stores, order will be split so that each ship group is associated with only one vendor (only if applicable)</description></field>
       <field name="carrierPartyId" type="id" enable-audit-log="true"></field>
       <field name="carrierRoleTypeId" type="id"></field>
@@ -882,6 +884,9 @@ under the License.
       <relation type="one" fk-name="ORDER_ITSG_SPRTY" title="Supplier" rel-entity-name="Party">
         <key-map field-name="supplierPartyId" rel-field-name="partyId"/>
       </relation>
+      <relation type="one" fk-name="ORDER_ITSG_SAGR" title="Supplier" rel-entity-name="Agreement">
+        <key-map field-name="supplierAgreementId" rel-field-name="agreementId"/>
+      </relation>
       <relation type="one" fk-name="ORDER_ITSG_VPRTY" title="Vendor" rel-entity-name="Party">
         <key-map field-name="vendorPartyId" rel-field-name="partyId"/>
       </relation>

Modified: ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/ShipSettings.groovy
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/ShipSettings.groovy?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/ShipSettings.groovy (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/groovyScripts/entry/ShipSettings.groovy Wed Feb 21 20:40:53 2018
@@ -17,6 +17,10 @@
  * under the License.
  */
 
+
+import org.apache.ofbiz.entity.condition.EntityCondition
+import org.apache.ofbiz.entity.condition.EntityConditionBuilder
+import org.apache.ofbiz.entity.util.EntityUtil
 import org.apache.ofbiz.party.contact.ContactHelper
 import org.apache.ofbiz.party.contact.ContactMechWorker
 import org.apache.ofbiz.base.util.UtilValidate
@@ -64,6 +68,14 @@ if ("SALES_ORDER".equals(cart.getOrderTy
     suppliers = from("PartyRole").where("roleTypeId", "SUPPLIER").queryList()
     context.suppliers = suppliers
 
+    //resolve Purchase agreements
+    EntityConditionBuilder conditionBuilder = new EntityConditionBuilder()
+    EntityCondition agreementCond = conditionBuilder.AND() {
+        IN(partyIdTo: EntityUtil.getFieldListFromEntityList(suppliers, 'partyId', true))
+        EQUALS(agreementTypeId: 'PURCHASE_AGREEMENT')
+    }
+    context.supplierAgreements = from("Agreement").where(agreementCond).queryList()
+
     // facilities used to reserve the items per ship group
     productStoreFacilities = from("ProductStoreFacility").where("productStoreId", cart.getProductStoreId()).queryList()
     context.productStoreFacilities = productStoreFacilities

Modified: ofbiz/ofbiz-framework/trunk/applications/order/minilang/order/OrderServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/minilang/order/OrderServices.xml?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/minilang/order/OrderServices.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/minilang/order/OrderServices.xml Wed Feb 21 20:40:53 2018
@@ -1105,7 +1105,7 @@ under the License.
         <field-to-result field="parameters.paymentMethodId" result-name="paymentMethodId"/>
     </simple-method>
 
-    <simple-method method-name="setUnitPriceAsLastPrice" short-description="Set unitPrice as lastPrice on create purchase order, edit purchase order items and on receive inventory against a purchase order">
+    <simple-method method-name="setUnitPriceAsLastPrice" short-description="Set unitPrice as lastPrice on create purchase order, edit purchase order items and on receive inventory against a purchase order, but only if the order price didn't come from an agreement">
         <if>
             <condition>
                 <and>
@@ -1158,6 +1158,11 @@ under the License.
                         </and>
                     </condition>
                     <then>
+                        <entity-one entity-name="OrderHeader" value-field="order"/>
+                        <!--Do not update lastPrice if an agreement has been used on the order -->
+                        <if-not-empty field="order.agreementId"><!--TODO replace by orderPItemPriceInfo analyse when it will support agreement-->
+                            <return/>
+                        </if-not-empty>
                         <entity-and entity-name="OrderItem" list="orderItems">
                             <field-map field-name="orderId" from-field="parameters.orderId"/>
                         </entity-and>

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=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml Wed Feb 21 20:40:53 2018
@@ -108,6 +108,7 @@ under the License.
         <attribute name="webSiteId" type="String" mode="IN" optional="true"/>
         <attribute name="externalId" type="String" mode="IN" optional="true"/>
         <attribute name="internalCode" type="String" mode="IN" optional="true"/>
+        <attribute name="agreementId" type="String" mode="IN" optional="true"/>
         <attribute name="distributorId" type="String" mode="IN" optional="true"/>
         <attribute name="orderTypeId" type="String" mode="INOUT" optional="false"/>
         <attribute name="salesChannelEnumId" type="String" mode="IN" optional="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=1825002&r1=1825001&r2=1825002&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 Wed Feb 21 20:40:53 2018
@@ -477,6 +477,7 @@ public class OrderServices {
                 "orderDate", orderDate, "entryDate", nowTimestamp,
                 "statusId", initialStatus, "billingAccountId", billingAccountId);
         orderHeaderMap.put("orderName", context.get("orderName"));
+        orderHeaderMap.put("agreementId", context.get("agreementId"));
         if (isImmediatelyFulfilled) {
             // also flag this order as needing inventory issuance so that when it is set to complete it will be issued immediately (needsInventoryIssuance = Y)
             orderHeaderMap.put("needsInventoryIssuance", "Y");
@@ -4980,6 +4981,7 @@ public class OrderServices {
                         cart.setBillToCustomerPartyId(cart.getBillFromVendorPartyId()); //Company
                         cart.setBillFromVendorPartyId(supplierPartyId);
                         cart.setOrderPartyId(supplierPartyId);
+                        cart.setAgreementId(shipGroup.getString("supplierAgreementId"));
                         // Get the items associated to it and create po
                         List<GenericValue> items = orh.getValidOrderItems(shipGroup.getString("shipGroupSeqId"));
                         if (UtilValidate.isNotEmpty(items)) {
@@ -5009,6 +5011,8 @@ public class OrderServices {
 
                         // If there are indeed items to drop ship, then create the purchase order
                         if (UtilValidate.isNotEmpty(cart.items())) {
+                            //resolve supplier promotion
+                            ProductPromoWorker.doPromotions(cart, dispatcher);
                             // set checkout options
                             cart.setDefaultCheckoutOptions(dispatcher);
                             // the shipping address is the one of the customer

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutEvents.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutEvents.java?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutEvents.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutEvents.java Wed Feb 21 20:40:53 2018
@@ -118,7 +118,8 @@ public class CheckOutEvents {
                     shippingContactMechId = (String) request.getAttribute("contactMechId"); // FIXME
                 }
                 String supplierPartyId = (String) request.getAttribute(shipGroupIndex + "_supplierPartyId");
-                Map<String, ? extends Object> callResult = checkOutHelper.finalizeOrderEntryShip(shipGroupIndex, shippingContactMechId, supplierPartyId);
+                String supplierAgreementId = (String) request.getAttribute(shipGroupIndex + "_supplierAgreementId");
+                Map<String, ? extends Object> callResult = checkOutHelper.finalizeOrderEntryShip(shipGroupIndex, shippingContactMechId, supplierPartyId, supplierAgreementId);
                 ServiceUtil.addErrors(errorMessages, errorMaps, callResult);
             }
 
@@ -835,6 +836,7 @@ public class CheckOutEvents {
                         }
                     }
                     String supplierPartyId = request.getParameter(shipGroupIndex + "_supplierPartyId");
+                    String supplierAgreementId = request.getParameter(shipGroupIndex + "_supplierAgreementId");
                     if (UtilValidate.isNotEmpty(facilityId)) {
                         cart.setShipGroupFacilityId(shipGroupIndex, facilityId);
                     }
@@ -845,7 +847,7 @@ public class CheckOutEvents {
                     } else {
                         cart.setShipToCustomerPartyId(request.getParameter("orderPartyId"));
                     }
-                    callResult = checkOutHelper.finalizeOrderEntryShip(shipGroupIndex, shippingContactMechId, supplierPartyId);
+                    callResult = checkOutHelper.finalizeOrderEntryShip(shipGroupIndex, shippingContactMechId, supplierPartyId, supplierAgreementId);
                     ServiceUtil.addErrors(errorMessages, errorMaps, callResult);
                 }
                 // set the options

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutHelper.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutHelper.java?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutHelper.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/CheckOutHelper.java Wed Feb 21 20:40:53 2018
@@ -599,6 +599,7 @@ public class CheckOutHelper {
         }
         context.put("webSiteId", webSiteId);
         context.put("originOrderId", originOrderId);
+        context.put("agreementId", cart.getAgreementId());
 
         // need the partyId; don't use userLogin in case of an order via order mgr
         String partyId = this.cart.getPartyId();
@@ -1378,10 +1379,12 @@ public class CheckOutHelper {
      *
      * @param shipGroupIndex The index of the ship group in the cart
      * @param shippingContactMechId The identifier of the contact
+     * @param supplierPartyId The identifier of the supplier to use for the drop shipment
+     * @param supplierAgreementId The identifier of the agreement with the supplier
      * @return A Map conforming to the OFBiz Service conventions containing
      * any error messages
      */
-    public Map<String, Object> finalizeOrderEntryShip(int shipGroupIndex, String shippingContactMechId, String supplierPartyId) {
+    public Map<String, Object> finalizeOrderEntryShip(int shipGroupIndex, String shippingContactMechId, String supplierPartyId, String supplierAgreementId) {
         Map<String, Object> result;
         String errMsg=null;
         //Verify the field is valid
@@ -1389,6 +1392,9 @@ public class CheckOutHelper {
             this.cart.setShippingContactMechId(shipGroupIndex, shippingContactMechId);
             if (UtilValidate.isNotEmpty(supplierPartyId)) {
                 this.cart.setSupplierPartyId(shipGroupIndex, supplierPartyId);
+                if (UtilValidate.isNotEmpty(supplierAgreementId)) {
+                    this.cart.setSupplierAgreementId(shipGroupIndex, supplierAgreementId);
+                }
             }
             result = ServiceUtil.returnSuccess();
         } else {

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=1825002&r1=1825001&r2=1825002&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 Wed Feb 21 20:40:53 2018
@@ -2369,6 +2369,18 @@ public class ShoppingCart implements Ite
         return csi.supplierPartyId;
     }
 
+    /** Sets the supplier agreement for the given ship group (drop shipment). */
+    public void setSupplierAgreementId(int idx, String supplierAgreementId) {
+        CartShipInfo csi = this.getShipInfo(idx);
+        csi.supplierAgreementId = supplierAgreementId;
+    }
+
+    /** Returns the supplier Agreement for the given ship group (drop shipment). */
+    public String getSupplierAgreementId(int idx) {
+        CartShipInfo csi = this.getShipInfo(idx);
+        return csi.supplierAgreementId;
+    }
+
     /** Sets the shipping instructions. */
     public void setShippingInstructions(int idx, String shippingInstructions) {
         CartShipInfo csi = this.getShipInfo(idx);
@@ -4337,6 +4349,7 @@ public class ShoppingCart implements Ite
                 shipInfo = this.shipInfo.get(newShipGroupIndex);
             }
             shipInfo.supplierPartyId = supplierPartyId;
+            shipInfo.supplierAgreementId = null;
 
             Map<ShoppingCartItem, Map<Integer, BigDecimal>> supplierCartItems = UtilGenerics.checkMap(supplierPartyEntry.getValue());
             for (Entry<ShoppingCartItem, Map<Integer, BigDecimal>> cartItemEntry : supplierCartItems.entrySet()) {
@@ -4578,6 +4591,7 @@ public class ShoppingCart implements Ite
         public String telecomContactMechId = null;
         public String shipmentMethodTypeId = null;
         public String supplierPartyId = null;
+        public String supplierAgreementId = null;
         public String carrierRoleTypeId = null;
         public String carrierPartyId = null;
         private String facilityId = null;
@@ -4616,6 +4630,7 @@ public class ShoppingCart implements Ite
 
         public String getCarrierPartyId() { return carrierPartyId; }
         public String getSupplierPartyId() { return supplierPartyId; }
+        public String getSupplierAgreementId() { return supplierAgreementId; }
         public String getShipmentMethodTypeId() { return shipmentMethodTypeId; }
         public BigDecimal getShipEstimate() { return shipEstimate; }
 
@@ -4673,6 +4688,7 @@ public class ShoppingCart implements Ite
             shipGroup.set("carrierRoleTypeId", carrierRoleTypeId);
             shipGroup.set("carrierPartyId", carrierPartyId);
             shipGroup.set("supplierPartyId", supplierPartyId);
+            shipGroup.set("supplierAgreementId", supplierAgreementId);
             shipGroup.set("shippingInstructions", shippingInstructions);
             shipGroup.set("giftMessage", giftMessage);
             shipGroup.set("contactMechId", this.internalContactMechId);

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=1825002&r1=1825001&r2=1825002&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 Wed Feb 21 20:40:53 2018
@@ -251,7 +251,9 @@ public class ShoppingCartItem implements
         if (supplierProduct != null) {
             newItem.setSupplierProductId(supplierProduct.getString("supplierProductId"));
             newItem.setName(getPurchaseOrderItemDescription(product, supplierProduct, cart.getLocale(), dispatcher));
-            newItem.setBasePrice(supplierProduct.getBigDecimal("lastPrice"));
+            if (newItem.getBasePrice().compareTo(BigDecimal.ZERO) == 0) {
+                newItem.setBasePrice(supplierProduct.getBigDecimal("lastPrice"));
+            }
         } else {
             newItem.setName(product.getString("internalName"));
         }
@@ -1088,6 +1090,7 @@ public class ShoppingCartItem implements
 
                 if ("PURCHASE_ORDER".equals(cart.getOrderType())) {
                     priceContext.put("currencyUomId", cart.getCurrency());
+                    priceContext.put("agreementId", cart.getAgreementId());
                     Map<String, Object> priceResult = dispatcher.runSync("calculatePurchasePrice", priceContext);
                     if (ServiceUtil.isError(priceResult)) {
                         String errorMessage = ServiceUtil.getErrorMessage(priceResult);

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=1825002&r1=1825001&r2=1825002&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 Wed Feb 21 20:40:53 2018
@@ -210,6 +210,7 @@ public class ShoppingCartServices {
         cart.setOrderStatusId(orderHeader.getString("statusId"));
         cart.setOrderStatusString(currentStatusString);
         cart.setFacilityId(orderHeader.getString("originFacilityId"));
+        cart.setAgreementId(orderHeader.getString("agreementId"));
 
         try {
             cart.setUserLogin(userLogin, dispatcher);

Modified: ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/product/ProductPromoWorker.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/product/ProductPromoWorker.java?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/product/ProductPromoWorker.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/shoppingcart/product/ProductPromoWorker.java Wed Feb 21 20:40:53 2018
@@ -58,6 +58,7 @@ import org.apache.ofbiz.order.shoppingca
 import org.apache.ofbiz.order.shoppingcart.ShoppingCartItem;
 import org.apache.ofbiz.product.product.ProductContentWrapper;
 import org.apache.ofbiz.product.product.ProductSearch;
+import org.apache.ofbiz.product.store.ProductStoreWorker;
 import org.apache.ofbiz.service.GenericServiceException;
 import org.apache.ofbiz.service.LocalDispatcher;
 import org.apache.ofbiz.service.ModelService;
@@ -282,10 +283,8 @@ public final class ProductPromoWorker {
             List<GenericValue> agreementPromoApplsList = agreementItem.getRelated("AgreementPromoAppl", null, UtilMisc.toList("sequenceNum"), true);
             agreementPromoApplsList = EntityUtil.filterByDate(agreementPromoApplsList, nowTimestamp);
 
-            if (UtilValidate.isEmpty(agreementPromoApplsList)) {
-                if (Debug.verboseOn()) {
+            if (Debug.verboseOn() && UtilValidate.isEmpty(agreementPromoApplsList)) {
                     Debug.logVerbose("Not doing promotions, none applied to agreement with ID " + agreementId, module);
-                }
             }
 
             Iterator<GenericValue> agreementPromoAppls = UtilMisc.toIterator(agreementPromoApplsList);

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/entry/ShipSettings.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/entry/ShipSettings.ftl?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/entry/ShipSettings.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/entry/ShipSettings.ftl Wed Feb 21 20:40:53 2018
@@ -190,6 +190,13 @@ under the License.
                           <option value="${supplier.partyId}"<#if supplierPartyId??><#if supplier.partyId == supplierPartyId> selected="selected"</#if></#if>>${Static["org.apache.ofbiz.party.party.PartyHelper"].getPartyName(supplier, true)}</option>
                         </#list>
                       </select>
+                      ${uiLabelMap.AccountingAgreement}:
+                      <select name="${shipGroupIndex?default("0")}_supplierAgreementId">
+                        <option value=""></option>
+                        <#list supplierAgreements as agreement>
+                          <option value="${agreement.agreementId}"<#if supplierAgreementId??><#if agreement.agreementId == supplierAgreementId> selected="selected"</#if></#if>>${agreement.description}</option>
+                        </#list>
+                      </select>
                       ${uiLabelMap.ProductReserveInventoryFromFacility}:
                       <select name="${shipGroupIndex?default("0")}_shipGroupFacilityId">
                         <option value=""></option>

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/ShipGroupConfirmSummary.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/ShipGroupConfirmSummary.ftl?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/ShipGroupConfirmSummary.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/entry/order/ShipGroupConfirmSummary.ftl Wed Feb 21 20:40:53 2018
@@ -83,7 +83,7 @@ standard order confirmation page and to
 
         <td rowspan="${numberOfItems}" valign="top">
           <#assign supplier =  delegator.findOne("PartyGroup", Static["org.apache.ofbiz.base.util.UtilMisc"].toMap("partyId", cartShipInfo.getSupplierPartyId()), false)! />
-          <#if supplier?has_content>${supplier.groupName?default(supplier.partyId)}</#if>
+          <#if supplier?has_content>${supplier.groupName?default(supplier.partyId)} <#if cartShipInfo.getSupplierAgreementId()??> (${cartShipInfo.getSupplierAgreementId()})</#if></#if>
         </td>
 
         <#-- carrier column (also spans rows = number of items) -->

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderInfo.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderInfo.ftl?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderInfo.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderInfo.ftl Wed Feb 21 20:40:53 2018
@@ -192,6 +192,16 @@ under the License.
                   </#if>
               </td>
             </tr>
+            <#if orderHeader.agreementId?has_content>
+            <tr><td colspan="3"><hr /></td></tr>
+            <tr>
+              <td align="right" valign="top" width="15%" class="label">&nbsp;${uiLabelMap.AccountingAgreement}</td>
+              <td width="5%">&nbsp;</td>
+              <td valign="top" width="80%">
+                    <a href="<@ofbizUrl>/accounting/control/EditAgreement?agreementId=${orderHeader.agreementId}</@ofbizUrl>" class="buttontext">${orderHeader.agreementId}</a>
+              </td>
+            </tr>
+            </#if>
             <#if (orderItem.cancelBackOrderDate)??>
               <tr><td colspan="3"><hr /></td></tr>
               <tr>

Modified: ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderShippingInfo.ftl
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderShippingInfo.ftl?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderShippingInfo.ftl (original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/template/order/OrderShippingInfo.ftl Wed Feb 21 20:40:53 2018
@@ -537,6 +537,17 @@ under the License.
                 ${Static["org.apache.ofbiz.party.party.PartyHelper"].getPartyName(delegator, shipGroup.supplierPartyId, false)!shipGroup.supplierPartyId}
               </td>
             </tr>
+            <#if shipGroup.supplierAgreementId??>
+            <tr>
+              <td align="right" valign="top" width="15%">
+                  <span class="label">&nbsp;${uiLabelMap.AccountingAgreement}</span>
+              </td>
+              <td width="5">&nbsp;</td>
+              <td valign="top" width="80%">
+                  ${shipGroup.supplierAgreementId}
+              </td>
+            </tr>
+            </#if>
           </#if>
   
           <#-- This section appears when Shipment of order is in picked status and its items are packed,this case comes when new shipping estimates based on weight of packages are more than or less than default percentage (defined in shipment.properties) of original shipping estimate-->

Modified: ofbiz/ofbiz-framework/trunk/applications/product/config/ProductUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/product/config/ProductUiLabels.xml?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/product/config/ProductUiLabels.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/product/config/ProductUiLabels.xml Wed Feb 21 20:40:53 2018
@@ -13019,6 +13019,10 @@
         <value xml:lang="zh">合同</value>
         <value xml:lang="zh-TW">合約</value>
     </property>
+    <property key="ProductAgreementUse">
+        <value xml:lang="en">Product agreement use</value>
+        <value xml:lang="fr">Accord produit utilisé</value>
+    </property>
     <property key="ProductAisle">
         <value xml:lang="de">Gang</value>
         <value xml:lang="en">Aisle</value>

Modified: ofbiz/ofbiz-framework/trunk/applications/product/servicedef/services_pricepromo.xml
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/product/servicedef/services_pricepromo.xml?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/product/servicedef/services_pricepromo.xml (original)
+++ ofbiz/ofbiz-framework/trunk/applications/product/servicedef/services_pricepromo.xml Wed Feb 21 20:40:53 2018
@@ -323,6 +323,7 @@ under the License.
         <attribute name="partyId" type="String" mode="IN" optional="true"/>
         <attribute name="quantity" type="BigDecimal" mode="IN" optional="true"/>
         <attribute name="amount" type="BigDecimal" mode="IN" optional="true"/>
+        <attribute name="agreementId" type="String" mode="IN" optional="true"/>
 
         <attribute name="price" type="BigDecimal" mode="OUT" optional="false"/>
         <attribute name="validPriceFound" type="Boolean" mode="OUT" optional="false"/>

Modified: ofbiz/ofbiz-framework/trunk/applications/product/src/main/java/org/apache/ofbiz/product/price/PriceServices.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/product/src/main/java/org/apache/ofbiz/product/price/PriceServices.java?rev=1825002&r1=1825001&r2=1825002&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/product/src/main/java/org/apache/ofbiz/product/price/PriceServices.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/product/src/main/java/org/apache/ofbiz/product/price/PriceServices.java Wed Feb 21 20:40:53 2018
@@ -40,6 +40,7 @@ import org.apache.ofbiz.entity.Delegator
 import org.apache.ofbiz.entity.GenericEntityException;
 import org.apache.ofbiz.entity.GenericValue;
 import org.apache.ofbiz.entity.condition.EntityCondition;
+import org.apache.ofbiz.entity.condition.EntityExpr;
 import org.apache.ofbiz.entity.condition.EntityOperator;
 import org.apache.ofbiz.entity.util.EntityQuery;
 import org.apache.ofbiz.entity.util.EntityUtil;
@@ -1218,13 +1219,76 @@ public class PriceServices {
 
         GenericValue product = (GenericValue)context.get("product");
         String productId = product.getString("productId");
+        String agreementId = (String)context.get("agreementId");
         String currencyUomId = (String)context.get("currencyUomId");
         String partyId = (String)context.get("partyId");
         BigDecimal quantity = (BigDecimal)context.get("quantity");
         Locale locale = (Locale)context.get("locale");
 
         // a) Get the Price from the Agreement* data model
-        // TODO: Implement this
+        if (Debug.infoOn()) Debug.logInfo("Try to resolve purchase price from agreement " + agreementId, module);
+        if (UtilValidate.isNotEmpty(agreementId)) {
+            //TODO Search before if agreement is associate to SupplierProduct.
+            //confirm that agreement is price application on purchase type and contains a value for the product
+            EntityCondition cond = EntityCondition.makeCondition(
+                    UtilMisc.toList(
+                            EntityExpr.makeCondition("agreementId", agreementId),
+                            EntityExpr.makeCondition("agreementItemTypeId", "AGREEMENT_PRICING_PR"),
+                            EntityExpr.makeCondition("agreementTypeId", "PURCHASE_AGREEMENT"),
+                            EntityExpr.makeCondition("productId", productId)));
+            try {
+                List<GenericValue> agreementPrices = delegator.findList("AgreementItemAndProductAppl", cond, UtilMisc.toSet("price", "currencyUomId"), null, null, true);
+                if (UtilValidate.isNotEmpty(agreementPrices)) {
+                    GenericValue priceFound = null;
+                    //resolve price on given currency. If not define, try to convert a present price
+                    priceFound = EntityUtil.getFirst(EntityUtil.filterByAnd(agreementPrices, UtilMisc.toMap("currencyUomId", currencyUomId)));
+                    if (Debug.infoOn()) {
+                        Debug.logInfo("             AgreementItem " + agreementPrices, module);
+                        Debug.logInfo("             currencyUomId " + currencyUomId, module);
+                        Debug.logInfo("             priceFound " + priceFound, module);
+                    }
+                    if (priceFound == null) {
+                        priceFound = EntityUtil.getFirst(agreementPrices);
+                        try {
+                            Map<String, Object> priceConvertMap = UtilMisc.toMap("uomId", priceFound.getString("currencyUomId"), "uomIdTo", currencyUomId,
+                                    "originalValue", priceFound.getBigDecimal("price"), "defaultDecimalScale" , Long.valueOf(2) , "defaultRoundingMode" , "HalfUp");
+                            Map<String, Object> priceResults = dispatcher.runSync("convertUom", priceConvertMap);
+                            if (ServiceUtil.isError(priceResults) || (priceResults.get("convertedValue") == null)) {
+                                Debug.logWarning("Unable to convert " + priceFound + " for product  " + productId , module);
+                            } else {
+                                price = (BigDecimal) priceResults.get("convertedValue");
+                                validPriceFound = true;
+                            }
+                        } catch (GenericServiceException e) {
+                            Debug.logError(e, module);
+                        }
+                    } else {
+                        price = priceFound.getBigDecimal("price");
+                        validPriceFound = true;
+                    }
+                }
+                if (validPriceFound) {
+                    GenericValue agreement = delegator.findOne("Agreement", true, UtilMisc.toMap("agreementId", agreementId));
+                    StringBuilder priceInfoDescription = new StringBuilder();
+                    priceInfoDescription.append(UtilProperties.getMessage(resource, "ProductAgreementUse", locale));
+                    priceInfoDescription.append("[");
+                    priceInfoDescription.append(agreementId);
+                    priceInfoDescription.append("] ");
+                    priceInfoDescription.append(agreement.get("description"));
+                    GenericValue orderItemPriceInfo = delegator.makeValue("OrderItemPriceInfo");
+                    // make sure description is <= than 250 chars
+                    String priceInfoDescriptionString = priceInfoDescription.toString();
+                    if (priceInfoDescriptionString.length() > 250) {
+                        priceInfoDescriptionString = priceInfoDescriptionString.substring(0, 250);
+                    }
+                    orderItemPriceInfo.set("description", priceInfoDescriptionString);
+                    orderItemPriceInfos.add(orderItemPriceInfo);
+                }
+            } catch (GenericEntityException gee) {
+                Debug.logError(gee, module);
+                return ServiceUtil.returnError(gee.getMessage());
+            }
+        }
 
         // b) If no price can be found, get the lastPrice from the SupplierProduct entity
         if (!validPriceFound) {