This is an automated email from the ASF dual-hosted git repository.

nmalin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 57bf0ce268 Improved: Convert OrderServices.xml mini-lang to groovyDSL 
(OFBIZ-9984) (#870)
57bf0ce268 is described below

commit 57bf0ce26838067b77b7f012b5defd22168022b9
Author: Nicolas Malin <nicolas.ma...@nereide.fr>
AuthorDate: Fri Jan 3 13:31:50 2025 +0100

    Improved: Convert OrderServices.xml mini-lang to groovyDSL (OFBIZ-9984) 
(#870)
    
    
    
    Fix error in ensureRouteSegPackage
    Migration of the services:
    
        recreateOrderAdjustments
        getOrderItemShipGroupEstimatedShipDate
        updateOrderNote
        getOrderStatus
        orderSequence_enforced
        createOrderHeader
        updateOrderHeader
        updateOrderItemShipGroup
        updateOrderContactMech
        addPaymentMethodToOrder
        checkOrderIsOnBackOrder
        createOrderItemChange
        createUpdateShippingAddress
        createUpdateBillingAddress
        createUpdateCreditCard
        setUnitPriceAsLastPrice
        cancelAllBackOrders
        updateShippingMethodAndCharges
        productAvailabilityByFacility
        createOrderPaymentApplication
        moveItemBetweenShipGroups
    
    Thanks to Julien NICOLAS, Gil PORTENSEIGNE, Sebastian Berg and Leila MEKIKA 
for work on it
    
    ---------
    
    Co-authored-by: Leila <leila.mek...@nereide.fr>
---
 .../order/minilang/customer/CheckoutMapProcs.xml   |  90 --
 .../order/minilang/order/OrderServices.xml         | 978 ---------------------
 applications/order/servicedef/services.xml         |  91 +-
 .../ofbiz/order/customer/CheckoutMapProcs.groovy   | 103 +++
 .../ofbiz/order/order/OrderServicesScript.groovy   | 826 ++++++++++++++++-
 .../order/template/entry/cart/ShowCart.ftl         |   2 +-
 applications/order/testdef/data/OrderTestData.xml  |   6 +
 .../order/webapp/ordermgr/WEB-INF/controller.xml   |   4 +-
 .../ofbiz/product/shipment/ShipmentServices.groovy |   9 +-
 9 files changed, 971 insertions(+), 1138 deletions(-)

diff --git a/applications/order/minilang/customer/CheckoutMapProcs.xml 
b/applications/order/minilang/customer/CheckoutMapProcs.xml
index 50d4c35b9d..8f74f5dad9 100644
--- a/applications/order/minilang/customer/CheckoutMapProcs.xml
+++ b/applications/order/minilang/customer/CheckoutMapProcs.xml
@@ -48,96 +48,6 @@ under the License.
         </process>
     </simple-map-processor>
 
-    <simple-map-processor name="shipToAddress">
-        <process field="shipToContactMechId">
-            <copy to-field="contactMechId" set-if-null="false"/>
-        </process>
-        <process field="shipToName">
-            <copy to-field="toName" set-if-null="false"/>
-        </process>
-        <process field="shipToAttnName">
-            <copy to-field="attnName" set-if-null="false"/>
-        </process>
-        <process field="shipToAddress1">
-            <copy to-field="address1"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyAddressLine1MissingError"/>
-            </not-empty>
-        </process>
-        <process field="shipToAddress2">
-            <copy to-field="address2"/>
-        </process>
-        <process field="shipToCity">
-            <copy to-field="city"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyCityMissing"/>
-            </not-empty>
-        </process>
-        <process field="shipToStateProvinceGeoId">
-            <copy to-field="stateProvinceGeoId"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyStateMissingError"/>
-            </not-empty>
-        </process>
-        <process field="shipToPostalCode">
-            <copy to-field="postalCode"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyPostalInformationNotFound"/>
-            </not-empty>
-        </process>
-        <process field="shipToCountryGeoId">
-            <copy to-field="countryGeoId"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyCountryMissing"/>
-            </not-empty>
-        </process>
-    </simple-map-processor>
-
-    <simple-map-processor name="billToAddress">
-        <process field="billToContactMechId">
-            <copy to-field="contactMechId" set-if-null="false"/>
-        </process>
-        <process field="billToName">
-            <copy to-field="toName" set-if-null="false"/>
-        </process>
-        <process field="billToAttnName">
-            <copy to-field="attnName" set-if-null="false"/>
-        </process>
-        <process field="billToAddress1">
-            <copy to-field="address1"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyAddressLine1MissingError"/>
-            </not-empty>
-        </process>
-        <process field="billToAddress2">
-            <copy to-field="address2"/>
-        </process>
-        <process field="billToCity">
-            <copy to-field="city"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyCityMissing"/>
-            </not-empty>
-        </process>
-        <process field="billToStateProvinceGeoId">
-            <copy to-field="stateProvinceGeoId"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyStateMissingError"/>
-            </not-empty>
-        </process>
-        <process field="billToPostalCode">
-            <copy to-field="postalCode"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyPostalInformationNotFound"/>
-            </not-empty>
-        </process>
-        <process field="billToCountryGeoId">
-            <copy to-field="countryGeoId"/>
-            <not-empty>
-                <fail-property resource="PartyUiLabels" 
property="PartyCountryMissing"/>
-            </not-empty>
-        </process>
-    </simple-map-processor>
-
     <simple-map-processor name="shipToPhone">
         <process field="shipToCountryCode">
             <copy to-field="countryCode"/>
diff --git a/applications/order/minilang/order/OrderServices.xml 
b/applications/order/minilang/order/OrderServices.xml
deleted file mode 100644
index 1147b39bce..0000000000
--- a/applications/order/minilang/order/OrderServices.xml
+++ /dev/null
@@ -1,978 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-<simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-        xmlns="http://ofbiz.apache.org/Simple-Method"; 
xsi:schemaLocation="http://ofbiz.apache.org/Simple-Method 
http://ofbiz.apache.org/dtds/simple-methods.xsd";>
-
-    <simple-method method-name="orderSequence_enforced" 
short-description="Enforced Sequence (no gaps, per organization)">
-        <log level="info" message="In getNextOrderId sequence enum Enforced"/> 
-        <set field="partyAcctgPreference" 
from-field="parameters.partyAcctgPreference"/>
-        <!-- this is sequential sequencing, we can't skip a number, also it 
must be a unique sequence per partyIdFrom -->
-
-        <if-not-empty field="partyAcctgPreference.lastOrderNumber">
-            <calculate field="partyAcctgPreference.lastOrderNumber" 
type="Long">
-                <calcop operator="add" 
field="partyAcctgPreference.lastOrderNumber"/>
-                <number value="1"/>
-            </calculate>
-            <else>
-                <calculate field="partyAcctgPreference.lastOrderNumber" 
type="Long"><number value="1"/></calculate>
-            </else>
-        </if-not-empty>
-
-        <store-value value-field="partyAcctgPreference"/>
-        <set from-field="partyAcctgPreference.lastOrderNumber" 
field="orderId"/>
-        <field-to-result field="orderId" result-name="orderId"/>
-    </simple-method> 
-
-    <simple-method method-name="createOrderHeader" short-description="Create 
OrderHeader">
-        <now-timestamp field="nowTimestamp"/>
-
-        <set value="Create OrderHeader" field="operationName"/>
-        <check-permission permission="ORDERMGR" action="_CREATE">
-            <fail-property resource="OrderErrorUiLabels" 
property="OrderSecurityErrorToRunCreateOrderShipment"/>
-        </check-permission>
-        <check-errors/>
-
-        <make-value entity-name="OrderHeader" value-field="newEntity"/>
-        
-        <if-not-empty field="parameters.orderId">
-            <set field="newEntity.orderId" from-field="parameters.orderId"/>
-        <else>
-            <sequenced-id sequence-name="OrderHeader" 
field="newEntity.orderId"/>
-        </else>
-        </if-not-empty>
-        <field-to-result field="newEntity.orderId" result-name="orderId"/>
-        
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-
-        <if-empty field="newEntity.statusId">
-            <set field="newEntity.statusId" value="ORDER_CREATED"/>
-        </if-empty>
-        <if-empty field="newEntity.orderDate">
-            <set field="newEntity.orderDate" from-field="nowTimestamp"/>
-        </if-empty>
-        <if-empty field="newEntity.entryDate">
-            <set field="newEntity.entryDate" from-field="nowTimestamp"/>
-        </if-empty>
-        
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    <simple-method method-name="updateOrderHeader" short-description="Update 
OrderHeader">
-        <set value="Update OrderHeader" field="operationName"/>
-        <check-permission permission="ORDERMGR" action="_UPDATE">
-            <fail-property resource="OrderErrorUiLabels" 
property="OrderSecurityErrorToRunCreateOrderShipment"/>
-        </check-permission>
-        <check-errors/>
-
-        <entity-one entity-name="OrderHeader" value-field="orderHeader"/>
-        <if-empty field="orderHeader">
-            <add-error>
-                <fail-property resource="OrderErrorUiLabels" 
property="OrderOrderIdDoesNotExists"/>
-            </add-error>
-        </if-empty>
-        <check-errors/>
-        <set-nonpk-fields map="parameters" value-field="orderHeader"/>
-        <store-value value-field="orderHeader"/>
-    </simple-method>
-
-    <simple-method method-name="recreateOrderAdjustments" 
short-description="Auto create OrderAdjustments">
-        <entity-one entity-name="OrderHeader" value-field="order" 
auto-field-map="true"/>
-        <!-- all existing promo order items are cancelled -->
-        <get-related value-field="order" relation-name="OrderItem" 
list="orderItems"/>
-        <iterate list="orderItems" entry="orderItem">
-            <if>
-                <condition>
-                    <and>
-                        <if-compare field="orderItem.isPromo" value="Y" 
operator="equals"/>
-                        <if-compare field="orderItem.statusId" 
value="ITEM_CANCELLED" operator="not-equals"/>
-                    </and>
-                </condition>
-                <then>
-                    <clear-field field="cancelOrderItemInMap"/>
-                    <set-service-fields 
service-name="cancelOrderItemNoActions" map="parameters" 
to-map="cancelOrderItemInMap"/>
-                    <set from-field="orderItem.orderItemSeqId" 
field="cancelOrderItemInMap.orderItemSeqId"/>
-                    <call-service service-name="cancelOrderItemNoActions" 
in-map-name="cancelOrderItemInMap"/>
-                </then>
-            </if>
-        </iterate>
-
-        <get-related value-field="order" relation-name="OrderAdjustment" 
list="orderAdjustments"/>
-
-        <!-- Accumulate the total existing promotional adjustment -->
-        <set field="existingOrderAdjustmentTotal" value="0" type="BigDecimal"/>
-        <iterate list="orderAdjustments" entry="orderAdjustment">
-            <if>
-                <condition>
-                    <and>
-                        <not><if-empty 
field="orderAdjustment.orderAdjustmentTypeId"/></not>
-                        <if-compare operator="equals" 
value="PROMOTION_ADJUSTMENT" 
field="orderAdjustment.orderAdjustmentTypeId"></if-compare>
-                    </and>
-                </condition>
-                <then>
-                    <calculate field="existingOrderAdjustmentTotal" 
decimal-scale="3">
-                        <calcop operator="add">
-                            <calcop operator="get" 
field="orderAdjustment.amount"/>
-                            <calcop operator="get" 
field="existingOrderAdjustmentTotal"/>
-                        </calcop>
-                    </calculate>
-                </then>
-            </if>
-        </iterate>
-
-        <!-- Recalculate the promotions for the order -->
-        <set-service-fields service-name="loadCartFromOrder" map="parameters" 
to-map="loadCartFromOrderInMap"/>
-        <set value="true" field="loadCartFromOrderInMap.skipInventoryChecks" 
type="Boolean"/>
-        <set value="true" field="loadCartFromOrderInMap.skipProductChecks" 
type="Boolean"/>
-        <call-service service-name="loadCartFromOrder" 
in-map-name="loadCartFromOrderInMap">
-            <result-to-field result-name="shoppingCart" field="cart"/>
-        </call-service>
-        <call-object-method obj-field="cart" method-name="items" 
ret-field="items"/>
-        <iterate list="items" entry="item">
-            <call-object-method obj-field="item" 
method-name="getOrderItemSeqId" ret-field="orderItemSeqId"/>
-            <if-empty field="orderItemSeqId">
-                <!-- this is a new (promo) item -->
-                <!-- a new order item is created -->
-                <make-value entity-name="OrderItem" 
value-field="newOrderItem"/>
-                <set field="newOrderItem.orderId" 
from-field="parameters.orderId"/>
-                <call-object-method obj-field="item" method-name="getItemType" 
ret-field="newOrderItem.orderItemTypeId"/>
-                <call-object-method obj-field="item" 
method-name="getSelectedAmount" ret-field="newOrderItem.selectedAmount"/>
-                <call-object-method obj-field="item" 
method-name="getBasePrice" ret-field="newOrderItem.unitPrice"/>
-                <call-object-method obj-field="item" 
method-name="getListPrice" ret-field="newOrderItem.unitListPrice"/>
-                <call-object-method obj-field="item" method-name="getName" 
ret-field="newOrderItem.itemDescription"/>
-                <call-object-method obj-field="item" method-name="getStatusId" 
ret-field="newOrderItem.statusId"/>
-                <call-object-method obj-field="item" 
method-name="getProductId" ret-field="newOrderItem.productId"/>
-                <call-object-method obj-field="item" method-name="getQuantity" 
ret-field="newOrderItem.quantity"/>
-                <set field="newOrderItem.isModifiedPrice" value="N"/>
-                <set field="newOrderItem.isPromo" value="Y"/>
-                <if-empty field="newOrderItem.statusId">
-                    <set field="newOrderItem.statusId" value="ITEM_CREATED"/>
-                </if-empty>
-                <make-next-seq-id value-field="newOrderItem" 
seq-field-name="orderItemSeqId"/>
-                <create-value value-field="newOrderItem"/>
-                <!-- and the orderItemSeqId is assigned to the shopping cart 
item-->
-                <call-object-method obj-field="item" 
method-name="setOrderItemSeqId">
-                    <field field="newOrderItem.orderItemSeqId" type="String"/>
-                </call-object-method>
-            </if-empty>
-        </iterate>
-        <call-object-method obj-field="cart" method-name="makeAllAdjustments" 
ret-field="adjustments"/>
-
-        <!-- Accumulate the new promotion total from the recalculated 
promotion adjustments -->
-        <set field="newOrderAdjustmentTotal" value="0" type="BigDecimal"/>
-        <iterate list="adjustments" entry="adjustment">
-            <if>
-                <condition>
-                    <and>
-                        <not><if-empty 
field="adjustment.productPromoId"/></not>
-                        <if-empty field="adjustment.orderAdjustmentId"/>
-                    </and>
-                </condition>
-                <then>
-                    <calculate field="newOrderAdjustmentTotal" 
decimal-scale="3">
-                        <calcop operator="add">
-                            <calcop operator="get" field="adjustment.amount"/>
-                            <calcop operator="get" 
field="newOrderAdjustmentTotal"/>
-                        </calcop>
-                    </calculate>
-                </then>
-            </if>
-        </iterate>
-
-        <!-- Determine the difference between existing and new promotion 
adjustment totals, if any -->
-        <calculate field="orderAdjustmentTotalDifference" decimal-scale="3" 
type="BigDecimal">
-            <calcop operator="subtract" field="newOrderAdjustmentTotal">
-                <calcop operator="get" field="existingOrderAdjustmentTotal"/>
-            </calcop>
-        </calculate>
-
-        <!-- If the total has changed, create an OrderAdjustment to reflect 
the fact -->
-        <if-compare field="orderAdjustmentTotalDifference" value="0" 
operator="not-equals" type="BigDecimal">
-            <set field="createOrderAdjContext.orderAdjustmentTypeId" 
value="PROMOTION_ADJUSTMENT"/>
-            <set field="createOrderAdjContext.orderId" 
from-field="parameters.orderId"/>
-            <set field="createOrderAdjContext.orderItemSeqId" value="_NA_"/>
-            <set field="createOrderAdjContext.shipGroupSeqId" value="_NA_"/>
-            <set field="createOrderAdjContext.description" value="Adjustment 
due to order change"/>
-            <set field="createOrderAdjContext.amount" 
from-field="orderAdjustmentTotalDifference" type="BigDecimal"/>
-            <call-service service-name="createOrderAdjustment" 
in-map-name="createOrderAdjContext" include-user-login="true"/>
-            <check-errors/>
-        </if-compare>
-    </simple-method>
-
-    <!--UpdateOrderContactMech-->
-
-     <simple-method method-name="updateOrderContactMech" 
short-description="Update OrderContactMech">
-        <check-permission permission="ORDERMGR" action="_UPDATE">
-           <fail-property resource="OrderErrorUiLabels" 
property="OrderSecurityErrorToRunUpdateOrderContactMech"/>
-        </check-permission>
-        <check-errors/>
-        <make-value entity-name="OrderContactMech" 
value-field="orderContactMechMap"/>
-        <set-pk-fields map="parameters" value-field="orderContactMechMap"/>
-        <set from-field="parameters.orderId" field="inputMap.orderId"/>
-        <set from-field="parameters.contactMechPurposeTypeId" 
field="inputMap.contactMechPurposeTypeId"/>
-        <set from-field="parameters.contactMechId" 
field="inputMap.contactMechId"/>
-        <if-compare field="parameters.contactMechPurposeTypeId" 
operator="equals" value="SHIPPING_LOCATION">
-           <if-compare field="parameters.contactMechId" operator="not-equals" 
value="parameters.oldContactMechId">
-           <set field="orderItemShipGroupMap.orderId" 
from-field="parameters.orderId"/>
-           <set field="orderItemShipGroupMap.contactMechId" 
from-field="parameters.oldContactMechId"/>
-           <find-by-and entity-name="OrderItemShipGroup" list="shipGroupList" 
map="orderItemShipGroupMap"/>
-           <if-not-empty field="shipGroupList">
-              <iterate list="shipGroupList" entry="shipGroup">
-                 <set field="inputMap.shipGroupSeqId" 
from-field="shipGroup.shipGroupSeqId"/>
-                 <set field="inputMap.shipmentMethod" 
value="${shipGroup.shipmentMethodTypeId}@${shipGroup.carrierPartyId}@${shipGroup.carrierRoleTypeId}"/>
-                 <set field="inputMap.oldContactMechId" 
from-field="parameters.oldContactMechId"/>
-                 <set-service-fields service-name="updateOrderItemShipGroup" 
map="inputMap" to-map="orderItemShipGroupMap"/>
-                 <call-service service-name="updateOrderItemShipGroup" 
in-map-name="orderItemShipGroupMap" include-user-login="true"/>
-              </iterate>
-           </if-not-empty>
-           </if-compare>
-        <else>
-        <find-by-and entity-name="OrderContactMech" map="inputMap" 
list="orderContactMechList"/>
-        <!-- If orderContactMechList value is null then create new entry in 
OrderContactMech entity-->
-        <if-empty field="orderContactMechList">
-            <set-service-fields service-name="createOrderContactMech" 
map="parameters" to-map="createOrderContactMechMap"/>
-            <call-service service-name="createOrderContactMech" 
in-map-name="createOrderContactMechMap" include-user-login="true"/>
-            <set from-field="parameters.orderId" 
field="orderContactMechLookupMap.orderId"/>
-            <set from-field="parameters.oldContactMechId" 
field="orderContactMechLookupMap.contactMechId"/>
-            <set from-field="parameters.contactMechPurposeTypeId" 
field="orderContactMechLookupMap.contactMechPurposeTypeId"/>
-            <if-not-empty field="parameters.oldContactMechId">
-                <set-service-fields service-name="removeOrderContactMech" 
map="orderContactMechLookupMap" to-map="removeOrderContactMechMap"/>
-                <call-service service-name="removeOrderContactMech" 
in-map-name="removeOrderContactMechMap" include-user-login="true"/>
-            </if-not-empty>
-        </if-empty>
-        <store-value value-field="orderContactMechMap"/>
-        </else>
-        </if-compare>
-     </simple-method>
-
-    <!-- OrderItemShipGroup -->
-    <simple-method method-name="updateOrderItemShipGroup" 
short-description="Update OrderItemShipGroup">
-        <check-permission permission="ORDERMGR" action="_UPDATE">
-            <fail-property resource="OrderErrorUiLabels" 
property="OrderSecurityErrorToRunUpdateOrderItemShipGroup"/>
-        </check-permission>
-        <check-errors/>
-        <make-value entity-name="OrderItemShipGroup" 
value-field="lookupPKMap"/>
-        <set-pk-fields map="parameters" value-field="lookupPKMap"/>
-        <find-by-primary-key entity-name="OrderItemShipGroup" 
map="lookupPKMap" value-field="lookedUpValue"/>
-        <!-- splitting shipmentMethod request parameter value that contains 
"@" symbol
-             into "shipmentMethodTypeId", "carrierPartyId" and 
"carrierRoleTypeId".
-        -->
-        <script>groovy:
-            shipmentMethod = parameters.get("shipmentMethod")
-            if (shipmentMethod != null) {
-               arr = shipmentMethod.split( "@" )
-               parameters.put("shipmentMethodTypeId", arr[0])
-               parameters.put("carrierPartyId", arr[1])
-               parameters.put("carrierRoleTypeId", arr[2])
-            }
-        </script>
-        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
-
-        <set from-field="parameters.orderId" field="inputMap.orderId"/>
-        <set from-field="parameters.contactMechPurposeTypeId" 
field="inputMap.contactMechPurposeTypeId"/>
-        <set from-field="parameters.contactMechId" 
field="inputMap.contactMechId"/>
-        <find-by-and entity-name="OrderContactMech" map="inputMap" 
list="orderContactMechList"/>
-        <!-- If orderContactMechList value is null then create new entry in 
OrderContactMech entity-->
-        <if-empty field="orderContactMechList">
-            <set-service-fields service-name="createOrderContactMech" 
map="parameters" to-map="createOrderContactMechMap"/>
-            <call-service service-name="createOrderContactMech" 
in-map-name="createOrderContactMechMap" include-user-login="true"/>
-        </if-empty>
-        <store-value value-field="lookedUpValue"/>
-        <!-- Remove the old values from OrderContactMech entity with the help 
of oldContactMechId -->
-        <set from-field="parameters.orderId" 
field="shipGroupLookupMap.orderId"/>
-        <set from-field="parameters.oldContactMechId" 
field="shipGroupLookupMap.contactMechId"/>
-        <find-by-and entity-name="OrderItemShipGroup" map="shipGroupLookupMap" 
list="orderItemShipGroupList"/>
-        <if-empty field="orderItemShipGroupList">
-            <set from-field="parameters.orderId" field="inputMap.orderId"/>
-            <set from-field="parameters.contactMechPurposeTypeId" 
field="inputMap.contactMechPurposeTypeId"/>
-            <set from-field="parameters.oldContactMechId" 
field="inputMap.contactMechId"/>
-            <find-by-and entity-name="OrderContactMech" map="inputMap" 
list="orderContactMechList"/>
-            <set-service-fields service-name="createOrderContactMech" 
map="inputMap" to-map="removeOrderContactMechMap"/>
-            <call-service service-name="removeOrderContactMech" 
in-map-name="removeOrderContactMechMap" include-user-login="true"/>
-        </if-empty>
-
-        <!-- Update promisedDateTime & currentPromisedDate in 
OrderItemShipGrpInvRes entity-->
-        <set field="itemShipGrpInvResLookupMap.orderId" 
from="parameters.orderId"/>
-        <set field="itemShipGrpInvResLookupMap.shipGroupSeqId" 
from="parameters.shipGroupSeqId"/>
-        <find-by-and entity-name="OrderItemShipGrpInvRes" 
map="itemShipGrpInvResLookupMap" list="itemShipGrpInvResList"/>
-        <if-not-empty field="itemShipGrpInvResList">
-            <iterate list="itemShipGrpInvResList" 
entry="orderItemShipGrpInvRes">
-                <set field="orderItemShipGrpInvRes.promisedDatetime" 
from="parameters.shipByDate"/>
-                <set field="orderItemShipGrpInvRes.currentPromisedDate" 
from="parameters.shipByDate"/>
-                <store-value value-field="orderItemShipGrpInvRes"/>
-            </iterate>
-        </if-not-empty>
-    </simple-method>
-
-    <simple-method method-name="getOrderItemShipGroupEstimatedShipDate" 
short-description="Compute and return the OrderItemShipGroup estimated ship 
date based on the associated items.">
-        <entity-one entity-name="OrderItemShipGroup" 
value-field="orderItemShipGroup"/>
-        <if-compare field="orderItemShipGroup.maySplit" operator="equals" 
value="Y">
-            <set field="orderByList[]" value="+promisedDatetime"/>
-        <else>
-            <set field="orderByList[]" value="-promisedDatetime"/>
-        </else>
-        </if-compare>
-        <get-related value-field="orderItemShipGroup" 
relation-name="OrderItemShipGrpInvRes" list="orderItemShipGroupInvResList" 
order-by-list="orderByList"/>
-        <first-from-list list="orderItemShipGroupInvResList" 
entry="orderItemShipGroupInvRes"/>
-        <field-to-result field="orderItemShipGroupInvRes.promisedDatetime" 
result-name="estimatedShipDate"/>
-    </simple-method>
-
-    <simple-method method-name="updateOrderNote" short-description="Update 
OrderNote">
-        <check-permission permission="ORDERMGR" action="_UPDATE">
-            <fail-property resource="OrderErrorUiLabels" 
property="OrderSecurityErrorToRunUpdateOrderNote"/>
-        </check-permission>
-        <check-errors/>
-        <entity-one entity-name="OrderHeaderNote" 
value-field="orderHeaderNote"/>
-        <set-nonpk-fields map="parameters" value-field="orderHeaderNote"/>
-        <store-value value-field="orderHeaderNote"/>
-    </simple-method>
-
-    <simple-method method-name="addPaymentMethodToOrder" 
short-description="Create an PaymentMethodToOrder">
-        <check-permission permission="ORDERMGR" action="_CREATE">
-            <fail-property resource="OrderErrorUiLabels" 
property="OrderSecurityErrorToRunAddPaymentMethodToOrder"/>
-        </check-permission>
-        <check-errors/>
-        <set field="inputMap.paymentMethodId" 
from-field="parameters.paymentMethodId"/>
-        <set field="inputMap.maxAmount" from-field="parameters.maxAmount"/>
-        <set field="inputMap.orderId" from-field="parameters.orderId"/>
-        <entity-one entity-name="PaymentMethod" value-field="paymentMethod">
-            <field-map field-name="paymentMethodId" 
from-field="parameters.paymentMethodId"/>
-        </entity-one>
-        <set field="inputMap.paymentMethodTypeId" 
from-field="paymentMethod.paymentMethodTypeId"/>
-        <!--In this method we calls createOrderPaymentPreference and returns 
orderPaymentPreferenceId field to authOrderPaymentPreference -->
-        <call-service service-name="createOrderPaymentPreference" 
in-map-name="inputMap" include-user-login="true">
-           <result-to-field result-name="orderPaymentPreferenceId" 
field="parameters.orderPaymentPreferenceId"/>
-        </call-service>
-        <field-to-result field="parameters.orderPaymentPreferenceId" 
result-name="orderPaymentPreferenceId"/>
-    </simple-method>
-
-    <simple-method method-name="getOrderStatus" short-description="Gets an 
order status" login-required="false">
-        <entity-one entity-name="OrderHeader" value-field="order"/>
-        <if-empty field="order">
-            <add-error>
-                <fail-property resource="OrderErrorUiLabels" 
property="OrderOrderIdDoesNotExists"/>
-            </add-error>
-            <check-errors/>
-        </if-empty>
-        <field-to-result field="order.statusId" result-name="statusId"/>
-    </simple-method>
-
-    <simple-method method-name="checkOrderIsOnBackOrder" 
short-description="Check if an Order is on Back Order" login-required="false">
-        <set field="zeroEnv" value="0" type="BigDecimal"/>
-        <entity-condition entity-name="OrderItemShipGrpInvRes" 
list="orderItemShipGrpInvResList">
-            <condition-list combine="and">
-                <condition-expr field-name="orderId" 
from-field="parameters.orderId"/>
-                <condition-expr field-name="quantityNotAvailable" 
operator="not-equals" from-field="nullField"/>
-                <condition-expr field-name="quantityNotAvailable" 
operator="greater" from-field="zeroEnv"/>
-            </condition-list>
-        </entity-condition>
-        <if-empty field="orderItemShipGrpInvResList">
-            <set field="isBackOrder" value="false" type="Boolean"/>
-            <else>
-                <set field="isBackOrder" value="true" type="Boolean"/>
-            </else>
-        </if-empty>
-        <field-to-result field="isBackOrder" result-name="isBackOrder"/>
-    </simple-method>
-
-    <simple-method method-name="createOrderItemChange" 
short-description="Creates a new Order Item Change record">
-        <make-value entity-name="OrderItemChange" value-field="newEntity"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <if-empty field="parameters.changeDatetime">
-            <now-timestamp field="nowTimestamp"/>
-            <set field="newEntity.changeDatetime" from-field="nowTimestamp"/>
-        </if-empty>
-        <if-empty field="parameters.changeUserLogin">
-            <set field="newEntity.changeUserLogin" 
from-field="userLogin.userLoginId"/>
-        </if-empty>
-        <sequenced-id sequence-name="OrderItemChange" 
field="newEntity.orderItemChangeId"/>
-        <create-value value-field="newEntity"/>
-        <field-to-result field="newEntity.orderItemChangeId" 
result-name="orderItemChangeId"/>
-    </simple-method>
-
-    <simple-method method-name="createUpdateShippingAddress" 
short-description="create and update Shipping address" login-required="false">
-        <set field="keepAddressBook" from-field="parameters.keepAddressBook" 
default-value="Y"/>
-        <call-map-processor 
xml-resource="component://order/minilang/customer/CheckoutMapProcs.xml"
-            processor-name="shipToAddress" in-map-name="parameters" 
out-map-name="shipToAddressCtx"/>
-        <check-errors/>
-        <set field="partyId" from-field="parameters.partyId"/>
-        <set field="shipToAddressCtx.partyId" from-field="partyId"/>
-
-        <if-empty field="shipToAddressCtx.contactMechId">
-            <set field="shipToAddressCtx.contactMechPurposeTypeId" 
value="SHIPPING_LOCATION"/>
-            <call-service service-name="createPartyPostalAddress" 
in-map-name="shipToAddressCtx">
-                <result-to-field result-name="contactMechId" 
field="parameters.shipToContactMechId"/>
-            </call-service>
-            <log level="info" message="Shipping address created with 
contactMechId ${parameters.shipToContactMechId}"/>
-        <else>
-            <if-compare field="keepAddressBook" operator="equals" value="Y">
-                <make-value entity-name="PostalAddress" 
value-field="newValue"/>
-                <set-pk-fields value-field="newValue" map="shipToAddressCtx"/>
-                <find-by-primary-key entity-name="PostalAddress" 
map="newValue" value-field="oldValue"/>
-                <set-nonpk-fields map="shipToAddressCtx" 
value-field="newValue"/>
-                <if-compare-field field="oldValue" to-field="newValue" 
operator="not-equals" type="Object">
-                    <set field="shipToAddressCtx.contactMechId" 
from-field="nullField"/>
-                    <call-service service-name="createPartyPostalAddress" 
in-map-name="shipToAddressCtx">
-                        <result-to-field result-name="contactMechId" 
field="parameters.shipToContactMechId"/>
-                    </call-service>
-                </if-compare-field>
-                <entity-and entity-name="PartyContactMechPurpose" 
list="pcmpShipList" filter-by-date="true">
-                    <field-map field-name="partyId" from-field="partyId"/>
-                    <field-map field-name="contactMechId" 
from-field="parameters.shipToContactMechId"/>
-                    <field-map field-name="contactMechPurposeTypeId" 
value="SHIPPING_LOCATION"/>
-                </entity-and>
-                <!-- If purpose is not exists then create -->
-                <if-empty field="pcmpShipList">
-                    <set-service-fields 
service-name="createPartyContactMechPurpose" map="parameters" 
to-map="serviceContext"/>
-                    <set field="serviceContext.partyId" from-field="partyId"/>
-
-                    <entity-and entity-name="PartyContactMechPurpose" 
list="pcmpList" filter-by-date="true">
-                        <field-map field-name="partyId" from-field="partyId"/>
-                        <field-map field-name="contactMechPurposeTypeId" 
value="SHIPPING_LOCATION"/>
-                    </entity-and>
-                    <iterate list="pcmpList" entry="pcmp">
-                        <set-service-fields 
service-name="expirePartyContactMechPurpose" map="pcmp" to-map="serviceInMap"/>
-                        <call-service 
service-name="expirePartyContactMechPurpose" in-map-name="serviceInMap"/>
-                        <clear-field field="serviceInMap"/>
-                    </iterate>
-                    <set field="serviceContext.partyId" from-field="partyId"/>
-                    <set field="serviceContext.contactMechId" 
from-field="parameters.shipToContactMechId"/>
-                    <set field="serviceContext.contactMechPurposeTypeId" 
value="SHIPPING_LOCATION"/>
-                    <call-service service-name="createPartyContactMechPurpose" 
in-map-name="serviceContext"/>
-                    <clear-field field="pcmpList"/>
-                    <clear-field field="serviceContext"/>
-                </if-empty>
-                <if-compare field="parameters.setDefaultShipping" 
operator="equals" value="Y">
-                    <set-service-fields service-name="setPartyProfileDefaults" 
map="parameters" to-map="partyProfileDefaultsCtx"/>
-                    <set field="partyProfileDefaultsCtx.defaultShipAddr" 
from-field="parameters.shipToContactMechId"/>
-                    <set field="partyProfileDefaultsCtx.partyId" 
from-field="partyId"/>
-                    <call-service service-name="setPartyProfileDefaults" 
in-map-name="partyProfileDefaultsCtx"/>
-                </if-compare>
-            </if-compare>
-            <if-compare field="keepAddressBook" operator="equals" value="N">
-                <set field="shipToAddressCtx.shipToContactMechId" 
from-field="shipToAddressCtx.contactMechId"></set>
-                <if-compare-field field="shipToAddressCtx.shipToContactMechId" 
operator="equals" to-field="parameters.billToContactMechId">
-                    <make-value entity-name="PostalAddress" 
value-field="newValue"/>
-                    <set-pk-fields value-field="newValue" 
map="shipToAddressCtx"/>
-                    <find-by-primary-key entity-name="PostalAddress" 
map="newValue" value-field="oldValue"/>
-                    <set-nonpk-fields map="shipToAddressCtx" 
value-field="newValue"/>
-                    <if-compare-field field="oldValue" to-field="newValue" 
operator="not-equals" type="Object">
-                        <entity-and entity-name="PartyContactMechPurpose" 
list="pcmpList" filter-by-date="true">
-                            <field-map field-name="contactMechId" 
from-field="shipToAddressCtx.shipToContactMechId"/>
-                            <field-map field-name="partyId" 
from-field="partyId"/>
-                            <field-map field-name="contactMechPurposeTypeId" 
value="SHIPPING_LOCATION"/>
-                        </entity-and>
-                        <iterate list="pcmpList" entry="pcmp">
-                            <set-service-fields 
service-name="expirePartyContactMechPurpose" map="pcmp" to-map="serviceInMap"/>
-                            <call-service 
service-name="expirePartyContactMechPurpose" in-map-name="serviceInMap"/>
-                        </iterate>
-                        <set field="shipToAddressCtx.contactMechPurposeTypeId" 
value="SHIPPING_LOCATION"/>
-                        <set field="shipToAddressCtx.contactMechId" 
from-field="nullField"/>
-                        <call-service service-name="createPartyPostalAddress" 
in-map-name="shipToAddressCtx">
-                            <result-to-field result-name="contactMechId" 
field="parameters.shipToContactMechId"/>
-                        </call-service>
-                        <log level="info" message="Shipping address updated 
with contactMechId ${shipToAddressCtx.shipToContactMechId}"/>
-                    </if-compare-field>
-                <else>
-                    <set field="shipToAddressCtx.userLogin" 
from-field="parameters.userLogin"/>
-                    <call-service service-name="updatePartyPostalAddress" 
in-map-name="shipToAddressCtx">
-                        <result-to-field result-name="contactMechId" 
field="parameters.shipToContactMechId"/>
-                    </call-service>
-                    <log level="info" message="Shipping address updated with 
contactMechId ${shipToAddressCtx.shipToContactMechId}"/>
-                </else>
-                </if-compare-field>
-            </if-compare>
-        </else>
-        </if-empty>
-        <field-to-result field="parameters.shipToContactMechId" 
result-name="contactMechId"/>
-    </simple-method>
-
-    <simple-method method-name="createUpdateBillingAddress" 
short-description="create and update billing address">
-
-        <set field="keepAddressBook" from-field="parameters.keepAddressBook" 
default-value="Y"/>
-        <if-compare field="parameters.useShippingAddressForBilling" 
operator="not-equals" value="Y">
-            <call-map-processor 
xml-resource="component://order/minilang/customer/CheckoutMapProcs.xml"
-                processor-name="billToAddress" in-map-name="parameters" 
out-map-name="billToAddressCtx"/>
-        </if-compare>
-        <check-errors/>
-        <set field="partyId" from-field="parameters.partyId"/>
-        <set field="billToAddressCtx.partyId" from-field="partyId"/>
-
-        <if-compare field="parameters.useShippingAddressForBilling" 
operator="equals" value="Y">
-            <if-empty field="parameters.billToContactMechId">
-                <set field="billToAddressCtx.contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                <set-service-fields 
service-name="createPartyContactMechPurpose" map="billToAddressCtx" 
to-map="serviceInMap"/>
-                <set field="serviceInMap.contactMechId" 
from-field="parameters.shipToContactMechId"/>
-                <call-service service-name="createPartyContactMechPurpose" 
in-map-name="serviceInMap"/>
-            <else>
-                <if-compare-field field="parameters.shipToContactMechId" 
operator="not-equals" to-field="parameters.billToContactMechId">
-                    <entity-and entity-name="PartyContactMechPurpose" 
list="pcmpList" filter-by-date="true">
-                        <field-map field-name="contactMechId" 
from-field="parameters.billToContactMechId"/>
-                        <field-map field-name="partyId" from-field="partyId"/>
-                        <field-map field-name="contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                    </entity-and>
-                    <iterate list="pcmpList" entry="pcmp">
-                        <set-service-fields 
service-name="expirePartyContactMechPurpose" map="pcmp" to-map="serviceInMap"/>
-                        <call-service 
service-name="expirePartyContactMechPurpose" in-map-name="serviceInMap"/>
-                        <clear-field field="serviceInMap"/>
-                    </iterate>
-                    <if-compare field="keepAddressBook" operator="equals" 
value="N">
-                        <set field="serviceInMap.contactMechId" 
from-field="parameters.billToContactMechId"/>
-                        <call-service service-name="deletePartyContactMech" 
in-map-name="serviceInMap"/>
-                        <clear-field field="serviceInMap"/>
-                    </if-compare>
-                    <!-- Check that the ship-to address doesn't already have a 
bill-to purpose -->
-                    <entity-and entity-name="PartyContactMechPurpose" 
list="pcmpList" filter-by-date="true">
-                        <field-map field-name="contactMechId" 
from-field="parameters.shipToContactMechId"/>
-                        <field-map field-name="partyId" from-field="partyId"/>
-                        <field-map field-name="contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                    </entity-and>
-                    <if-empty field="pcmpList">
-                        <set field="billToAddressCtx.contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                        <set-service-fields 
service-name="createPartyContactMechPurpose" map="billToAddressCtx" 
to-map="serviceInMap"/>
-                        <set field="serviceInMap.contactMechId" 
from-field="parameters.shipToContactMechId"/>
-                        <call-service 
service-name="createPartyContactMechPurpose" in-map-name="serviceInMap"/>
-                    </if-empty>
-                    <log level="info" message="Billing address updated with 
contactMechId ${parameters.billToContactMechId}"/>
-                </if-compare-field>
-            </else>
-            </if-empty>
-            <set field="parameters.billToContactMechId" 
from-field="parameters.shipToContactMechId"/>
-        </if-compare>
-        <if-compare field="parameters.useShippingAddressForBilling" 
operator="not-equals" value="Y">
-            <if-empty field="parameters.billToContactMechId">
-                <set field="billToAddressCtx.contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                <call-service service-name="createPartyPostalAddress" 
in-map-name="billToAddressCtx">
-                    <result-to-field result-name="contactMechId" 
field="parameters.billToContactMechId"/>
-                </call-service>
-                <log level="info" message="Billing address created with 
contactmechId ${parameters.billToContactMechId}"/>
-            <else>
-                <if-compare-field field="parameters.shipToContactMechId" 
operator="equals" to-field="parameters.billToContactMechId">
-                    <set field="billToAddressCtx.contactMechId" 
from-field="nullField"/>
-                    <call-service service-name="createPartyPostalAddress" 
in-map-name="billToAddressCtx">
-                        <result-to-field result-name="contactMechId" 
field="parameters.billToContactMechId"/>
-                    </call-service>
-                    <set-service-fields 
service-name="createPartyContactMechPurpose" map="parameters" 
to-map="serviceContext"/>
-                    <set field="serviceContext.partyId" from-field="partyId"/>
-
-                    <entity-and entity-name="PartyContactMechPurpose" 
list="pcmpList" filter-by-date="true">
-                        <field-map field-name="partyId" 
from-field="billToAddressCtx.partyId"/>
-                        <field-map field-name="contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                    </entity-and>
-                    <iterate list="pcmpList" entry="pcmp">
-                        <set-service-fields 
service-name="expirePartyContactMechPurpose" map="pcmp" to-map="serviceInMap"/>
-                        <call-service 
service-name="expirePartyContactMechPurpose" in-map-name="serviceInMap"/>
-                        <clear-field field="serviceInMap"/>
-                    </iterate>
-                    <set field="serviceContext.partyId" from-field="partyId"/>
-                    <set field="serviceContext.contactMechId" 
from-field="parameters.billToContactMechId"/>
-                    <set field="serviceContext.contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                    <call-service service-name="createPartyContactMechPurpose" 
in-map-name="serviceContext"/>
-                    <clear-field field="pcmpList"/>
-                    <clear-field field="serviceContext"/>
-                    <log level="info" message="Billing address updated with 
contactMechId ${parameters.billToContactMechId}"/>
-                <else>
-                    <if-compare field="keepAddressBook" operator="equals" 
value="N">
-                        <call-service service-name="updatePartyPostalAddress" 
in-map-name="billToAddressCtx">
-                            <result-to-field result-name="contactMechId" 
field="parameters.billToContactMechId"/>
-                        </call-service>
-                    </if-compare>
-                    <if-compare field="keepAddressBook" operator="equals" 
value="Y">
-                        <make-value entity-name="PostalAddress" 
value-field="newValue"/>
-                        <set-pk-fields value-field="newValue" 
map="billToAddressCtx"/>
-                        <set-nonpk-fields map="billToAddressCtx" 
value-field="newValue"/>
-                        <entity-one entity-name="PostalAddress" 
value-field="oldValue" auto-field-map="false">
-                            <field-map field-name="contactMechId" 
from-field="billToAddressCtx.contactMechId"/>
-                        </entity-one>
-                        <if-compare-field field="oldValue" to-field="newValue" 
operator="not-equals" type="Object">
-                            <set field="billToAddressCtx.contactMechId" 
from-field="nullField"/>
-                            <call-service 
service-name="createPartyPostalAddress" in-map-name="billToAddressCtx">
-                                <result-to-field result-name="contactMechId" 
field="parameters.billToContactMechId"/>
-                            </call-service>
-                        </if-compare-field>
-                    </if-compare>
-                    <log level="info" message="Billing Postal Address created 
billToContactMechId is ${parameters.billToContactMechId}"/>
-                </else>
-                </if-compare-field>
-
-                <entity-and entity-name="PartyContactMechPurpose" 
list="pcmpBillList" filter-by-date="true">
-                    <field-map field-name="partyId" from-field="partyId"/>
-                    <field-map field-name="contactMechId" 
from-field="parameters.billToContactMechId"/>
-                    <field-map field-name="contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                </entity-and>
-                <!-- If purpose is not exists then create -->
-                <if-empty field="pcmpBillList">
-                    <set-service-fields 
service-name="createPartyContactMechPurpose" map="parameters" 
to-map="serviceContext"/>
-                    <set field="serviceContext.partyId" from-field="partyId"/>
-
-                    <entity-and entity-name="PartyContactMechPurpose" 
list="pcmpList" filter-by-date="true">
-                        <field-map field-name="partyId" from-field="partyId"/>
-                        <field-map field-name="contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                    </entity-and>
-                    <iterate list="pcmpList" entry="pcmp">
-                        <set-service-fields 
service-name="expirePartyContactMechPurpose" map="pcmp" to-map="serviceInMap"/>
-                        <call-service 
service-name="expirePartyContactMechPurpose" in-map-name="serviceInMap"/>
-                        <clear-field field="serviceInMap"/>
-                    </iterate>
-                    <set field="serviceContext.partyId" from-field="partyId"/>
-                    <set field="serviceContext.contactMechId" 
from-field="parameters.billToContactMechId"/>
-                    <set field="serviceContext.contactMechPurposeTypeId" 
value="BILLING_LOCATION"/>
-                    <call-service service-name="createPartyContactMechPurpose" 
in-map-name="serviceContext"/>
-                    <clear-field field="pcmpList"/>
-                    <clear-field field="serviceContext"/>
-                </if-empty>
-                <if-compare field="parameters.setDefaultBilling" 
operator="equals" value="Y">
-                    <set-service-fields service-name="setPartyProfileDefaults" 
map="parameters" to-map="partyProfileDefaultsCtx"/>
-                    <set field="partyProfileDefaultsCtx.defaultBillAddr" 
from-field="parameters.billToContactMechId"/>
-                    <set field="partyProfileDefaultsCtx.partyId" 
from-field="partyId"/>
-                    <call-service service-name="setPartyProfileDefaults" 
in-map-name="partyProfileDefaultsCtx"/>
-                </if-compare>
-            </else>
-            </if-empty>
-        </if-compare>
-        <field-to-result field="parameters.billToContactMechId" 
result-name="contactMechId"/>
-    </simple-method>
-    <simple-method method-name="createUpdateCreditCard" 
short-description="create and update credit card">
-        <set-service-fields service-name="createCreditCard" map="parameters" 
to-map="creditCardContext"/>
-        <set field="partyId" from-field="parameters.partyId"/>
-        <set field="creditCardContext.partyId" from-field="partyId"/>
-        <set field="creditCardContext.contactMechId" 
from-field="parameters.contactMechId"/>
-        <if-empty field="parameters.paymentMethodId">
-            <!-- call create Credit Card -->
-            <call-service service-name="createCreditCard" 
in-map-name="creditCardContext">
-                <result-to-field result-name="paymentMethodId" 
field="parameters.paymentMethodId"/>
-            </call-service>
-        <else>
-            <!-- call update Credit Card -->
-            <entity-and entity-name="PaymentMethod" list="paymentMethodList" 
filter-by-date="true">
-                <field-map field-name="partyId" from-field="partyId"/>
-                <field-map field-name="paymentMethodTypeId" 
value="CREDIT_CARD"/>
-                <order-by field-name="-fromDate"/>
-            </entity-and>
-            <first-from-list list="paymentMethodList" entry="paymentMethod"/>
-            <set field="creditCardContext.paymentMethodId" 
from-field="paymentMethod.paymentMethodId"/>
-            <call-service service-name="updateCreditCard" 
in-map-name="creditCardContext">
-                <result-to-field result-name="paymentMethodId" 
field="parameters.paymentMethodId"/>
-            </call-service>
-        </else>
-        </if-empty>
-        <set field="paymentMethodId" from-field="parameters.paymentMethodId"/>
-        <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, but 
only if the order price didn't come from an agreement">
-        <if>
-            <condition>
-                <and>
-                    <not><if-empty field="parameters.facilityId"/></not>
-                    <not><if-empty field="parameters.orderId"/></not>
-                </and>
-            </condition>
-            <then>
-                <entity-and list="orderSuppliers" 
entity-name="OrderHeaderItemAndRoles">
-                    <field-map field-name="orderId" 
from-field="parameters.orderId"/>
-                    <field-map field-name="roleTypeId" 
value="BILL_FROM_VENDOR"/>
-                    <field-map field-name="orderTypeId" 
value="PURCHASE_ORDER"/>
-                </entity-and>
-                <first-from-list list="orderSuppliers" entry="orderSupplier"/>
-                <entity-and list="supplierProducts" 
entity-name="SupplierProduct">
-                    <field-map field-name="productId" 
from-field="parameters.productId"/>
-                    <field-map field-name="partyId" 
from-field="orderSupplier.partyId"/>
-                    <field-map field-name="availableThruDate" 
from-field="nullField"/>
-                </entity-and>
-                <iterate list="supplierProducts" entry="supplierProduct">
-                    <now-timestamp field="nowTimestamp"/>
-                    <if-not-empty field="parameters.orderCurrencyUnitPrice">
-                        <if-compare-field 
field="parameters.orderCurrencyUnitPrice" operator="not-equals" 
to-field="supplierProduct.lastPrice" type="BigDecimal">
-                            <clone-value value-field="supplierProduct" 
new-value-field="newSupplierProduct"/>
-                            <set field="newSupplierProduct.availableFromDate" 
from-field="nowTimestamp"/>
-                            <set field="newSupplierProduct.lastPrice" 
from-field="parameters.orderCurrencyUnitPrice" type="BigDecimal"/>
-                            <create-value value-field="newSupplierProduct"/>
-                            <set field="supplierProduct.availableThruDate" 
from-field="nowTimestamp"/>
-                            <store-value value-field="supplierProduct"/>
-                        </if-compare-field>
-                    <else>
-                        <if-compare-field field="parameters.unitCost" 
operator="not-equals" to-field="supplierProduct.lastPrice" type="BigDecimal">
-                            <clone-value value-field="supplierProduct" 
new-value-field="newSupplierProduct"/>
-                            <set field="newSupplierProduct.availableFromDate" 
from-field="nowTimestamp"/>
-                            <set field="newSupplierProduct.lastPrice" 
from-field="parameters.unitCost" type="BigDecimal"/>
-                            <create-value value-field="newSupplierProduct"/>
-                            <set field="supplierProduct.availableThruDate" 
from-field="nowTimestamp"/>
-                            <store-value value-field="supplierProduct"/>
-                        </if-compare-field>
-                    </else>
-                    </if-not-empty>
-                </iterate>
-            </then>
-            <else>
-                <if>
-                    <condition>
-                        <and>
-                          <if-empty field="parameters.orderItems"/>
-                          <not><if-empty field="parameters.orderId"/></not>
-                        </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>
-                        <iterate list="orderItems" entry="orderItem">
-                            <iterate-map key="orderItemSeqId" 
value="unitPrice" map="parameters.itemPriceMap">
-                                <if>
-                                    <condition>
-                                        <if-compare-field 
field="orderItem.orderItemSeqId" operator="equals" to-field="orderItemSeqId"/>
-                                    </condition>
-                                    <then>
-                                        <iterate-map key="orderItemSeqId" 
value="Y" map="parameters.overridePriceMap">
-                                            <if>
-                                                <condition>
-                                                    <if-compare-field 
field="orderItem.orderItemSeqId"  operator="equals" to-field="orderItemSeqId"/>
-                                                </condition>
-                                                <then>
-                                                    <set 
field="orderItem.unitPrice" from-field="unitPrice" type="BigDecimal"/>
-                                                    <entity-and 
list="supplierProducts" entity-name="SupplierProduct">
-                                                        <field-map 
field-name="productId" from-field="orderItem.productId"/>
-                                                        <field-map 
field-name="partyId" from-field="parameters.supplierPartyId"/>
-                                                        <field-map 
field-name="availableThruDate" from-field="nullField"/>
-                                                    </entity-and>
-                                                    <iterate 
list="supplierProducts" entry="supplierProduct">
-                                                        <now-timestamp 
field="nowTimestamp"/>
-                                                        <if>
-                                                            <condition>
-                                                                
<if-compare-field field="orderItem.unitPrice" 
to-field="supplierProduct.lastPrice" operator="not-equals" type="BigDecimal"/>
-                                                            </condition>
-                                                            <then>
-                                                                <make-value 
entity-name="SupplierProduct" value-field="newSupplierProduct"/>
-                                                                <clone-value 
value-field="supplierProduct" new-value-field="newSupplierProduct"/>
-                                                                <set 
from-field="nowTimestamp" field="newSupplierProduct.availableFromDate"/>
-                                                                <set 
from-field="orderItem.unitPrice" field="newSupplierProduct.lastPrice"/>
-                                                                <create-value 
value-field="newSupplierProduct"/>
-                                                                <set 
from-field="nowTimestamp" field="supplierProduct.availableThruDate"/>
-                                                                <store-value 
value-field="supplierProduct"/>
-                                                            </then>
-                                                        </if>
-                                                    </iterate>
-                                                </then>
-                                            </if>
-                                        </iterate-map>
-                                    </then>
-                                </if>
-                            </iterate-map>
-                        </iterate>
-                    </then>
-                    <else>
-                        <iterate entry="orderItem" 
list="parameters.orderItems">
-                            <entity-and list="supplierProducts" 
entity-name="SupplierProduct">
-                                <field-map field-name="productId" 
from-field="orderItem.productId"/>
-                                <field-map field-name="partyId" 
from-field="parameters.supplierPartyId"/>
-                                <field-map field-name="availableThruDate" 
from-field="nullField"/>
-                            </entity-and>
-                            <iterate entry="supplierProduct" 
list="supplierProducts">
-                                <now-timestamp field="nowTimestamp"/>
-                                <if>
-                                    <condition>
-                                        <if-compare-field 
field="orderItem.unitPrice" to-field="supplierProduct.lastPrice" 
operator="not-equals" type="BigDecimal"/>
-                                    </condition>
-                                    <then>
-                                        <make-value 
entity-name="SupplierProduct" value-field="newSupplierProduct"/>
-                                        <clone-value 
value-field="supplierProduct" new-value-field="newSupplierProduct"/>
-                                        <set from-field="nowTimestamp" 
field="newSupplierProduct.availableFromDate"/>
-                                        <set from-field="orderItem.unitPrice" 
field="newSupplierProduct.lastPrice" type="BigDecimal"/>
-                                        <create-value 
value-field="newSupplierProduct"/>
-                                        <set from-field="nowTimestamp" 
field="supplierProduct.availableThruDate"/>
-                                        <store-value 
value-field="supplierProduct"/>
-                                    </then>
-                                </if>
-                            </iterate>
-                        </iterate>
-                    </else>
-                </if>
-            </else>
-        </if>
-    </simple-method>
-
-    <simple-method method-name="cancelAllBackOrders" 
short-description="Cancels those back orders from suppliers whose cancel back 
order date (cancelBackOrderDate) has passed the current date">
-        <now-timestamp field="nowTimestamp"/>
-        <entity-condition entity-name="OrderHeader" list="orders">
-            <condition-list combine="and">
-                <condition-expr field-name="orderTypeId" operator="equals" 
value="PURCHASE_ORDER"/>
-                <condition-expr field-name="statusId" operator="not-equals" 
value="ORDER_CANCELLED"/>
-                <condition-expr field-name="statusId" operator="not-equals" 
value="ORDER_COMPLETED"/>
-            </condition-list>
-        </entity-condition>
-        <iterate list="orders" entry="currentOrder">
-            <entity-and list="orderItems" entity-name="OrderItem">
-                <field-map field-name="orderId" 
from-field="currentOrder.orderId"/>
-            </entity-and>
-            <iterate list="orderItems" entry="currentOrderItem">
-                <set field="backOrderDate" 
from-field="currentOrderItem.cancelBackOrderDate" type="Timestamp"/>
-                <if>
-                    <condition>
-                        <and>
-                            <not><if-empty field="backOrderDate"/></not>
-                            <if-compare-field field="nowTimestamp" 
to-field="backOrderDate" operator="greater" type="Timestamp"/>
-                        </and>
-                    </condition>
-                    <then>
-                        <set field="orderItemMap.orderId" 
from-field="currentOrder.orderId"/>
-                        <set field="orderItemMap.orderItemSeqId" 
from-field="currentOrderItem.orderItemSeqId"/>
-                        <call-service service-name="cancelOrderItem" 
in-map-name="orderItemMap"/>
-                    </then>
-                </if>
-            </iterate>
-        </iterate>
-    </simple-method>
-
-    <simple-method  method-name="updateShippingMethodAndCharges" 
short-description="Updates shipping method and shipping charges from Order View 
page when Shipment is in picked status and items of Order are packed">
-         <!-- splitting shipmentMethodAndAmount request parameter value that 
contains "*" symbol
-             into "shipmentMethod" and "newAmount".
-        -->
-         <!-- shipmentMethod request parameter value contains "@" symbol
-             between "shipmentMethodTypeId" and "carrierPartyId".This will be 
splitted in updateOrderItemShipGroup method
-        -->
-
-        <script>groovy:
-            shipmentMethodAndAmount = parameters.get("shipmentMethodAndAmount")
-            if (shipmentMethodAndAmount != null) {
-               parameters.put("shipmentMethod", 
shipmentMethodAndAmount.substring(0, shipmentMethodAndAmount.indexOf("*")))
-               parameters.put("amount", 
shipmentMethodAndAmount.substring(shipmentMethodAndAmount.indexOf("*")+1))
-               parameters.put("shipmentMethodTypeId", 
shipmentMethodAndAmount.substring(0, shipmentMethodAndAmount.indexOf("@")))
-            }
-        </script>
-        <set field="newAmount" from-field="parameters.amount" 
type="BigDecimal"/>
-        <set field="shippingAmount" from-field="parameters.shippingAmount" 
type="BigDecimal"/>
-        <property-to-field field="percentAllowed" resource="shipment" 
property="shipment.default.cost_actual_over_estimated_percent_allowed"/>
-        <if-compare-field field="newAmount" operator="greater" 
to-field="shippingAmount" type="BigDecimal">
-            <set field="diffPercentage" value="${(newAmount - 
shippingAmount/shippingAmount)*100}" type="BigDecimal"/>
-        <else>
-            <set field="diffPercentage" value="${(shippingAmount - 
newAmount/newAmount)*100}" type="BigDecimal"/>
-        </else>
-        </if-compare-field>
-        <if-compare-field field="diffPercentage" operator="greater" 
to-field="percentAllowed" type="BigDecimal">
-            <set-service-fields service-name="updateOrderItemShipGroup" 
map="parameters" to-map="updateOrderItemShipGroupContext"/>
-            <call-service service-name="updateOrderItemShipGroup" 
in-map-name="updateOrderItemShipGroupContext"/>
-            <set-service-fields service-name="updateOrderAdjustment" 
map="parameters" to-map="updateOrderAdjustmentContext"/>
-            <call-service service-name="updateOrderAdjustment" 
in-map-name="updateOrderAdjustmentContext"/>
-            <set-service-fields service-name="updateShipmentRouteSegment" 
map="parameters" to-map="updateShipmentRouteSegmentContext"/>
-            <clear-field 
field="updateShipmentRouteSegmentContext.trackingIdNumber"/>
-            <clear-field 
field="updateShipmentRouteSegmentContext.trackingDigest"/>
-            <clear-field 
field="updateShipmentRouteSegmentContext.carrierServiceStatusId"/>
-            <call-service service-name="updateShipmentRouteSegment" 
in-map-name="updateShipmentRouteSegmentContext"/>
-            <set-service-fields service-name="upsShipmentConfirm" 
map="parameters" to-map="upsShipmentConfirmContext"/>
-            <call-service service-name="upsShipmentConfirm" 
in-map-name="upsShipmentConfirmContext"/>
-        <else>
-            <set-service-fields service-name="updateOrderItemShipGroup" 
map="parameters" to-map="updateOrderItemShipGroupContext"/>
-            <call-service service-name="updateOrderItemShipGroup" 
in-map-name="updateOrderItemShipGroupContext"/>
-            <set-service-fields service-name="updateShipmentRouteSegment" 
map="parameters" to-map="updateShipmentRouteSegmentContext"/>
-            <clear-field 
field="updateShipmentRouteSegmentContext.trackingIdNumber"/>
-            <clear-field 
field="updateShipmentRouteSegmentContext.trackingDigest"/>
-            <clear-field 
field="updateShipmentRouteSegmentContext.carrierServiceStatusId"/>
-            <call-service service-name="updateShipmentRouteSegment" 
in-map-name="updateShipmentRouteSegmentContext"/>
-            <set-service-fields service-name="upsShipmentConfirm" 
map="parameters" to-map="upsShipmentConfirmContext"/>
-            <call-service service-name="upsShipmentConfirm" 
in-map-name="upsShipmentConfirmContext"/>
-        </else>
-        </if-compare-field>
-    </simple-method>
-
-    <simple-method method-name="productAvailabalityByFacility" 
short-description="Calculate ATP and Qoh According For each facility">
-        <set field="facilityMap.ownerPartyId" 
from-field="parameters.ownerPartyId"/>
-        <find-by-and map="facilityMap" list="facilityList" 
entity-name="Facility"/>
-        <iterate list="facilityList" entry="facility">
-            <set field="getInventoryAvailableByFacilityMap.facilityId" 
from-field="facility.facilityId"/>
-            <set field="getInventoryAvailableByFacilityMap.productId" 
from-field="parameters.productId"/>
-            <call-service service-name="getInventoryAvailableByFacility" 
in-map-name="getInventoryAvailableByFacilityMap">
-                <result-to-field result-name="quantityOnHandTotal"/>
-                <result-to-field result-name="availableToPromiseTotal"/>
-            </call-service>
-            <set field="availabalityMap.facilityId" 
from-field="facility.facilityId"/>
-            <set field="availabalityMap.quantityOnHandTotal" 
from-field="quantityOnHandTotal"/>
-            <set field="availabalityMap.availableToPromiseTotal" 
from-field="availableToPromiseTotal"/>
-            <field-to-list field="availabalityMap" list="availabalityList"/>
-            <clear-field field="availabalityMap"/>
-        </iterate>
-        <field-to-result field="availabalityList"/>
-    </simple-method>
-
-    <simple-method method-name="createOrderPaymentApplication" 
short-description="Create Order Payment Application">
-        <entity-one entity-name="Payment" value-field="paymentMap"/>
-        <set field="createCtx.amountApplied" from-field="paymentMap.amount" 
type="BigDecimal"/>
-        <set field="createCtx.paymentId" from-field="paymentMap.paymentId"/>
-        <entity-one entity-name="OrderPaymentPreference" 
value-field="orderPaymentPreMap">
-            <field-map field-name="orderPaymentPreferenceId" 
from-field="paymentMap.paymentPreferenceId"/>
-        </entity-one>
-        <entity-and entity-name="OrderItemBilling" list="orderItemBilList">
-            <field-map field-name="orderId" 
from-field="orderPaymentPreMap.orderId"/>
-            <order-by field-name="invoiceId"/>
-        </entity-and>
-        <if-not-empty field="orderItemBilList">
-            <set field="createCtx.invoiceId" 
from-field="orderItemBilList[0].invoiceId"/>
-            <call-service service-name="createPaymentApplication" 
in-map-name="createCtx"/>
-        </if-not-empty>
-    </simple-method>
-
-    <simple-method method-name="moveItemBetweenShipGroups" 
short-description="Move order items between ship groups">
-        <entity-one entity-name="OrderItemShipGroupAssoc" 
value-field="orderItemShipGroupAssoc">
-            <field-map field-name="orderId" from-field="parameters.orderId"/>
-            <field-map field-name="orderItemSeqId" 
from-field="parameters.orderItemSeqId"/>
-            <field-map field-name="shipGroupSeqId" 
from-field="parameters.toGroupIndex"/>
-        </entity-one>
-        <if-empty field="orderItemShipGroupAssoc">
-            <set-service-fields service-name="addOrderItemShipGroupAssoc" 
map="parameters" to-map="map"/>
-            <set field="map.quantity" value="0" type="BigDecimal"/>
-            <set field="map.shipGroupSeqId" from="parameters.toGroupIndex"/>
-            <call-service service-name="addOrderItemShipGroupAssoc" 
in-map-name="map"/>
-            <entity-one entity-name="OrderItemShipGroupAssoc" 
value-field="orderItemShipGroupAssoc">
-                <field-map field-name="orderId" 
from-field="parameters.orderId"/>
-                <field-map field-name="orderItemSeqId" 
from-field="parameters.orderItemSeqId"/>
-                <field-map field-name="shipGroupSeqId" 
from-field="parameters.toGroupIndex"/>
-            </entity-one>
-        </if-empty>
-        <clear-field field="map"/>
-        <set field="map.orderId" from-field="parameters.orderId"/>
-        <set field="map.orderItemSeqId" 
from-field="parameters.orderItemSeqId"/>
-        <set field="map.shipGroupSeqId" from-field="parameters.toGroupIndex"/>
-        <set field="map.quantity" value="${orderItemShipGroupAssoc.quantity + 
parameters.quantity}" type="BigDecimal"/>
-        <call-service service-name="updateOrderItemShipGroupAssoc" 
in-map-name="map"/>
-
-        <entity-one entity-name="OrderItemShipGroupAssoc" 
value-field="orderItemShipGroupAssoc">
-            <field-map field-name="orderId" from-field="parameters.orderId"/>
-            <field-map field-name="orderItemSeqId" 
from-field="parameters.orderItemSeqId"/>
-            <field-map field-name="shipGroupSeqId" 
from-field="parameters.fromGroupIndex"/>
-        </entity-one>
-        <if-empty field="orderItemShipGroupAssoc">
-            <add-error>
-                <fail-property resource="OrderErrorUiLabels" 
property="OrderServiceOrderItemShipGroupAssocNotExist"/>
-            </add-error>
-        </if-empty>
-        <check-errors/>
-
-        <clear-field field="map"/>
-        <set field="map.orderId" from-field="parameters.orderId"/>
-        <set field="map.orderItemSeqId" 
from-field="parameters.orderItemSeqId"/>
-        <set field="map.shipGroupSeqId" 
from-field="parameters.fromGroupIndex"/>
-        <set field="map.quantity" value="${orderItemShipGroupAssoc.quantity - 
parameters.quantity}" type="BigDecimal"/>
-        <call-service service-name="updateOrderItemShipGroupAssoc" 
in-map-name="map"/>
-    </simple-method>
-
-</simple-methods>
diff --git a/applications/order/servicedef/services.xml 
b/applications/order/servicedef/services.xml
index 74b9ed49c2..a9bb6a723a 100644
--- a/applications/order/servicedef/services.xml
+++ b/applications/order/servicedef/services.xml
@@ -483,8 +483,8 @@ under the License.
         <attribute name="shoppingCart" 
type="org.apache.ofbiz.order.shoppingcart.ShoppingCart" mode="OUT" 
optional="false"/>
     </service>
 
-    <service name="recreateOrderAdjustments" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="recreateOrderAdjustments">
+    <service name="recreateOrderAdjustments" engine="groovy" auth="true"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="recreateOrderAdjustments">
         <description>Remove all existing order adjustments, recalc them and 
persist in OrderAdjustment.</description>
         <permission-service service-name="orderAdjustmentPermissionCheck" 
main-action="UPDATE"/>
         <attribute name="orderId" type="String" mode="IN" optional="false">
@@ -560,8 +560,8 @@ under the License.
         </attribute>
     </service>
 
-    <service name="getOrderItemShipGroupEstimatedShipDate" engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="getOrderItemShipGroupEstimatedShipDate" auth="true">
+    <service name="getOrderItemShipGroupEstimatedShipDate" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="getOrderItemShipGroupEstimatedShipDate" auth="true">
         <description>Compute and return the OrderItemShipGroup estimated ship 
date based on the associated items.</description>
         <attribute name="orderId" type="String" mode="IN" optional="false">
             <type-validate>
@@ -608,9 +608,11 @@ under the License.
         <attribute name="noteName" type="String" mode="IN" optional="true"/>
     </service>
 
-    <service name="updateOrderNote" engine="simple" 
default-entity-name="OrderHeaderNote"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="updateOrderNote" auth="true">
-        <description>Toggle Order Note and make it either Public or 
Private</description>
+  <service name="updateOrderNote" default-entity-name="OrderHeaderNote" 
engine="entity-auto" invoke="update" auth="true">
+        <description>Update OrderHeader</description>
+        <required-permissions join-type="AND">
+            <check-permission permission="ORDERMGR" action="_UPDATE"/>
+        </required-permissions>
         <attribute name="orderId" type="String" mode="IN" optional="false">
             <type-validate>
                 <fail-property resource="OrderErrorUiLabels" 
property="OrderRequiredFieldMissingOrderId"/>
@@ -698,8 +700,8 @@ under the License.
         </attribute>
         <attribute name="shippingAmount" type="BigDecimal" mode="OUT" 
optional="false"/>
     </service>
-    <service name="getOrderStatus" engine="simple" 
location="component://order/minilang/order/OrderServices.xml"
-            invoke="getOrderStatus" auth="false">
+    <service name="getOrderStatus" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="getOrderStatus" auth="false">
         <description>Gets the order status</description>
         <attribute name="orderId" type="String" mode="IN" optional="false">
             <type-validate>
@@ -867,23 +869,25 @@ under the License.
         </attribute>
     </service>
 
-    <service name="orderSequence_enforced" engine="simple"
-        location="component://order/minilang/order/OrderServices.xml" 
invoke="orderSequence_enforced">
+    <service name="orderSequence_enforced" engine="groovy"
+        
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="orderSequence_enforced">
         <implements service="getNextOrderId"/>
         <attribute name="partyAcctgPreference" 
type="org.apache.ofbiz.entity.GenericValue" mode="IN"/>
         <override name="orderId" type="Long" mode="OUT"/>
     </service>
 
     <!-- OrderHeader -->
-    <service name="createOrderHeader" default-entity-name="OrderHeader" 
engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="createOrderHeader" auth="true">
+    <service name="createOrderHeader" default-entity-name="OrderHeader" 
engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="createOrderHeader" auth="true">
         <description>Create OrderHeader</description>
         <auto-attributes include="pk" mode="INOUT" optional="true"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="updateOrderHeader" default-entity-name="OrderHeader" 
engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="updateOrderHeader" auth="true">
+    <service name="updateOrderHeader" default-entity-name="OrderHeader" 
engine="entity-auto" invoke="update" auth="true">
         <description>Update OrderHeader</description>
+        <required-permissions join-type="AND">
+            <check-permission permission="ORDERMGR" action="_UPDATE"/>
+        </required-permissions>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
@@ -924,8 +928,9 @@ under the License.
         </attribute>
         <attribute name="shipGroupSeqId" type="String" mode="INOUT" 
optional="true"/>
     </service>
-    <service name="updateOrderItemShipGroup" 
default-entity-name="OrderItemShipGroup" engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="updateOrderItemShipGroup" auth="true">
+
+    <service name="updateOrderItemShipGroup" 
default-entity-name="OrderItemShipGroup" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="updateOrderItemShipGroup" auth="true">
         <description>Updates OrderItemShipGroup.  The shipmentMethod field is 
of the format ${shipmentMethodTypeId}@${carrierPartyId}</description>
         <auto-attributes mode="IN" include="pk" optional="false"/>
         <auto-attributes mode="IN" include="nonpk" optional="true"/>
@@ -942,8 +947,8 @@ under the License.
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
 
-    <service name="updateOrderContactMech" 
default-entity-name="OrderContactMech" engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="updateOrderContactMech" auth="true">
+    <service name="updateOrderContactMech" 
default-entity-name="OrderContactMech" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="updateOrderContactMech" auth="true">
         <description>Update Order Contact Mech</description>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <attribute name="oldContactMechId" type="String" mode="IN" 
optional="true"/>
@@ -993,8 +998,8 @@ under the License.
         </attribute>
     </service>
 
-    <service name="addPaymentMethodToOrder" engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="addPaymentMethodToOrder" auth="true">
+    <service name="addPaymentMethodToOrder" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="addPaymentMethodToOrder" auth="true">
         <description>Add Payment Method to Order.From this servicewe will call 
the createOrderPaymentPreference service to create 
OrderPaymentPreference</description>
         <attribute type="String" mode="IN" name="orderId" optional="false">
             <type-validate>
@@ -1152,8 +1157,8 @@ under the License.
         <attribute name="orderListSize" type="Integer" mode="OUT" 
optional="false"/>
     </service>
 
-    <service name="checkOrderIsOnBackOrder" engine="simple" auth="false"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="checkOrderIsOnBackOrder">
+    <service name="checkOrderIsOnBackOrder" engine="groovy" auth="false"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="checkOrderIsOnBackOrder">
         <description>Check if an Order is on Back Order</description>
         <attribute name="orderId" type="String" mode="IN" optional="false">
             <type-validate>
@@ -1201,8 +1206,8 @@ under the License.
         <attribute name="changeReason" type="String" mode="IN" 
optional="true"/>
     </service>
 
-    <service name="createOrderItemChange" engine="simple" auth="true" 
default-entity-name="OrderItemChange"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="createOrderItemChange">
+    <service name="createOrderItemChange" engine="groovy" auth="true" 
default-entity-name="OrderItemChange"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="createOrderItemChange">
         <description>Creates a new OrderItemChange record</description>
         <auto-attributes mode="OUT" include="pk" optional="false"/>
         <auto-attributes mode="IN" include="nonpk" optional="true"/>
@@ -1216,8 +1221,8 @@ under the License.
             This is done by looking for all subscriptions which are active and 
where the automaticExtend flag is set to "Y"</description>
     </service>
 
-    <service name="createUpdateShippingAddress" engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="createUpdateShippingAddress" auth="true">
+    <service name="createUpdateShippingAddress" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="createUpdateShippingAddress" auth="true">
         <description>Creates new shipping address and update existing 
address</description>
         <attribute name="productStoreId" mode="IN" type="String" 
optional="true"/>
         <attribute name="setDefaultShipping" mode="IN" type="String" 
optional="true"/>
@@ -1257,8 +1262,8 @@ under the License.
         <attribute name="billToContactMechId" mode="IN" type="String" 
optional="true"/>
     </service>
 
-    <service name="createUpdateBillingAddress" engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="createUpdateBillingAddress" auth="true">
+    <service name="createUpdateBillingAddress" engine="groovy" auth="true"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="createUpdateBillingAddress">
         <description>Creates new billing address and update existing 
address</description>
         <attribute name="productStoreId" mode="IN" type="String" 
optional="true"/>
         <attribute name="setDefaultBilling" mode="IN" type="String" 
optional="true"/>
@@ -1279,8 +1284,8 @@ under the License.
         <attribute name="contactMechId" mode="OUT" type="String" 
optional="false"/>
     </service>
 
-    <service name="createUpdateCreditCard" engine="simple" auth="true" 
default-entity-name="CreditCard"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="createUpdateCreditCard">
+    <service name="createUpdateCreditCard" engine="groovy" auth="true" 
default-entity-name="CreditCard"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="createUpdateCreditCard">
         <description>Create/Update credit card</description>
         <attribute name="expMonth" type="String" mode="IN" optional="false">
             <type-validate>
@@ -1322,8 +1327,8 @@ under the License.
         <attribute name="paymentMethodId" type="String" mode="OUT" 
optional="false"/>
     </service>
 
-   <service name="setUnitPriceAsLastPrice" engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="setUnitPriceAsLastPrice" auth="false">
+    <service name="setUnitPriceAsLastPrice" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="setUnitPriceAsLastPrice" auth="false">
         <description>Sets unit price as last price for product</description>
         <attribute name="supplierPartyId" type="String" mode="IN" 
optional="true"/>
         <attribute name="orderTypeId" type="String" mode="IN" optional="true"/>
@@ -1337,13 +1342,13 @@ under the License.
         <attribute name="orderCurrencyUnitPrice" type="String" mode="IN" 
optional="true"/>
    </service>
 
-    <service name="cancelAllBackOrders" engine="simple"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="cancelAllBackOrders" auth="true">
+    <service name="cancelAllBackOrders" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="cancelAllBackOrders" auth="true">
         <description>Cancels those back orders from suppliers whose cancel 
back order date (cancelBackOrderDate) has passed the current date</description>
     </service>
 
-    <service name="updateShippingMethodAndCharges" engine="simple" 
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="updateShippingMethodAndCharges">
+    <service name="updateShippingMethodAndCharges" engine="groovy" auth="true"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="updateShippingMethodAndCharges">
         <description>Compare order's shipping amount and new shipping 
amount(based on weight and dimension of packages).If new shipping amount is 
more then or less than default percentage (defined in shipment.properties) of 
Order's shipping amount, then shipping method and shipping charges are updated. 
And if new shipping amount is not more then or less than default percentage 
(defined in shipment.properties)% of Order's shipping amount then only shipping 
method is updated.Also updates r [...]
         <attribute name="orderId" type="String" mode="IN" optional="false">
             <type-validate>
@@ -1447,8 +1452,8 @@ under the License.
             </type-validate>
         </attribute>
     </service>
-    <service name="productAvailabalityByFacility" engine="simple" 
location="component://order/minilang/order/OrderServices.xml"
-            invoke="productAvailabalityByFacility" auth="true">
+    <service name="productAvailabilityByFacility" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="productAvailabilityByFacility" auth="true">
         <description>
             Calculate ATP and QOH According For each facility
         </description>
@@ -1498,8 +1503,8 @@ under the License.
     </service>
 
     <!-- Use for link the payment and the invoice When Received Payment -->
-    <service name="createOrderPaymentApplication" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderServices.xml" 
invoke="createOrderPaymentApplication">
+    <service name="createOrderPaymentApplication" engine="groovy" auth="true"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="createOrderPaymentApplication">
         <description>Create Order Payment Application</description>
         <attribute name="paymentId" type="String" mode="IN" optional="false"/>
     </service>
@@ -1552,8 +1557,8 @@ under the License.
         </attribute>
     </service>
     
-    <service name="moveItemBetweenShipGroups" engine="simple"
-        location="component://order/minilang/order/OrderServices.xml" 
invoke="moveItemBetweenShipGroups">
+    <service name="moveItemBetweenShipGroups" engine="groovy"
+            
location="component://order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy"
 invoke="moveItemBetweenShipGroups">
         <description>Move order items between ship groups</description>
         <attribute name="orderId" type="String" mode="IN"/>
         <attribute name="orderItemSeqId" type="String" mode="IN"/>
diff --git 
a/applications/order/src/main/groovy/org/apache/ofbiz/order/customer/CheckoutMapProcs.groovy
 
b/applications/order/src/main/groovy/org/apache/ofbiz/order/customer/CheckoutMapProcs.groovy
new file mode 100644
index 0000000000..849726ae77
--- /dev/null
+++ 
b/applications/order/src/main/groovy/org/apache/ofbiz/order/customer/CheckoutMapProcs.groovy
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.ofbiz.order.customer
+
+static Map shipToAddress(Map parameters) {
+    Map processedMap = [:]
+    if (parameters.shipToContactMechId) {
+        processedMap.contactMechId = parameters.shipToContactMechId
+    }
+    if (parameters.shipToName) {
+        processedMap.toName = parameters.shipToName
+    }
+    if (parameters.shipToAttnName) {
+        processedMap.attnName = parameters.shipToAttnName
+    }
+    if (parameters.shipToAddress1) {
+        processedMap.address1 = parameters.shipToAddress1
+    } else {
+        return error(label('PartyUiLabels', 'PartyAddressLine1MissingError'))
+    }
+    if (parameters.shipToAddress2) {
+        processedMap.address2 = parameters.shipToAddress2
+    }
+    if (parameters.shipToCity) {
+        processedMap.city = parameters.shipToCity
+    } else {
+        return error(label('PartyUiLabels', 'PartyCityMissing'))
+    }
+    if (parameters.shipToStateProvinceGeoId) {
+        processedMap.stateProvinceGeoId = parameters.shipToStateProvinceGeoId
+    } else {
+        return error(label('PartyUiLabels', 'PartyStateMissingError'))
+    }
+    if (parameters.shipToPostalCode) {
+        processedMap.postalCode = parameters.shipToPostalCode
+    } else {
+        return error(label('PartyUiLabels', 'PartyPostalInformationNotFound'))
+    }
+    if (parameters.shipToCountryGeoId) {
+        processedMap.countryGeoId = parameters.shipToCountryGeoId
+    } else {
+        return error(label('PartyUiLabels', 'PartyCountryMissing'))
+    }
+    return processedMap
+}
+
+static Map billToAddress(Map parameters) {
+    Map processedMap = [:]
+    if (parameters.billToContactMechId) {
+        processedMap.contactMechId = parameters.billToContactMechId
+    }
+    if (parameters.billToName) {
+        processedMap.toName = parameters.billToName
+    }
+    if (parameters.billToAttnName) {
+        processedMap.attnName = parameters.billToAttnName
+    }
+    if (parameters.billToAddress1) {
+        processedMap.address1 = parameters.billToAddress1
+    } else {
+        return error(label('PartyUiLabels', 'PartyAddressLine1MissingError'))
+    }
+    if (parameters.billToAddress2) {
+        processedMap.address2 = parameters.billToAddress2
+    }
+    if (parameters.billToCity) {
+        processedMap.city = parameters.billToCity
+    } else {
+        return error(label('PartyUiLabels', 'PartyCityMissing'))
+    }
+    if (parameters.billToStateProvinceGeoId) {
+        processedMap.stateProvinceGeoId = parameters.billToStateProvinceGeoId
+    } else {
+        return error(label('PartyUiLabels', 'PartyStateMissingError'))
+    }
+    if (parameters.billToPostalCode) {
+        processedMap.postalCode = parameters.billToPostalCode
+    } else {
+        return error(label('PartyUiLabels', 'PartyPostalInformationNotFound'))
+    }
+    if (parameters.billToCountryGeoId) {
+        processedMap.countryGeoId = parameters.billToCountryGeoId
+    } else {
+        return error(label('PartyUiLabels', 'PartyCountryMissing'))
+    }
+    return processedMap
+}
\ No newline at end of file
diff --git 
a/applications/order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy
 
b/applications/order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy
index 41764950d6..c2fd7b665d 100644
--- 
a/applications/order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy
+++ 
b/applications/order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy
@@ -18,13 +18,41 @@
 */
 package org.apache.ofbiz.order.order
 
+import org.apache.ofbiz.base.util.GeneralException
+import org.apache.ofbiz.base.util.ObjectType
 import org.apache.ofbiz.base.util.UtilDateTime
+import org.apache.ofbiz.base.util.UtilProperties
 import org.apache.ofbiz.entity.GenericValue
 import org.apache.ofbiz.entity.condition.EntityCondition
 import org.apache.ofbiz.entity.condition.EntityConditionBuilder
+import org.apache.ofbiz.entity.condition.EntityOperator
+import org.apache.ofbiz.order.customer.CheckoutMapProcs
+import org.apache.ofbiz.order.shoppingcart.ShoppingCart
+import org.apache.ofbiz.order.shoppingcart.ShoppingCartItem
 
 import java.sql.Timestamp
 
+/**
+ * Service to create OrderHeader
+ */
+Map createOrderHeader() {
+    Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
+    if (!(security.hasEntityPermission('ORDERMGR', '_CREATE', 
parameters.userLogin))) {
+        return error(label('OrderErrorUiLabels', 
'OrderSecurityErrorToRunCreateOrderShipment'))
+    }
+
+    GenericValue orderHeader = makeValue('OrderHeader',
+            [orderId: parameters.orderId ?: 
delegator.getNextSeqId('OrderHeader')])
+    orderHeader.with {
+        setNonPKFields(parameters)
+        statusId = orderHeader.statusId ?: 'ORDER_CREATED'
+        orderDate = orderHeader.orderDate ?: nowTimestamp
+        entryDate = orderHeader.entryDate ?: nowTimestamp
+        create()
+    }
+    return success([orderId: orderHeader.orderId])
+}
+
 /**
  * Service to get the next OrderId
  */
@@ -49,8 +77,8 @@ Map getNextOrderId() {
     String orderIdTemp
     if (customMethodName) {
         parameters.partyAcctgPreference = partyAcctgPreference
-        Map result = run service: customMethodName, with: parameters
-        orderIdTemp = result.orderId
+        Map serviceResult = run service: customMethodName, with: parameters
+        orderIdTemp = serviceResult.orderId
     } else {
         logInfo 'In getNextOrderId sequence by Standard'
         // default to the default sequencing: ODRSQ_STANDARD
@@ -63,14 +91,7 @@ Map getNextOrderId() {
     }
 
     // use orderIdTemp along with the orderIdPrefix to create the real ID
-    String orderId = ''
-    if (productStore) {
-        orderId += productStore.orderNumberPrefix ?: ''
-    }
-    if (partyAcctgPreference) {
-        orderId += partyAcctgPreference.orderIdPrefix ?: ''
-    }
-    orderId += orderIdTemp.toString()
+    String orderId = "${productStore?.orderNumberPrefix ?: 
''}${partyAcctgPreference?.orderIdPrefix ?: ''}${orderIdTemp as String}"
 
     return success([orderId: orderId])
 }
@@ -89,17 +110,18 @@ Map getOrderedSummaryInformation() {
     */
     Timestamp fromDate = null, thruDate = null
     Timestamp now = UtilDateTime.nowTimestamp()
+    Integer monthsToInclude = parameters.monthsToInclude
     if (monthsToInclude) {
         thruDate = now
         fromDate = UtilDateTime.adjustTimestamp(now, Calendar.MONTH, 
-monthsToInclude)
     }
 
-    roleTypeId = roleTypeId ?: 'PLACING_CUSTOMER'
-    orderTypeId = orderTypeId ?: 'SALES_ORDER'
-    statusId = statusId ?: 'ORDER_COMPLETED'
+    String roleTypeId = parameters.roleTypeId ?: 'PLACING_CUSTOMER'
+    String orderTypeId = parameters.orderTypeId ?: 'SALES_ORDER'
+    String statusId = parameters.statusId ?: 'ORDER_COMPLETED'
 
     //find the existing exchange rates
-    exprBldr = new EntityConditionBuilder()
+    EntityConditionBuilder exprBldr = new EntityConditionBuilder()
 
     EntityCondition condition = exprBldr.AND {
         EQUALS(partyId: partyId)
@@ -128,14 +150,778 @@ Map getOrderedSummaryInformation() {
         }
     }
 
-    orderInfo = select('partyId', 'roleTypeId', 'totalGrandAmount', 
'totalSubRemainingAmount', 'totalOrders')
+    GenericValue orderInfo = select('partyId', 'roleTypeId', 
'totalGrandAmount', 'totalSubRemainingAmount', 'totalOrders')
             .from('OrderHeaderAndRoleSummary').where(condition).queryFirst()
 
     // first set the required OUT fields to zero
-    result = success()
-    result.totalGrandAmount = orderInfo ? orderInfo.totalGrandAmount : 
BigDecimal.ZERO
-    result.totalSubRemainingAmount = orderInfo ? 
orderInfo.totalSubRemainingAmount : BigDecimal.ZERO
-    result.totalOrders = orderInfo ? orderInfo.totalOrders : 0L
+    return success([
+            totalGrandAmount: orderInfo ? orderInfo.totalGrandAmount : 
BigDecimal.ZERO,
+            totalSubRemainingAmount: orderInfo ? 
orderInfo.totalSubRemainingAmount : BigDecimal.ZERO,
+            totalOrders: orderInfo ? orderInfo.totalOrders : 0L])
+}
+
+/**
+ * Service to get enforced Sequence (no gaps, per organization)
+ */
+Map orderSequence_enforced() {
+    logInfo 'In getNextOrderId sequence enum Enforced'
+    GenericValue partyAcctgPreference = parameters.partyAcctgPreference
+    // this is sequential sequencing, we can't skip a number, also it must be 
a unique sequence per partyIdFrom
+
+    partyAcctgPreference.lastOrderNumber = partyAcctgPreference.lastOrderNumber
+            ? partyAcctgPreference.lastOrderNumber + 1
+            : 1
+
+    partyAcctgPreference.store()
+    return success([orderId: partyAcctgPreference.lastOrderNumber])
+}
+
+/**
+ * Service to automatically create OrderAdjustments
+ */
+Map recreateOrderAdjustments() {
+    GenericValue order = from('OrderHeader').where(context).queryOne()
+
+    // All existing promo order items are cancelled
+    List<GenericValue> orderItems = order.getRelated('OrderItem', null, null, 
false)
+    for (GenericValue orderItem : orderItems) {
+        if (orderItem.isPromo == 'Y' && orderItem.statusId != 
'ITEM_CANCELLED') {
+            run service: 'cancelOrderItemNoActions', with: [*: parameters,
+                                                            orderItemSeqId: 
orderItem.orderItemSeqId]
+        }
+    }
+
+    List<GenericValue> orderAdjustments = order.getRelated('OrderAdjustment', 
null, null, false)
+    // Accumulate the total existing promotional adjustment
+    BigDecimal existingOrderAdjustmentTotal = BigDecimal.ZERO
+    for (GenericValue orderAdjustment : orderAdjustments) {
+        if (orderAdjustment.orderAdjustmentTypeId == 'PROMOTION_ADJUSTMENT' ) {
+            existingOrderAdjustmentTotal = 
existingOrderAdjustmentTotal.add(orderAdjustment.getBigDecimal('amount').setScale(3))
+        }
+    }
+
+    // Recalculate the promotions for the order
+    Map<String, Object> serviceCtx = [*: parameters,
+        skipInventoryChecks: true,
+        skipProductChecks: true]
+    Map<String, Object> loadCartFromOrderInMap = 
dispatcher.runSync('loadCartFromOrder', serviceCtx)
+    ShoppingCart cart = loadCartFromOrderInMap.shoppingCart
+    List<ShoppingCartItem> items = cart.items()
+    for (ShoppingCartItem item : items) {
+        String orderItemSeqId = item.getOrderItemSeqId()
+        if (!orderItemSeqId) {
+            // this is a new (promo) item
+            // a new order item is created
+            GenericValue newOrderItem = makeValue('OrderItem')
+            newOrderItem.with {
+                orderId = parameters.orderId
+                orderItemTypeId = item.getItemType()
+                selectedAmount = item.getSelectedAmount()
+                unitPrice = item.getBasePrice()
+                unitListPrice = item.getListPrice()
+                itemDescription = item.getName(dispatcher)
+                statusId = item.getStatusId()
+                productId = item.getProductId()
+                quantity = item.getQuantity()
+                isModifiedPrice = 'N'
+                isPromo = 'Y'
+                statusId = newOrderItem.statusId ?: 'ITEM_CREATED'
+            }
+            newOrderItem.orderItemSeqId = delegator.getNextSeqId('OrderItem')
+            newOrderItem.create()
+            // And the orderItemSeqId is assigned to the shopping cart item
+            item.setOrderItemSeqId(newOrderItem.orderItemSeqId)
+        }
+    }
+    List<GenericValue> adjustments = cart.makeAllAdjustments()
+
+    // Accumulate the new promotion total from the recalculated promotion 
adjustments
+    BigDecimal newOrderAdjustmentTotal = BigDecimal.ZERO
+    for (GenericValue adjustment : adjustments) {
+        if (adjustment.productPromoId && !adjustment.orderAdjustmentId) {
+            newOrderAdjustmentTotal = 
newOrderAdjustmentTotal.add(adjustment.getBigDecimal('amount').setScale(3))
+        }
+    }
 
-    return result
+    // Determine the difference between existing and new promotion adjustment 
totals, if any
+    BigDecimal orderAdjustmentTotalDifference = 
newOrderAdjustmentTotal.subtract(existingOrderAdjustmentTotal)
+
+    // If the total has changed, create an OrderAdjustment to reflect the fact
+    if (orderAdjustmentTotalDifference != 0) {
+        run service: 'createOrderAdjustment',
+            with: [orderAdjustmentTypeId: 'PROMOTION_ADJUSTMENT',
+                   orderId: parameters.orderId,
+                   orderItemSeqId: '_NA_',
+                   shipGroupSeqId: '_NA_',
+                   description: 'Adjustment due to order change',
+                   amount: orderAdjustmentTotalDifference
+            ]
+    }
+    return success()
+}
+
+/*
+ * Update OrderContactMech
+ */
+Map updateOrderContactMech() {
+    if (!(security.hasEntityPermission('ORDERMGR', '_UPDATE', 
parameters.userLogin))) {
+        return error(label('OrderErrorUiLabels', 
'OrderSecurityErrorToRunUpdateOrderContactMech'))
+    }
+
+    if (parameters.contactMechPurposeTypeId == 'SHIPPING_LOCATION' &&
+            parameters.contactMechId != parameters.oldContactMechId) {
+        Map orderItemShipGroupMap = [orderId: parameters.orderId]
+        if (parameters.oldContactMechId) {
+            orderItemShipGroupMap.contactMechId = parameters.oldContactMechId
+        }
+        List<GenericValue> shipGroupList = from('OrderItemShipGroup')
+            .where(orderItemShipGroupMap)
+            .queryList()
+        if (shipGroupList) {
+            for (GenericValue shipGroup: shipGroupList) {
+                run service: 'updateOrderItemShipGroup', with: [
+                    orderId: parameters.orderId,
+                    contactMechId: parameters.contactMechId,
+                    contactMechPurposeTypeId: 
parameters.contactMechPurposeTypeId,
+                    shipGroupSeqId: shipGroup.shipGroupSeqId,
+                    shipmentMethod: 
"${shipGroup.shipmentMethodTypeId}@${shipGroup.carrierPartyId}@${shipGroup.carrierRoleTypeId}",
+                    oldContactMechId: parameters.oldContactMechId]
+            }
+        }
+    } else {
+        List<GenericValue> orderContactMechList = from('OrderContactMech')
+            .where(orderId: parameters.orderId,
+                   contactMechPurposeTypeId: 
parameters.contactMechPurposeTypeId,
+                   contactMechId: parameters.contactMechId)
+            .queryList()
+        // If orderContactMechList value is null then create new entry in 
OrderContactMech entity
+        if (!orderContactMechList) {
+            run service: 'createOrderContactMech', with: parameters
+            if (parameters.oldContactMechId) {
+                run service: 'removeOrderContactMech', with: [
+                    orderId: parameters.orderId,
+                    contactMechId: parameters.oldContactMechId,
+                    contactMechPurposeTypeId: 
parameters.contactMechPurposeTypeId]
+            }
+        }
+    }
+    return success()
+}
+
+/*
+ * Update OrderItemShipGroup
+ */
+Map updateOrderItemShipGroup() {
+    if (!(security.hasEntityPermission('ORDERMGR', '_UPDATE', 
parameters.userLogin))) {
+        return error(label('OrderErrorUiLabels', 
'OrderSecurityErrorToRunUpdateOrderItemShipGroup'))
+    }
+    GenericValue lookedUpValue =  from('OrderItemShipGroup')
+            .where(parameters)
+            .queryOne()
+
+    // splitting shipmentMethod request parameter value that contains '@' 
symbol into
+    // 'shipmentMethodTypeId', 'carrierPartyId' and 'carrierRoleTypeId'.
+    String shipmentMethod = parameters.shipmentMethod
+    if (shipmentMethod != null) {
+        String[] arr = shipmentMethod.split( '@' )
+        parameters.put('shipmentMethodTypeId', arr[0])
+        parameters.put('carrierPartyId', arr[1])
+        parameters.put('carrierRoleTypeId', arr[2])
+    }
+    lookedUpValue.setNonPKFields(parameters)
+
+    Map inputMap = [orderId: parameters.orderId,
+                    contactMechPurposeTypeId: 
parameters.contactMechPurposeTypeId]
+    if (parameters.contactMechId) {
+        inputMap.contactMechId = parameters.contactMechId
+    }
+    List orderContactMechList = from('OrderContactMech')
+        .where(inputMap)
+        .queryList()
+    // If orderContactMechList value is null then create new entry in 
OrderContactMech entity
+    if (!orderContactMechList && parameters.contactMechId) {
+        run service: 'createOrderContactMech', with: [*: inputMap]
+    }
+    lookedUpValue.store()
+
+    // Remove the old values from OrderContactMech entity with the help of 
oldContactMechId
+    Map shipGroupLookupMap = [orderId: parameters.orderId]
+    if (parameters.oldContactMechId) {
+        shipGroupLookupMap.contactMechId =  parameters.oldContactMechId
+    }
+    List<GenericValue> orderItemShipGroupList = from('OrderItemShipGroup')
+        .where(shipGroupLookupMap)
+        .queryList()
+    if (!orderItemShipGroupList) {
+        inputMap.contactMechId = parameters.oldContactMechId
+        run service: 'removeOrderContactMech', with: [*: inputMap]
+    }
+
+    // Update promisedDateTime & currentPromisedDate in OrderItemShipGrpInvRes 
entity
+    List itemShipGrpInvResList = from('OrderItemShipGrpInvRes')
+        .where('orderId', parameters.orderId,
+               'shipGroupSeqId', parameters.shipGroupSeqId)
+        .queryList()
+    if (itemShipGrpInvResList) {
+        for (GenericValue orderItemShipGrpInvRes: itemShipGrpInvResList) {
+            orderItemShipGrpInvRes.promisedDatetime = parameters.shipByDate
+            orderItemShipGrpInvRes.currentPromisedDate = parameters.shipByDate
+            orderItemShipGrpInvRes.store()
+        }
+    }
+    return success()
+}
+
+/*
+ * Compute and return the OrderItemShipGroup estimated ship date based on the 
associated items.
+ */
+Map getOrderItemShipGroupEstimatedShipDate() {
+    GenericValue orderItemShipGroup = from('OrderItemShipGroup')
+        .where('orderId', parameters.orderId,
+               'contactMechId', parameters.oldContactMechId)
+        .queryFirst()
+    GenericValue orderItemShipGroupInvRes =  from('OrderItemShipGrpInvRes')
+        .where('orderId', parameters.orderId,
+               'shipGroupSeqId', parameters.shipGroupSeqId)
+        .orderBy((orderItemShipGroup.maySplit == 'Y' ? '+' : '-') + 
'promisedDatetime')
+        .queryFirst()
+    return success(estimatedShipDate: 
orderItemShipGroupInvRes.promisedDatetime)
+}
+
+/*
+ * Create a PaymentMethodToOrder
+ */
+Map addPaymentMethodToOrder() {
+    if (!(security.hasEntityPermission('ORDERMGR', '_CREATE', 
parameters.userLogin))) {
+        return error(label('OrderErrorUiLabels', 
'OrderSecurityErrorToRunAddPaymentMethodToOrder'))
+    }
+    GenericValue paymentMethod = from('PaymentMethod')
+        .where('paymentMethodId', parameters.paymentMethodId)
+        .queryOne()
+
+    // In this method we calls createOrderPaymentPreference and returns 
orderPaymentPreferenceId field to authOrderPaymentPreference
+    return (run service: 'createOrderPaymentPreference', with: [
+            orderId: parameters.orderId,
+            maxAmount: parameters.maxAmount,
+            paymentMethodId: parameters.paymentMethodId,
+            paymentMethodTypeId: paymentMethod.paymentMethodTypeId])
+}
+
+/*
+ * Gets an order status
+ */
+Map getOrderStatus() {
+    GenericValue order = from('OrderHeader').where(parameters).queryOne()
+    return order
+            ? success(statusId: order.statusId)
+            : error(label('OrderErrorUiLabels', 'OrderOrderIdDoesNotExists'))
+}
+
+/*
+ * Check if an Order is on Back Order
+ */
+Map checkOrderIsOnBackOrder() {
+    EntityCondition condition = new EntityConditionBuilder().AND {
+            EQUALS(orderId: parameters.orderId)
+            NOT_EQUAL(quantityNotAvailable: null)
+            GREATER_THAN_EQUAL_TO(quantityNotAvailable: BigDecimal.ZERO)
+        }
+    return success([isBackOrder: from('OrderItemShipGrpInvRes')
+            .where(condition)
+            .queryCount() > 0])
+}
+
+/*
+ * Creates a new Order Item Change record
+ */
+Map createOrderItemChange() {
+    GenericValue newEntity = makeValue('OrderItemChange',
+            [*: parameters,
+             orderItemChangeId: delegator.getNextSeqId('OrderItemChange'),
+             changeDatetime: parameters.changeDatetime ?: 
UtilDateTime.nowTimestamp(),
+             changeUserLogin: parameters.changeUserLogin ?: 
userLogin.userLoginId])
+    newEntity.create()
+    return success([orderItemChangeId: newEntity.orderItemChangeId])
+}
+
+/*
+ * Create and update a Shipping Address
+ */
+Map createUpdateShippingAddress() {
+    String contactMechId = parameters.shipToContactMechId
+    String keepAddressBook = parameters.keepAddressBook ?: 'Y'
+    // Call map Processor
+    Map shipToAddressCtx = CheckoutMapProcs.shipToAddress(parameters)
+    String partyId = parameters.partyId
+    shipToAddressCtx.partyId = partyId
+
+    if (!contactMechId) {
+        shipToAddressCtx.contactMechPurposeTypeId = 'SHIPPING_LOCATION'
+        Map serviceResult = run service: 'createPartyPostalAddress', with: 
shipToAddressCtx
+        parameters.shipToContactMechId = serviceResult.contactMechId
+        logInfo("Shipping address created with contactMechId 
${parameters.shipToContactMechId}")
+    } else if (keepAddressBook == 'Y') {
+        GenericValue newValue = makeValue('PostalAddress', shipToAddressCtx)
+        GenericValue oldValue = 
from('PostalAddress').where(parameters).queryOne()
+        if (newValue != oldValue) {
+            shipToAddressCtx.contactMechId = null
+            Map serviceResult = run service: 'createPartyPostalAddress', with: 
shipToAddressCtx
+            parameters.shipToContactMechId = serviceResult.contactMechId
+        }
+
+        List<GenericValue> pcmpShipList = from('PartyContactMechPurpose')
+            .where(partyId: partyId,
+                   contactMechId: parameters.shipToContactMechId,
+                   contactMechPurposeTypeId: 'SHIPPING_LOCATION')
+            .filterByDate()
+            .queryList()
+        // If purpose does not exists then create
+        if (!pcmpShipList) {
+            List<GenericValue> pcmpList = from('PartyContactMechPurpose')
+                .where(partyId: partyId,
+                       contactMechPurposeTypeId: 'SHIPPING_LOCATION')
+                .filterByDate()
+                .queryList()
+            for (GenericValue pcmp: pcmpList) {
+                run service: 'expirePartyContactMechPurpose', with: 
pcmp.getAllFields()
+            }
+            run service: 'createPartyContactMechPurpose', with: [*: parameters,
+                                                                 partyId: 
partyId,
+                                                                 
contactMechId: parameters.shipToContactMechId,
+                                                                 
contactMechPurposeTypeId: 'SHIPPING_LOCATION']
+        }
+        if (parameters.setDefaultShipping == 'Y') {
+            run service: 'setPartyProfileDefaults', with: [partyId: partyId,
+                                                           productStoreId: 
parameters.productStoreId,
+                                                           defaultShipAddr: 
parameters.shipToContactMechId]
+        }
+    } else {
+        shipToAddressCtx.shipToContactMechId = shipToAddressCtx.contactMechId
+        if (shipToAddressCtx.shipToContactMechId == 
parameters.billToContactMechId) {
+            GenericValue newValue = makeValue('PostalAddress', 
shipToAddressCtx)
+            GenericValue oldValue = 
from('PostalAddress').where(parameters).queryOne()
+            if (newValue != oldValue) {
+                List<GenericValue> pcmpShipList = 
from('PartyContactMechPurpose')
+                    .where(partyId: partyId,
+                           contactMechId: shipToAddressCtx.shipToContactMechId,
+                           contactMechPurposeTypeId: 'SHIPPING_LOCATION')
+                    .filterByDate()
+                    .queryList()
+                for (GenericValue pcmp: pcmpShipList) {
+                    run service: 'expirePartyContactMechPurpose', with: 
pcmp.getAllFields()
+                }
+                Map serviceResult = run service: 'createPartyPostalAddress', 
with: [*: shipToAddressCtx,
+                                                                               
     partyId: partyId,
+                                                                               
     contactMechId: null,
+                                                                               
     contactMechPurposeTypeId: 'SHIPPING_LOCATION']
+                parameters.shipToContactMechId = serviceResult.contactMechId
+                logInfo("Shipping address updated with contactMechId 
${shipToAddressCtx.shipToContactMechId}")
+            }
+        } else {
+            shipToAddressCtx.userLogin = parameters.userLogin
+            Map serviceResult = run service: 'updatePartyPostalAddress', with: 
shipToAddressCtx
+            parameters.shipToContactMechId = serviceResult.contactMechId
+            logInfo("Shipping address updated with contactMechId 
${shipToAddressCtx.shipToContactMechId}")
+        }
+    }
+    return success([contactMechId: parameters.shipToContactMechId])
+}
+
+/*
+ * Create and update Billing Address
+ */
+Map createUpdateBillingAddress() {
+    String keepAddressBook = parameters.keepAddressBook ?: 'Y'
+    Map billToAddressCtx = [:]
+    if (parameters.useShippingAddressForBilling != 'Y') {
+        // Call map Processor
+        billToAddressCtx = CheckoutMapProcs.billToAddress(parameters)
+    }
+    String partyId = parameters.partyId
+    billToAddressCtx.partyId = partyId
+
+    if (parameters.useShippingAddressForBilling == 'Y') {
+        if (parameters.billToContactMechId) {
+            if (parameters.shipToContactMechId != 
parameters.billToContactMechId) {
+                List<GenericValue> pcmpList = from('PartyContactMechPurpose')
+                    .where(partyId: partyId,
+                           contactMechId: parameters.billToContactMechId,
+                           contactMechPurposeTypeId: 'BILLING_LOCATION')
+                    .filterByDate()
+                    .queryList()
+                for (GenericValue pcmp: pcmpList) {
+                    run service: 'deletePartyContactMech', with: 
pcmp.getAllFields()
+                }
+                if (keepAddressBook == 'N') {
+                    run service: 'createPartyContactMechPurpose', with: 
[contactMechId: parameters.billToContactMechId]
+                }
+                // Check that the ship-to address doesn't already have a 
bill-to purpose
+                pcmpList = from('PartyContactMechPurpose')
+                    .where(partyId: partyId,
+                           contactMechId: parameters.shipToContactMechId,
+                           contactMechPurposeTypeId: 'BILLING_LOCATION')
+                    .filterByDate()
+                    .queryList()
+                if (!pcmpList) {
+                    Map serviceContext = [*: parameters,
+                                          partyId: partyId,
+                                          contactMechId: 
parameters.shipToContactMechId,
+                                          contactMechPurposeTypeId: 
'BILLING_LOCATION']
+                    run service: 'createPartyContactMechPurpose', with: 
serviceContext
+                }
+                logInfo("Billing address updated with contactMechId 
${parameters.billToContactMechId}")
+            }
+        } else {
+            Map serviceContext = [*: parameters,
+                                  partyId: partyId,
+                                  contactMechId: 
parameters.shipToContactMechId,
+                                  contactMechPurposeTypeId: 'BILLING_LOCATION']
+            run service: 'createPartyContactMechPurpose', with: serviceContext
+        }
+        parameters.billToContactMechId = parameters.shipToContactMechId
+    } else {
+        if (parameters.billToContactMechId) {
+            if (parameters.shipToContactMechId == 
parameters.billToContactMechId) {
+                Map serviceResult = run service: 'createPartyPostalAddress', 
with: [*: billToAddressCtx,
+                                                                               
     contactMechId: null,
+                                                                               
     contactMechPurposeTypeId: 'BILLING_LOCATION']
+                parameters.billToContactMechId = serviceResult.contactMechId
+
+                List<GenericValue> pcmpList = from('PartyContactMechPurpose')
+                    .where(partyId: partyId,
+                           contactMechPurposeTypeId: 'BILLING_LOCATION')
+                    .filterByDate()
+                    .queryList()
+                for (GenericValue pcmp: pcmpList) {
+                    run service: 'expirePartyContactMechPurpose', with: 
pcmp.getAllFields()
+                }
+                serviceContext = [*: parameters,
+                                  partyId: partyId,
+                                  contactMechId: 
parameters.billToContactMechId,
+                                  contactMechPurposeTypeId: 'BILLING_LOCATION']
+                run service: 'createPartyContactMechPurpose', with: 
serviceContext
+                logInfo("Billing address updated with contactMechId 
${parameters.billToContactMechId}")
+            } else {
+                if (keepAddressBook == 'N') {
+                    billToAddressCtx.userLogin = parameters.userLogin
+                    Map serviceResult = run service: 
'updatePartyPostalAddress', with: billToAddressCtx
+                    parameters.billToContactMechId = 
serviceResult.contactMechId
+                } else if (keepAddressBook == 'Y') {
+                    GenericValue newValue = makeValue('PostalAddress', 
billToAddressCtx)
+                    GenericValue oldValue = 
from('PostalAddress').where(parameters).queryOne()
+                    if (newValue != oldValue) {
+                        billToAddressCtx.contactMechId = null
+                        Map serviceResult = run service: 
'createPartyPostalAddress', with: billToAddressCtx
+                        parameters.billToContactMechId = 
serviceResult.contactMechId
+                    }
+                }
+                logInfo("Billing Postal Address created billToContactMechId is 
${parameters.billToContactMechId}")
+            }
+            List<GenericValue> pcmpBillList = from('PartyContactMechPurpose')
+                .where(partyId: partyId,
+                       contactMechId: parameters.billToContactMechId,
+                       contactMechPurposeTypeId: 'BILLING_LOCATION')
+                .filterByDate()
+                .queryList()
+            // If purpose does not exists then create
+            if (!pcmpBillList) {
+                List<GenericValue> pcmpList = from('PartyContactMechPurpose')
+                    .where(partyId: partyId,
+                           contactMechPurposeTypeId: 'BILLING_LOCATION')
+                    .filterByDate()
+                    .queryList()
+                for (GenericValue pcmp: pcmpList) {
+                    run service: 'expirePartyContactMechPurpose', with: 
pcmp.getAllFields()
+                }
+                run service: 'createPartyContactMechPurpose', with: [*: 
parameters,
+                                                                     partyId: 
partyId,
+                                                                     
contactMechId: parameters.billToContactMechId,
+                                                                     
contactMechPurposeTypeId: 'BILLING_LOCATION']
+            }
+            if (parameters.setDefaultBilling == 'Y') {
+                run service: 'setPartyProfileDefaults', with: [partyId: 
partyId,
+                                                               productStoreId: 
parameters.productStoreId,
+                                                               
defaultBillAddr: parameters.billToContactMechId]
+            }
+        } else {
+            Map serviceResult = run service: 'createPartyPostalAddress', with: 
[*: billToAddressCtx,
+                                                                               
 contactMechPurposeTypeId: 'BILLING_LOCATION']
+            parameters.billToContactMechId = serviceResult.contactMechId
+            logInfo("Billing address created with contactmechId 
${parameters.billToContactMechId}")
+        }
+    }
+    return success([contactMechId: parameters.billToContactMechId])
+}
+
+/*
+ * Create and update credit card
+ */
+Map createUpdateCreditCard() {
+    Map serviceResult
+    String paymentMethodId = parameters.paymentMethodId
+    if (paymentMethodId) {
+        // call update Credit Card
+        GenericValue paymentMethod = from('PaymentMethod')
+            .where(partyId: parameters.partyId,
+                   paymentMethodTypeId: 'CREDIT_CARD')
+            .orderBy('-fromDate')
+            .queryFirst()
+        paymentMethodId = paymentMethod ? paymentMethod.paymentMethodId : ''
+        serviceResult = run service: 'updateCreditCard', with: [*: parameters,
+                                                              paymentMethodId: 
paymentMethodId]
+    } else {
+        // call create Credit Card
+        serviceResult = run service: 'createCreditCard', with: parameters
+    }
+    return success(paymentMethodId: serviceResult.paymentMethodId)
+}
+
+/*
+ * 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
+ */
+Map setUnitPriceAsLastPrice() {
+    GenericValue order = from('OrderHeader').where(parameters).queryOne()
+    if (!order || order.agreementId) {
+        return success()
+        // Do not update lastPrice if an agreement has been used on the order
+        // TODO replace by orderPItemPriceInfo analyse when it will support 
agreement
+    }
+    Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
+    if (parameters.facilityId) {
+        GenericValue orderSupplier = from('OrderHeaderItemAndRoles')
+            .where(orderId: order.orderId,
+                   roleTypeId: 'BILL_FROM_VENDOR',
+                   orderTypeId: 'PURCHASE_ORDER')
+            .queryFirst()
+        List<GenericValue> supplierProducts = from('SupplierProduct')
+            .where(productId: parameters.productId,
+                   partyId: orderSupplier.partyId,
+                   availableThruDate: null)
+            .queryList()
+        for (GenericValue supplierProduct: supplierProducts) {
+            if (parameters.orderCurrencyUnitPrice && 
parameters.orderCurrencyUnitPrice != supplierProduct.lastPrice) {
+                GenericValue newSupplierProduct = supplierProduct.clone()
+                newSupplierProduct.availableFromDate = nowTimestamp
+                newSupplierProduct.lastPrice = 
parameters.orderCurrencyUnitPrice
+                newSupplierProduct.create()
+                supplierProduct.availableThruDate = nowTimestamp
+                supplierProduct.store()
+            } else if (parameters.unitCost != supplierProduct.lastPrice) {
+                GenericValue newSupplierProduct = supplierProduct.clone()
+                newSupplierProduct.availableFromDate = nowTimestamp
+                newSupplierProduct.lastPrice = parameters.unitCost
+                newSupplierProduct.create()
+                supplierProduct.availableThruDate = nowTimestamp
+                supplierProduct.store()
+            }
+        }
+    } else if (!parameters.orderItems) {
+        List<GenericValue> orderItems = from('OrderItem')
+            .where(orderId: order.orderId)
+            .queryList()
+        Map<String, Object> itemPriceMap = parameters.itemPriceMap as Map
+        Map<String, Object> overridePriceMap = parameters.overridePriceMap as 
Map
+        List<Map<String, BigDecimal>> productIdPrices = []
+        Set<String> productIds = []
+        for (Map.Entry<String, String> itemPrice : itemPriceMap.entrySet()) {
+            String orderItemSeqId = itemPrice.getKey()
+            BigDecimal unitPrice = itemPrice.getValue()
+            GenericValue orderItem = orderItems.find { it.orderItemSeqId == 
orderItemSeqId }
+            Map.Entry<String, String> overridePrice = overridePriceMap.find { 
it.key == orderItemSeqId }
+            if (orderItem && overridePrice) {
+                productIdPrices << [(orderItem.productId): unitPrice]
+                productIds << orderItem.productId
+            }
+        }
+        EntityCondition condition = new EntityConditionBuilder().AND {
+            EQUALS(partyId: parameters.supplierPartyId)
+            EQUALS(availableThruDate: null)
+            IN(productId: productIds)
+        }
+        List<GenericValue> supplierProducts = from('SupplierProduct')
+            .where(condition)
+            .queryList()
+        for (GenericValue supplierProduct : supplierProducts) {
+            BigDecimal unitPrice = productIdPrices.find { 
it.keySet().contains(supplierProduct.productId) }?.(supplierProduct.productId)
+            if (unitPrice != supplierProduct.lastPrice) {
+                GenericValue newSupplierProduct = supplierProduct.clone()
+                newSupplierProduct.availableFromDate = nowTimestamp
+                newSupplierProduct.lastPrice = unitPrice
+                newSupplierProduct.create()
+                supplierProduct.availableThruDate = nowTimestamp
+                supplierProduct.store()
+            }
+        }
+    } else {
+        List<GenericValue> orderItems = parameters.orderItems
+        Set<String> productIds = orderItems*.productId
+        EntityCondition condition = new EntityConditionBuilder().AND {
+            EQUALS(partyId: parameters.supplierPartyId)
+            EQUALS(availableThruDate: null)
+            IN(productId: productIds)
+        }
+        List<GenericValue> supplierProducts = from('SupplierProduct')
+            .where(condition)
+            .queryList()
+        for (GenericValue supplierProduct : supplierProducts) {
+            GenericValue orderItem = orderItems.find { it.productId == 
supplierProduct.productId }
+            if (orderItem.unitPrice != supplierProduct.lastPrice) {
+                GenericValue newSupplierProduct = supplierProduct.clone()
+                newSupplierProduct.availableFromDate = nowTimestamp
+                newSupplierProduct.lastPrice = orderItem.unitPrice
+                newSupplierProduct.create()
+                supplierProduct.availableThruDate = nowTimestamp
+                supplierProduct.store()
+            }
+        }
+    }
+    return success()
+}
+
+/*
+ * Cancels those back orders from suppliers whose cancel back order date 
(cancelBackOrderDate) has passed the current date
+ */
+Map cancelAllBackOrders() {
+    Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
+    EntityCondition condition = EntityCondition.makeCondition([
+        EntityCondition.makeCondition('orderTypeId', 'PURCHASE_ORDER'),
+        EntityCondition.makeCondition('statusId', EntityOperator.NOT_IN, 
['ORDER_CANCELLED', 'ORDER_COMPLETED'])])
+    List<String> currentOrderIds = from('OrderHeader')
+        .where(condition)
+        .getFieldList('orderId')
+    if (currentOrderIds) {
+        List<GenericValue> orderItems = from('OrderItem')
+            .where(EntityCondition.makeCondition('orderId', EntityOperator.IN, 
currentOrderIds))
+            .queryList()
+        for (GenericValue currentOrderItem: orderItems) {
+            Timestamp backOrderDate = currentOrderItem.cancelBackOrderDate
+            if (backOrderDate && backOrderDate.before(nowTimestamp) ) {
+                run service: 'cancelOrderItem', with: [ orderId: 
currentOrderItem.orderId,
+                                                        orderItemSeqId: 
currentOrderItem.orderItemSeqId]
+            }
+        }
+    }
+    return success()
+}
+
+/*
+ * Updates shipping method and shipping charges from Order View page when 
Shipment is in picked status and items of Order are packed
+ */
+Map updateShippingMethodAndCharges() {
+    // splitting shipmentMethodAndAmount request parameter value that contains 
"*" symbol into "shipmentMethod" and "newAmount".
+    // shipmentMethod request parameter value contains "@" symbol between 
"shipmentMethodTypeId" and "carrierPartyId".
+    // This will be splitted in updateOrderItemShipGroup method
+    String shipmentMethodAndAmount = parameters.shipmentMethodAndAmount
+    if (shipmentMethodAndAmount != null) {
+        parameters.shipmentMethod = shipmentMethodAndAmount.substring(0, 
shipmentMethodAndAmount.indexOf('*'))
+        parameters.amount = 
shipmentMethodAndAmount.substring(shipmentMethodAndAmount.indexOf('*') + 1)
+        parameters.shipmentMethodTypeId = shipmentMethodAndAmount.substring(0, 
shipmentMethodAndAmount.indexOf('@'))
+    }
+    BigDecimal newAmount
+    BigDecimal shippingAmount
+    BigDecimal percentAllowedBd
+    String percentAllowed = 
UtilProperties.getPropertyValue('shipment.properties', 
'shipment.default.cost_actual_over_estimated_percent_allowed')
+    try {
+        newAmount = (BigDecimal) 
ObjectType.simpleTypeOrObjectConvert(parameters.amount, 'BigDecimal', null, 
locale)
+        shippingAmount = (BigDecimal) 
ObjectType.simpleTypeOrObjectConvert(parameters.shippingAmount, 'BigDecimal', 
null, locale)
+        percentAllowedBd = (BigDecimal) 
ObjectType.simpleTypeOrObjectConvert(percentAllowed, 'BigDecimal', null, locale)
+    } catch (GeneralException e) {
+        return error(e.getMessage())
+    }
+    BigDecimal diffPercentage = (newAmount > shippingAmount
+            ? (newAmount - shippingAmount / shippingAmount)
+            : (shippingAmount - newAmount / newAmount)) * 100
+
+    if (diffPercentage > percentAllowedBd) {
+        run service: 'updateOrderAdjustment', with: parameters
+    }
+    run service: 'updateOrderItemShipGroup', with: parameters
+    run service: 'updateShipmentRouteSegment', with: [*: parameters,
+                                                       trackingIdNumber: null,
+                                                       trackingDigest: null,
+                                                       carrierServiceStatusId: 
null]
+    run service: 'upsShipmentConfirm', with: parameters
+    return success()
+}
+
+/*
+ * Calculate ATP and Qoh According For each facility
+ */
+Map productAvailabilityByFacility() {
+    List availabilityList = []
+    List<GenericValue> facilityList = from('Facility')
+        .where(ownerPartyId: parameters.ownerPartyId)
+        .queryList()
+    for (GenericValue facility: facilityList) {
+        Map serviceResult = run service: 'getInventoryAvailableByFacility', 
with: [
+            facilityId: facility.facilityId,
+            productId: parameters.productId]
+        availabilityList << [facilityId: facility.facilityId,
+                             quantityOnHandTotal: 
serviceResult.quantityOnHandTotal,
+                             availableToPromiseTotal: 
serviceResult.availableToPromiseTotal]
+    }
+    return success([availabalityList: availabilityList])
+}
+
+/*
+ * Create Order Payment Application
+ */
+Map createOrderPaymentApplication() {
+    GenericValue payment = from('Payment').where(parameters).queryOne()
+    if (!payment) {
+        return error(label('AccountingUiLabels', 'AccountingNoPaymentsfound'))
+    }
+    GenericValue orderPaymentPref = from('OrderPaymentPreference')
+        .where(orderPaymentPreferenceId: payment.paymentPreferenceId)
+        .queryOne()
+    GenericValue orderItemBilling = from('OrderItemBilling')
+        .where(orderId: orderPaymentPref.orderId)
+        .queryFirst()
+    if (orderItemBilling) {
+        run service: 'createPaymentApplication', with: [amountApplied: 
payment.amount,
+                                                        paymentId: 
payment.paymentId,
+                                                        invoiceId: 
orderItemBilling.invoiceId]
+    }
+    return success()
+}
+
+/*
+ * Move order items between ship groups
+ */
+Map moveItemBetweenShipGroups() {
+    GenericValue toOisga = from('OrderItemShipGroupAssoc')
+        .where(orderId: parameters.orderId,
+               orderItemSeqId: parameters.orderItemSeqId,
+               shipGroupSeqId: parameters.toGroupIndex)
+        .queryOne()
+    if (!toOisga) {
+        run service: 'addOrderItemShipGroupAssoc', with: [*: parameters,
+                                                          quantity: 
BigDecimal.ZERO,
+                                                          shipGroupSeqId: 
parameters.toGroupIndex]
+        toOisga = from('OrderItemShipGroupAssoc')
+            .where(orderId: parameters.orderId,
+                   orderItemSeqId: parameters.orderItemSeqId,
+                   shipGroupSeqId: parameters.toGroupIndex)
+            .queryOne()
+    }
+
+    run service: 'updateOrderItemShipGroupAssoc', with: [orderId: 
parameters.orderId,
+                                                         orderItemSeqId: 
parameters.orderItemSeqId,
+                                                         shipGroupSeqId: 
parameters.toGroupIndex,
+                                                         quantity: 
toOisga.quantity + parameters.quantity]
+
+    GenericValue fromOisga = from('OrderItemShipGroupAssoc')
+        .where(orderId: parameters.orderId,
+               orderItemSeqId: parameters.orderItemSeqId,
+               shipGroupSeqId: parameters.fromGroupIndex)
+        .queryOne()
+    if (!fromOisga) {
+        return error(label('OrderErrorUiLabels', 
'OrderServiceOrderItemShipGroupAssocNotExist'))
+    }
+    run service: 'updateOrderItemShipGroupAssoc', with: [orderId: 
parameters.orderId,
+                                                         orderItemSeqId: 
parameters.orderItemSeqId,
+                                                         shipGroupSeqId: 
parameters.fromGroupIndex,
+                                                         quantity: 
fromOisga.quantity - parameters.quantity]
+    return success()
 }
diff --git a/applications/order/template/entry/cart/ShowCart.ftl 
b/applications/order/template/entry/cart/ShowCart.ftl
index 6af741b821..de35e0fa02 100644
--- a/applications/order/template/entry/cart/ShowCart.ftl
+++ b/applications/order/template/entry/cart/ShowCart.ftl
@@ -27,7 +27,7 @@ under the License.
     }
 </script>
 <#if "PURCHASE_ORDER" == shoppingCart.getOrderType()>
-  <#assign target="productAvailabalityByFacility">
+  <#assign target="productAvailabilityByFacility">
 <#else>
   <#assign target="getProductInventoryAvailable">
 </#if>
diff --git a/applications/order/testdef/data/OrderTestData.xml 
b/applications/order/testdef/data/OrderTestData.xml
index 518c13dc01..f9519e00d3 100644
--- a/applications/order/testdef/data/OrderTestData.xml
+++ b/applications/order/testdef/data/OrderTestData.xml
@@ -70,4 +70,10 @@ under the License.
     <Shipment shipmentId="1014" shipmentTypeId="SALES_SHIPMENT" 
primaryOrderId="DEMO10090" primaryShipGroupSeqId="00001" 
statusId="SHIPMENT_SHIPPED"/>
     <ShipmentItem shipmentId="1014" shipmentItemSeqId="00001"/>
 
+    <Invoice invoiceId="TEST_DEMO10090" partyId="TestDemoCustomer" 
partyIdFrom="Company" invoiceDate="2009-08-17 14:56:44.573" 
statusId="INVOICE_PAID" currencyUom="USD"/>
+    <InvoiceItem invoiceId="TEST_DEMO10090" invoiceItemSeqId="00001" 
invoiceItemTypeId="PINV_FPROD_ITEM" productId="GZ-2644" quantity="2.000000" 
amount="38.40" description="GZ-2644-0 Round Gizmo"/>
+    <OrderItemBilling orderId="TEST_DEMO10090" orderItemSeqId="00001" 
invoiceId="TEST_DEMO10090" invoiceItemSeqId="00001" quantity="2.000000" 
amount="38.40"/>
+    <OrderPaymentPreference orderPaymentPreferenceId="TEST_DEMO10090" 
orderId="TEST_DEMO10090" maxAmount="76.80" statusId="PAYMENT_SETTLED" 
createdDate="2009-08-17 14:56:44.573"/>
+    <Payment paymentId="1014" paymentTypeId="CUSTOMER_PAYMENT" 
paymentPreferenceId="TEST_DEMO10090" paymentMethodTypeId="EFT_ACCOUNT" 
partyIdFrom="TestDemoCustomer" partyIdTo="Company" statusId="PMNT_RECEIVED" 
effectiveDate="2006-04-25 12:56:54.292" amount="76.80" currencyUomId="USD"/>
+
 </entity-engine-xml>
diff --git a/applications/order/webapp/ordermgr/WEB-INF/controller.xml 
b/applications/order/webapp/ordermgr/WEB-INF/controller.xml
index 6fd65ef329..d5668b06cb 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/controller.xml
+++ b/applications/order/webapp/ordermgr/WEB-INF/controller.xml
@@ -1895,9 +1895,9 @@ under the License.
     </request-map>
 
     <request-map uri="LookupContent"><security auth="true" 
https="true"/><response name="success" type="view" 
value="LookupContent"/></request-map>
-    <request-map uri="productAvailabalityByFacility">
+    <request-map uri="productAvailabilityByFacility">
         <security https="true" auth="true"/>
-        <event type="service" invoke="productAvailabalityByFacility"/>
+        <event type="service" invoke="productAvailabilityByFacility"/>
         <response name="success" type="view" value="showcart"/>
         <response name="error" type="view" value="showcart"/>
     </request-map>
diff --git 
a/applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentServices.groovy
 
b/applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentServices.groovy
index e2c6d1cf8c..d263435dee 100644
--- 
a/applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentServices.groovy
+++ 
b/applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentServices.groovy
@@ -678,13 +678,14 @@ Map ensureRouteSegPackage() {
     GenericValue shipmentRouteSegment = 
from('ShipmentRouteSegment').where(parameters).cache().queryOne()
     List shipmentPackages = from('ShipmentPackage').where(shipmentId: 
shipmentRouteSegment.shipmentId).queryList()
     for (GenericValue shipmentPackage : shipmentPackages) {
+        Map sprsMap = [shipmentId: parameters.shipmentId,
+            shipmentRouteSegmentId: parameters.shipmentRouteSegmentId,
+            shipmentPackageSeqId: shipmentPackage.shipmentPackageSeqId]
         GenericValue checkShipmentPackageRouteSeg = 
from('ShipmentPackageRouteSeg')
-                .where(shipmentRouteSegment as Map)
+                .where(sprsMap)
                 .queryOne()
         if (!checkShipmentPackageRouteSeg) {
-            run service: 'createShipmentPackageRouteSeg', with: [shipmentId: 
parameters.shipmentId,
-                                                                 
shipmentRouteSegmentId: parameters.shipmentRouteSegmentId,
-                                                                 
shipmentPackageSeqId: shipmentPackage.shipmentPackageSeqId]
+            run service: 'createShipmentPackageRouteSeg', with: sprsMap
         }
     }
     return success()


Reply via email to