You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by nm...@apache.org on 2020/04/08 12:25:35 UTC

[ofbiz-framework] branch trunk updated: Improved: Convert OrderReturnService.xml from mini lang to groovy (OFBIZ-11442)

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 f6418d5  Improved: Convert OrderReturnService.xml from mini lang to groovy (OFBIZ-11442)
f6418d5 is described below

commit f6418d52f598e64340268fadf2b22d361bdd2a49
Author: Nicolas Malin <ni...@nereide.fr>
AuthorDate: Wed Apr 8 14:25:00 2020 +0200

    Improved: Convert OrderReturnService.xml from mini lang to groovy
    (OFBIZ-11442)
    
    Thanks to Sebastian Berg for providing the patch
---
 .../groovyScripts/order/OrderReturnServices.groovy |  988 ++++++++++++++++
 .../order/minilang/order/OrderReturnServices.xml   | 1186 --------------------
 applications/order/servicedef/services_return.xml  |  103 +-
 3 files changed, 1039 insertions(+), 1238 deletions(-)

diff --git a/applications/order/groovyScripts/order/OrderReturnServices.groovy b/applications/order/groovyScripts/order/OrderReturnServices.groovy
new file mode 100644
index 0000000..b8bb8ce
--- /dev/null
+++ b/applications/order/groovyScripts/order/OrderReturnServices.groovy
@@ -0,0 +1,988 @@
+/*
+ * 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.
+ */
+
+import java.sql.Timestamp
+
+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.util.EntityUtil
+import org.apache.ofbiz.service.ServiceUtil
+
+
+/**
+ * Create a ReturnHeader
+ * @return
+ */
+def createReturnHeader() {
+    Map result = success()
+    Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
+    
+    if (!security.hasEntityPermission("ORDERMGR", "_CREATE", parameters.userLogin)
+            && userLogin.partyId != parameters.fromPartyId) {
+        return informError("OrderSecurityErrorToRunCreateReturnHeader")
+    }
+    String returnHeaderTypeId = parameters.returnHeaderTypeId
+    if (!parameters.toPartyId) {
+        // no toPartyId was specified. use destination facility to determine the party of the return
+        if ("CUSTOMER_RETURN" == returnHeaderTypeId && parameters.destinationFacilityId) {
+            GenericValue destinationFacility = from("Facility")
+                    .where(facilityId: parameters.destinationFacilityId)
+                    .cache()
+                    .queryOne()
+            parameters.toPartyId = destinationFacility.ownerPartyId
+        }
+    } else {
+        // make sure that the party to return to is an INTERNAL_ORGANIZATIO for customer return
+        // and SUPPLIER for vendor return else stop
+        if (returnHeaderTypeId.contains("CUSTOMER_")) {
+            GenericValue partyRole = from("PartyRole")
+                    .where(partyId: parameters.toPartyId, roleTypeId: "INTERNAL_ORGANIZATIO")
+                    .cache()
+                    .queryOne()
+            if (!partyRole) {
+                return informError("OrderReturnRequestPartyRoleInternalOrg")
+            }
+        } else {
+            GenericValue partyRole = from("PartyRole")
+                    .where(partyId: parameters.toPartyId, roleTypeId: "SUPPLIER")
+                    .cache()
+                    .queryOne()
+            if (!partyRole) {
+                return informError("OrderReturnRequestPartyRoleSupplier")
+            }
+        }
+    }
+    if (parameters.paymentMethodId) {
+        GenericValue paymentMethod = from("PaymentMethod")
+                .where(paymentMethodId: parameters.paymentMethodId)
+                .cache()
+                .queryOne()
+        if (!paymentMethod) {
+            return informError("OrderReturnRequestPaymentMethodId")
+        }
+    }
+    // check the needs (auto) inventory receive flag
+    // (default to N, meaning that return won't automatically be considered Received when Accepted)
+    if (!parameters.needsInventoryReceive) {
+        parameters.needsInventoryReceive = "N"
+    }
+    GenericValue newEntity = makeValue("ReturnHeader")
+    newEntity.setNonPKFields(parameters)
+    
+    // If PartyAcctgPreference.useInvoiceIdForReturns is Y, get the ID from the getNextInvoiceId service
+    GenericValue systemLogin = from("UserLogin")
+            .where(userLoginId: "system")
+            .cache()
+            .queryOne()
+    Map serviceResult = run service:"getPartyAccountingPreferences", with: [organizationPartyId: parameters.toPartyId,
+                                                                            userLogin: systemLogin]
+    GenericValue partyAcctgPreference = serviceResult.partyAccountingPreference
+    
+    if ("Y" == partyAcctgPreference.useInvoiceIdForReturns) {
+        Map serviceResultInvoice = run service: "getNextInvoiceId", with: [partyId: parameters.toPartyId]
+        newEntity.returnId = serviceResultInvoice.invoiceId
+    } else {
+        newEntity.returnId = delegator.getNextSeqId("ReturnHeader")
+    }
+    result.returnId = newEntity.returnId
+
+    boolean hasCreatePermission = security.hasEntityPermission("ORDERMGR", "_CREATE", parameters.userLogin)
+    if (!newEntity.entryDate || !hasCreatePermission) {
+        newEntity.entryDate = nowTimestamp
+    }
+    if (!newEntity.statusId || !hasCreatePermission) {
+        newEntity.statusId = "CUSTOMER_RETURN" == returnHeaderTypeId ? "RETURN_REQUESTED" : "SUP_RETURN_REQUESTED"
+    }
+    newEntity.createdBy = userLogin.userLoginId
+    newEntity.create()
+    result.successMessage = "Return Request #[${newEntity.returnId}] was created successfully."
+    return result
+}
+
+/**
+ * Update a ReturnHeader
+ * @return
+ */
+def updateReturnHeader() {
+    Map result = success()
+    GenericValue returnHeader = from("ReturnHeader").where(parameters).queryOne()
+    // test the total return amount vs the total order amount
+    if ("RETURN_ACCEPTED" == parameters.statusId) {
+        // get the list of ReturnItems.  Note: return may be associated with many different orders
+        List returnItems = from("ReturnItem").where(returnId: returnHeader.returnId).distinct().queryList()
+        
+        // this is used to make sure we don't return a negative amount
+        BigDecimal returnTotalAmount = (BigDecimal) 0
+        
+        // check them all to make sure that the return total does not exceed order total.
+        for (GenericValue returnItem : returnItems) {
+            if (!returnHeader.paymentMethodId && !parameters.paymentMethodId &&
+                ("RTN_CSREPLACE" == returnItem.returnTypeId || "RTN_REPAIR_REPLACE" == returnItem.returnTypeId)) {
+                return informError("OrderReturnPaymentMethodNeededForThisTypeOfReturn")
+            }
+            // tally up the return total amount
+            returnTotalAmount += returnItem.returnPrice * returnItem.returnQuantity
+            // compare return vs order total
+            if (returnItem.orderId) {
+                // no adjustment needed: adjustment is passed in to calculate
+                // the effect of an additional item on return total.
+                Map serviceResult = run service:"getOrderAvailableReturnedTotal", with: [orderId: returnItem.orderId,
+                                                                                         adjustment : (BigDecimal) 0]
+                BigDecimal availableReturnTotal = serviceResult.availableReturnTotal
+                BigDecimal returnTotal = serviceResult.returnTotal
+                BigDecimal orderTotal = serviceResult.returnTotal
+                logInfo("Available amount for return on order # ${returnItem.orderId} is " +
+                        "[${availableReturnTotal}] (orderTotal = [${orderTotal}] - returnTotal = [${returnTotal}]")
+                
+                if (availableReturnTotal < (BigDecimal) -0.01) {
+                    return informError("OrderReturnPriceCannotExceedTheOrderTotal")
+                }
+            } else {
+                logInfo("Not an order based returnItem; uable to check valid amounts!")
+            }
+        }
+        // Checking that the Status change is Valid or Not
+        if (parameters.statusId && parameters.statusId != returnHeader.statusId) {
+            GenericValue statusValidChange = from("StatusValidChange")
+                    .where(statusId: returnHeader.statusId, statusIdTo: parameters.statusId)
+                    .cache()
+                    .queryOne()
+            if (!statusValidChange) {
+                return informError("OrderErrorReturnHeaderItemStatusNotChangedIsNotAValidChange")
+            }
+        }
+        List returnAdjustments = from("ReturnAdjustment").where(returnId: returnHeader.returnId).queryList()
+        for (GenericValue returnAdjustment : returnAdjustments) {
+            returnTotalAmount += returnAdjustment.amount
+        }
+        if (returnTotalAmount < 0) {
+            return informError("OrderReturnTotalCannotLessThanZero")
+        }
+    }
+    result.oldStatusId = returnHeader.statusId
+    returnHeader.setNonPKFields(parameters)
+    returnHeader.store()
+    return result
+}
+
+/**
+ * Create Return Item
+ * @return
+ */
+def createReturnItem() {
+    Map result = success()
+    GenericValue orderItem
+    GenericValue returnHeader = from("ReturnHeader")
+            .where(returnId: parameters.returnId)
+            .queryOne()
+    
+    if (!security.hasEntityPermission("ORDERMGR", "_CREATE", parameters.userLogin)
+            && returnHeader.fromPartyId != userLogin.partyId) {
+        return informError("OrderSecurityErrorToRunCreateReturnItem")
+    }
+    if (!parameters.returnItemTypeId) {
+        return informError("OrderReturnItemTypeIsNotDefined")
+    }
+    
+    if (!returnHeader?.paymentMethodId && "RETURN_ACCEPTED" == returnHeader.statusId
+        && ("RTN_CSREPLACE" == parameters.returnTypeId || "RTN_REPAIR_REPLACE" == parameters.returnTypeId)) {
+        return informError("OrderReturnPaymentMethodNeededForThisTypeOfReturn")
+    }
+    if (parameters.returnQuantity == (BigDecimal) 0) {
+        return informError("OrderNoReturnQuantityAvailablePreviousReturnsMayExist")
+    }
+    
+    // setup some default values for protection
+    BigDecimal returnableQuantity = (BigDecimal) 0
+    BigDecimal returnablePrice = (BigDecimal) 0
+    
+    // if an orderItemSeqId is provided, then find the corresponding orderItem
+    if (parameters.orderItemSeqId) {
+        Map itemLookup = makeValue("OrderItem")
+        itemLookup.setPKFields(parameters)
+        if (parameters.orderItemSeqId) {
+            orderItem = from("OrderItem").where(itemLookup).queryOne()
+            logInfo("Return item is an Order Item - " + orderItem.orderItemSeqId)
+        }
+    }
+    /*
+     * get the returnableQuantity and returnablePrice:
+     * for orderItems, it's found by getReturnableQuantity;
+     * for adjustments, either order adjustments or manual adjustments, it's always 1 and based on input parameter
+     */
+    if (orderItem) {
+        Map serviceResult = run service: "getReturnableQuantity", with: [orderItem: orderItem]
+        returnableQuantity = serviceResult.returnableQuantity ?: returnableQuantity
+        returnablePrice = serviceResult.returnablePrice ?: returnablePrice
+    }
+    if (returnableQuantity > (BigDecimal) 0) {
+        // the user is only allowed to set a returnPrice if he has ORDERMGR_CREATE privilege,
+        // otherwise only the returnablePrice calculated by service is used
+        if (!security.hasEntityPermission("ORDERMGR", "_CREATE", parameters.userLogin)) {
+            returnablePrice = parameters.returnPrice
+        }
+        // make sure the returnQuantity is not greater than the returnableQuantity
+        // from service or the quantity on the original orderItem
+        if (parameters.returnQuantity > returnableQuantity) {
+            return informError("OrderRequestedReturnQuantityNotAvailablePreviousReturnsMayExist")
+        }
+        if (orderItem && parameters.returnQuantity > orderItem.quantity) {
+            return informError("OrderReturnQuantityCannotExceedTheOrderedQuantity")
+        }
+        if (parameters.returnPrice > returnablePrice) {
+            return informError("OrderReturnPriceCannotExceedThePurchasePrice")
+        }
+    } else {
+        logError("Order ${parameters.orderId} item ${parameters.orderItemSeqId} has been returned in full")
+        return informError("OrderIllegalReturnItemTypePassed")
+    }
+    GenericValue newEntity = makeValue("ReturnItem")
+    newEntity.returnId = parameters.returnId
+    delegator.setNextSubSeqId(newEntity, "returnItemSeqId", 5, 1)
+    newEntity.setNonPKFields(parameters)
+    newEntity.statusId = "RETURN_REQUESTED" // default status for new return items
+    result.returnItemSeqId = newEntity.returnItemSeqId
+    newEntity.create()
+    newEntity.refresh()
+    
+    if (orderItem && !parameters.includeAdjustments || "Y" == parameters.includeAdjustments) {
+        // create return adjustments for all adjustments associated with the order item
+        List orderAdjustments = delegator.getRelated("OrderAdjustment", null, null, orderItem, false)
+        for (GenericValue orderAdjustment : orderAdjustments) {
+            Map returnAdjCtx = [returnId: parameters.returnId,
+                                returnItemSeqId: newEntity.returnItemSeqId,
+                                returnTypeId: newEntity.returnTypeId,
+                                orderAdjustmentId: orderAdjustment.orderAdjustmentId]
+            run service:"createReturnAdjustment", with: returnAdjCtx
+        }
+    }
+    return result
+}
+
+/**
+ * Update Return Item
+ * @return
+ */
+def updateReturnItem() {
+    Map result = success()
+    Map lookupPKMap = [returnId: parameters.returnId, returnItemSeqId: parameters.returnItemSeqId]
+    GenericValue returnItem = from("ReturnItem").where(lookupPKMap).queryOne()
+    BigDecimal originalReturnPrice = returnItem.returnPrice
+    BigDecimal originalReturnQuantity = returnItem.returnQuantity
+    result.oldStatusId = returnItem.statusId
+    
+    returnItem.setNonPKFields(parameters)
+    returnItem.store()
+    returnItem.refresh()
+    
+    // now update all return adjustments associated with this return item
+    List returnAdjustments = from("ReturnAdjustment")
+            .where(returnId: returnItem.returnId,
+                    returnItemSeqId: returnItem.returnItemSeqId)
+            .queryList()
+    for (GenericValue returnAdjustment : returnAdjustments) {
+        logInfo("updating returnAdjustment with Id:[${returnAdjustment.returnAdjustmentId}]")
+        Map ctx = returnAdjustment
+        ctx.originalReturnPrice = originalReturnPrice
+        ctx.originalReturnQuantity = originalReturnQuantity
+        ctx.ReturnTypeId = returnItem.returnTypeId
+        run service: "updateReturnAdjustment", with: ctx
+    }
+    return result
+}
+
+/**
+ * Update Return Items Status
+ * @return
+ */
+def updateReturnItemsStatus() {
+    List returnItems = from("ReturnItem").where(returnId: parameters.returnId).queryList()
+    for (GenericValue item : returnItems) {
+        item.statusId = parameters.statusId
+        Map serviceInMap = [:]
+        serviceInMap << item
+        run service:"updateReturnItem", with: serviceInMap
+    }
+    return success()
+}
+
+/**
+ * Remove Return Item
+ * @return
+ */
+def removeReturnItem() {
+    GenericValue returnHeader = from("ReturnHeader").where(parameters).queryOne()
+    if ("CUSTOMER_RETURN" == returnHeader.returnHeaderTypeId) {
+        if ("RETURN_REQUESTED" != returnHeader.statusId) {
+            return informError("OrderCannotRemoveItemsOnceReturnIsApproved")
+        }
+    } else {
+        if ("SUP_RETURN_REQUESTED" != returnHeader.statusId) {
+            return informError("OrderCannotRemoveItemsOnceReturnIsApproved")
+        }
+    }
+    GenericValue returnItem = from("ReturnItem")
+            .where(returnId: parameters.returnId,
+                    returnItemSeqId: parameters.returnItemSeqId)
+            .queryOne()
+    // remove related  adjustments
+    List returnAdjustments = from("ReturnAdjustment")
+            .where(returnItemSeqId: returnItem.returnItemSeqId,
+                    returnId: returnItem.returnId)
+            .queryList()
+    for (GenericValue returnAdjustment : returnAdjustments) {
+        run service:"removeReturnAdjustment", with: [returnAdjustmentId: returnAdjustment.returnAdjustmentId]
+    }
+    returnItem.remove()
+    return success()
+}
+
+// note that this service is designed to be called once for each shipment receipt that is created
+
+/**
+ * Update Return Status From ShipmentReceipt
+ * @return
+ */
+def updateReturnStatusFromReceipt() {
+    Map result = success()
+    Map lookupPKMap = [returnId: parameters.returnId]
+    GenericValue returnHeader = from("ReturnHeader").where(lookupPKMap).queryOne()
+    List shipmentReceipts = from("ShipmentReceipt").where(lookupPKMap).queryList()
+    Map totalsMap = [:]
+    for (GenericValue receipt : shipmentReceipts) {
+        if (!totalsMap[receipt?.returnItemSeqId]) {
+            totalsMap[receipt.returnItemSeqId] = (BigDecimal) 0
+        }
+        totalsMap[receipt.returnItemSeqId] += receipt.quantityAccepted + receipt.quantityRejected
+    }
+    List returnItems = delegator.getRelated("ReturnItem", null, null, returnHeader, false)
+    
+    for (Map.Entry entry : totalsMap.entrySet()) {
+        Map filterMap = [returnItemSeqId: entry.getKey()]
+        Map item = EntityUtil.getFirst(EntityUtil.filterByAnd(returnItems, filterMap))
+        item.receivedQuantity = entry.getValue()
+        if (entry.getValue() >= item.returnQuantity) {
+            // update the status for the item
+            item.statusId = "RETURN_RECEIVED"
+        }
+        // update the returnItem with at least receivedQuantity, and also statusId if applicable
+        run service: "updateReturnItem", with: item
+    }
+    // check to see if all items have been received
+    boolean allReceived = true
+    List allReturnItems = from("ReturnItem").where(lookupPKMap).queryList()
+    for (GenericValue item : allReturnItems) {
+        if ("RETURN_RECEIVED" != item.statusId) {
+            if (item.orderItemSeqId) {
+                // non-order items (i.e. adjustments) are not received
+                allReceived = false
+            }
+        }
+    }
+    
+    // if the items are all received, then update the return header, store the status history change,
+    // and set the shipment to received
+    if (allReceived) {
+        /*
+         * Go through all the items yet again and set their shipment status to PURCH_SHIP_RECEIVED (if it isn't already)
+         * This activates SECAS such as creating return invoices. This MUST be done before updating the return header so
+         * that the ReturnItemBillings are created and then whatever SECA binds to the return header update will have them.
+         */
+        for (GenericValue receipt : shipmentReceipts) {
+            GenericValue shipment = delegator.getRelatedOne("Shipment", receipt, false)
+            if (shipment.shipmentId) {
+                if ("RETURN_RECEIVED" != shipment.statusId) {
+                    run service:"updateShipment", with: [shipmentId: shipment.shipmentId,
+                                                         statusId: "PURCH_SHIP_RECEIVED"]
+                }
+            }
+        }
+        // update the return header
+        run service:"updateReturnHeader", with: [statusId: "RETURN_RECEIVED",
+                                                 returnId: returnHeader.returnId]
+    }
+    result.returnHeaderStatus = returnHeader.statusId
+    return result
+}
+
+/**
+ * Create Quick Return From Order
+ * @return
+ */
+def quickReturnFromOrder() {
+    Map result = success()
+    GenericValue returnItemTypeMapping
+    
+    if (!security.hasEntityPermission("ORDERMGR", "_CREATE", parameters.userLogin)
+            && !parameters.fromPartyId == userLogin.partyId) {
+        return informError("OrderSecurityErrorToRunQuickReturnFromOrder")
+    }
+    
+    // get primary information from the order header
+    GenericValue orderHeader = from("OrderHeader").where(orderId: parameters.orderId).queryOne()
+    String returnHeaderTypeId = parameters.returnHeaderTypeId
+    String roleTypeId = "CUSTOMER_RETURN" == returnHeaderTypeId ? "BILL_TO_CUSTOMER" : "BILL_FROM_VENDOR"
+
+    // find the bill to customer; for return's fromPartyId
+    GenericValue orderRole = from("OrderRole").where(orderId: orderHeader.orderId, roleTypeId: roleTypeId).queryFirst()
+    // create the return header
+    // changed from minilang: used createHeaderCtx instead of updateHeader on neesInventoryReceive
+    Map createHeaderCtx = [destinationFacilityId: orderHeader.originFacilityId,
+                           needsInventoryReceive: "Y",
+                           returnHeaderTypeId: returnHeaderTypeId]
+    // get the return to party for customer return and return from party for vendor return from the product store
+    GenericValue productStore = delegator.getRelatedOne("ProductStore", orderHeader, false)
+    if ("CUSTOMER_RETURN" == returnHeaderTypeId) {
+        createHeaderCtx.fromPartyId = orderRole.partyId
+        createHeaderCtx.toPartyId = productStore.payToPartyId
+        if (!createHeaderCtx.destinationFacilityId) {
+            createHeaderCtx.destinationFacilityId = productStore.inventoryFacilityId
+        }
+    } else {
+        createHeaderCtx.fromPartyId = productStore.paytoPartyId
+        createHeaderCtx.toPartyId = orderRole.partyId
+    }
+    // copy over the currency of the order to the currency of the return
+    createHeaderCtx.currencyUomId = orderHeader.currencyUom
+    Map serviceResult = run service: "createReturnHeader", with: createHeaderCtx
+    String returnId = serviceResult.returnId
+    // get the available to return order items
+    List orderItems = from("OrderItem").where(orderId: orderHeader.orderId, statusId: "ITEM_COMPLETED").queryList()
+    
+    if (!parameters.returnReasonId) {
+        parameters.returnReasonId = "RTN_NOT_WANT"
+    }
+    if (!parameters.returnTypeId) {
+        parameters.returnTypeId = "RTN_REFUND"
+    }
+    // create the return items
+    for (GenericValue orderItem : orderItems) {
+        Map newItemCtx = [returnId: returnId,
+                          returnReasonId: parameters.returnReasonId,
+                          returnTypeId: parameters.returnTypeId]
+        if (orderItem.productId) {
+            newItemCtx.productId = orderItem.productId
+        }
+        newItemCtx.orderId = orderItem.orderId
+        newItemCtx.orderItemSeqId = orderItem.orderItemSeqId
+        newItemCtx.description = orderItem.itemDescription
+        
+        // get the returnable price and quantity
+        Map serviceResultQuantity = run service: "getReturnableQuantity", with: [orderItem: orderItem]
+        newItemCtx.returnQuantity = serviceResultQuantity.returnableQuantity
+        newItemCtx.returnPrice = serviceResultQuantity.returnablePrice
+        
+        // get the matching return item type from the order item type
+        String orderItemTypeId = orderItem.orderItemTypeId
+        if ("PRODUCT_ORDER_ITEM" == orderItemTypeId) {
+            // Check if orderItemTypeId equals PRODUCT_ORDER_ITEM,
+            // if so, use ProductType and ReturnItemTypeMap to get ReturnItemType
+            String productTypeId = from("Product")
+                    .where(productId: orderItem.productId)
+                    .cache()
+                    .getFieldList("productTypeId")
+            returnItemTypeMapping = from("ReturnItemTypeMap")
+                    .where(returnItemMapKey: productTypeId, returnHeaderTypeId: returnHeaderTypeId)
+                    .queryOne()
+        } else {
+            // if not, try the ReturnItemTypeMap, but this may not actually work, so log a warning
+            logWarning("Trying to find returnItemtype from ReturnItemTypeMap with orderItemtypeId" +
+                    " [${orderItem.orderItemTypeId} for order item [${orderItem}]")
+            returnItemTypeMapping = from("ReturnItemTypeMap")
+                    .where(returnItemMapKey: orderItemTypeId, returnHeaderTypeId: returnHeaderTypeId)
+                    .queryOne()
+        }
+        if (!returnItemTypeMapping.returnItemTypeId) {
+            return informError("OrderReturnItemTypeOrderItemNoMatching")
+        } else {
+            newItemCtx.returnItemTypeId = returnItemTypeMapping.returnItemTypeId
+        }
+        // create the return item
+        if (newItemCtx.orderAdjustmentId) {
+            logInfo("Found unexpected orderAdjustment: ${newItemCtx.orderAdjustmentId}")
+            newItemCtx.orderAdjustmentId = null
+        }
+        if (newItemCtx.returnQuantity > (BigDecimal) 0) {
+            // otherwise, items which have been fully returned would still get passed in and then come back with an error
+            run service:"createReturnItem", with: newItemCtx
+        } else {
+            logInfo("This return item is not going to be created because its returnQuantity is zero: ${newItemCtx}")
+        }
+    }
+    
+    // create a return adjustment for all order adjustments not attached to a particular orderItem (orderItemSeqId = "_NA_")
+    List orderAdjustments = from("OrderAdjustment")
+            .where(orderId: orderHeader.orderId, orderItemSeqId: "_NA_")
+            .queryList()
+    for (GenericValue orderAdjustment : orderAdjustments) {
+        Map returnAdjCtx = [:]
+        returnAdjCtx.returnId = returnId
+        // filter out orderAdjustment that have been returned
+        if (from("ReturnAdjustment").where(orderAdjustmentId: orderAdjustment.orderAdjustmentId).queryCount() == 0) {
+            logInfo("Create new return adjustment: " + returnAdjCtx)
+            run service:"createReturnAdjustment", with: returnAdjCtx
+        }
+    }
+    // very important: if countNewReturnItemx is not set,
+    // getOrderAvailableReturnedTotal would not count the return items we just created
+    Map orderAvailableCtx = [orderId: orderHeader.orderId, countNewReturnItemx: true]
+    Map serviceResultART = run service:"getOrderAvailableReturnedTotal", with: orderAvailableCtx
+    BigDecimal availableReturnTotal = serviceResult.availableReturnTotal
+    BigDecimal returnTotal = serviceResultART.returnTotal
+    BigDecimal orderTotal = serviceResultART.orderTotal
+    logInfo("OrderTotal [${orderTotal}] - ReturnTotal [${returnTotal}] = available Return Total [${}]")
+    
+    // create a manual balance adjustment based on the difference between order total and return total
+    if (availableReturnTotal != (BigDecimal) 0) {
+        logWarning("Creating a balance adjustment of [" + availableReturnTotal + "] for return [" + returnId + "]")
+        
+        // create the balance adjustment return item
+        run service:"createReturnAdjustment", with: [returnId: returnId,
+                                                     returnAdjustmentTypeId: "RET_MAN_ADJ",
+                                                     returnItemSeqId: "_NA_",
+                                                     description: "Balance Adjustment",
+                                                     amount: availableReturnTotal]
+    }
+    // update the header status
+    Map updateHeaderCtx = [returnId: returnId]
+    updateHeaderCtx.statusId = "CUSTOMER_RETURN" == returnHeaderTypeId ? "RETURN_ACCEPTED" : "SUP_RETURN_ACCEPTED"
+    run service:"updateReturnHeader", with: updateHeaderCtx
+    
+    if ("CUSTOMER_RETURN" == returnHeaderTypeId) {
+        // auto-receive this return if we passed in the flag
+        if (parameters.receiveReturn) {
+            run service:"quickReceiveReturn", with: [returnId: returnId]
+        } else {
+            // update the header status
+            logInfo("Receive flag not set; will handle receiving on entity-sync")
+        }
+    }
+    result.returnId = returnId
+    return result
+}
+
+/**
+ * If returnId is null, create a return; then create Return Item or Adjustment based on the parameters passed in
+ * @return
+ */
+def createReturnAndItemOrAdjustment() {
+    Map result = success()
+    if (!parameters.returnId) {
+        Map serviceResultcRH = run service:"createReturnHeader", with: parameters
+        if (!ServiceUtil.isSuccess(serviceResultcRH)) {
+            return serviceResultcRH
+        }
+        parameters.returnId = serviceResultcRH.returnId
+        result.returnId = serviceResultcRH.returnId
+    }
+    Map serviceResult = run service:"createReturnItemOrAdjustment", with: parameters
+    if (!ServiceUtil.isSuccess(serviceResult)) {
+        return serviceResult
+    }
+    result.returnAdjustmentId = serviceResult.returnAdjustmentId
+    result.returnItemSeqId = serviceResult.returnItemSeqId
+    return result
+}
+
+/**
+ * Update a ReturnItems
+ * @return
+ */
+def cancelReturnItems() {
+    List returnItems = from("ReturnItem").where(returnId: parameters.returnId).distinct().queryList()
+    for (GenericValue returnItem : returnItems) {
+        run service:"updateReturnItem", with: [returnId: parameters.returnId,
+                                               returnItemSeqId: returnItem.returnItemSeqId,
+                                               statusId: "RETURN_CANCELLED"]
+    }
+    return success()
+}
+
+/**
+ * Cancel the associated OrderItems of the replacement order, if any.
+ * @return
+ */
+def cancelReplacementOrderItems() {
+    GenericValue returnItem = from("ReturnItems").where(parameters).queryOne()
+    if ("RTN_REPLACE" == returnItem.returnTypeId
+            || "RTN_CSREPLACE" == returnItem.returnTypeId
+            || "RTN_REPAIR_REPLACE" == returnItem.returnTypeId) {
+        // get the returned order item
+        GenericValue orderItem = delegator.getRelatedOne("OrderItem", returnItem, false)
+        // get the order items of the replacement order associated to the returned item
+        Map oiaMap = [orderItemAssocTypeId: "REPLACEMENT"]
+        List replacementOrderItems = delegator.getRelated("FromOrderItemAssoc", oiaMap, null, orderItem, false)
+        for (GenericValue replacementOrderItem : replacementOrderItems) {
+            run service:"cancelOrderItem", with: [orderId: replacementOrderItem.toOrderId,
+                                                  orderItemSeqId: replacementOrderItem.toOrderItemSeqId]
+        }
+    }
+    return success()
+}
+
+/**
+ * Process the replacements in a wait return
+ * @return
+ */
+def processWaitReplacementReturn() {
+    run service: "processReplacementReturn", with: [returnId: parameters.returnId,
+                                                    returnTypeId: "RTN_REPLACE"]
+    return success()
+}
+
+/**
+ * Process the replacements in a cross-ship return
+ * @return
+ */
+def processCrossShipReplacementReturn() {
+    run service:"processReplacementReturn", with: [returnId: parameters.returnId,
+                                                   returnTypeId: "RTN_CSREPLACE"]
+    return success()
+}
+
+/**
+ * Process the replacements in a repair return
+ * @return
+ */
+def processRepairReplacementReturn() {
+    run service:"processReplacementReturn", with: [returnId: parameters.returnId,
+                                                   returnTypeId: "RTN_REPAIR_REPLACE"]
+    return success()
+}
+
+/**
+ * Process the replacements in a wait reserved return when the return is accepted and then received
+ * @return
+ */
+def processWaitReplacementReservedReturn() {
+    GenericValue returnHeader = from("ReturnHeader").where(parameters).queryOne()
+    if ("RETURN_ACCEPTED" == returnHeader.statusId) {
+        run service:"processReplacementReturn", with: [returnId: parameters.returnId,
+                                                       returnTypeId: "RTN_WAIT_REPLACE_RES"]
+    }
+    if ("RETURN_RECEIVED" == returnHeader.statusId) {
+        GenericValue returnItem = from("ReturnItem")
+                .where(returnId: returnHeader.returnId,
+                        returnTypeId: "RTN_WAIT_REPLACE_RES")
+                .queryFirst()
+        if (returnItem) {
+            // Get the replacement order and update its status to Approved
+            GenericValue returnItemResponse = delegator.getRelatedOne("ReturnItemResponse", returnItem, false)
+            GenericValue orderHeader = from("OrderHeader").where(orderId: returnItemResponse.replacementOrderId).queryOne()
+            if (orderHeader) {
+                if ("ORDER_HOLD" == orderHeader.statusId) {
+                    run service:"changeOrderStatus", with: [statusId: "ORDER_APPROVED",
+                                                            orderId: returnItemResponse.replacementOrderId,
+                                                            setItemStatus: "Y"]
+                }
+                if ("ORDER_CANCELLED" == orderHeader.statusId) {
+                    run service:"processReplacementReturn", with: [returnId: parameters.returnId,
+                                                                   returnTypeId: "RTN_WAIT_REPLACE_RES"]
+                }
+            }
+        }
+    }
+    return success()
+}
+
+/**
+ * Process the replacements in a immediate return
+ * @return
+ */
+def processReplaceImmediatelyReturn() {
+    run service: "processReplacementReturn", with: [returnId: parameters.returnId,
+                                                    returnTypeId: "RTN_REPLACE_IMMEDIAT"]
+    return success()
+}
+
+/**
+ * Process the refund in a return
+ * @return
+ */
+def processRefundOnlyReturn() {
+    run service: "processRefundReturn", with: [returnId: parameters.returnId,
+                                               returnTypeId: "RTN_REFUND"]
+    return success()
+}
+
+/**
+ * Process the Immediate refund in a return
+ * @return
+ */
+def processRefundImmediatelyReturn() {
+    run service:"processRefundReturn", with: [returnId: parameters.returnId,
+                                              returnTypeId: "RTN_REFUND_IMMEDIATE"]
+    return success()
+}
+
+/**
+ * Get the return status associated with customer vs. vendor return
+ * @return
+ */
+def getStatusItemsForReturn() {
+    Map result = success()
+    if ("CUSTOMER_RETURN" == parameters.returnHeaderTypeId) {
+        List statusItems = from("StatusItem").where(statusTypeId: "ORDER_RETURN_STTS").queryList()
+        result.statusItems = statusItems
+    } else {
+        List statusItems = from("StatusItem").where(statusTypeId: "PORDER_RETURN_STTS").queryList()
+        result.statusItems = statusItems
+    }
+    return result
+}
+
+/**
+ * Associate exchange order with original order in OrderItemAssoc entity
+ * @return
+ */
+def createExchangeOrderAssoc() {
+    List returnItems = from("ReturnItem")
+            .where(orderId: parameters.originOrderId,
+                    returnTypeId: "RTN_REFUND")
+            .queryList()
+    Long returnItemSize = returnItems.size()
+    List orderItems = from("OrderItem").where(orderId: parameters.orderId).queryList()
+    Long orderItemSize = orderItems.size()
+    if (returnItemSize > orderItemSize) {
+        Long returnItemCounter = (Long) 1
+        for (GenericValue returnItem : returnItems) {
+            Map orderItemAssocMap = [orderId: parameters.originOrderId, orderItemSeqId: returnItem.orderItemSeqId]
+            Long orderItemCounter = (Long) 1
+            for (GenericValue orderItem : orderItems) {
+                if (returnItemCounter == orderItemCounter) {
+                    orderItemAssocMap.toOrderId = parameters.orderId
+                    orderItemAssocMap.toOrderItemSeqId = orderItem.orderItemSeqId
+                } else if (returnItemCounter > orderItemSize) {
+                    orderItemAssocMap.toOrderId = parameters.orderId
+                    orderItemAssocMap.toOrderItemSeqId = orderItem.orderItemSeqId
+                }
+                orderItemCounter++
+            }
+            orderItemAssocMap.shipGroupSeqId = "_NA_"
+            orderItemAssocMap.toShipGroupSeqId = "_NA_"
+            orderItemAssocMap.orderItemAssocTypeId = "EXCHANGE"
+            GenericValue orderItemAssoc = makeValue("OrderItemAssoc")
+            orderItemAssoc.setPKFields(orderItemAssocMap)
+            GenericValue orderItemAssocValue = from("OrderItemAssoc").where(orderItemAssoc).queryOne()
+            if (!orderItemAssocValue) {
+                orderItemAssoc.create()
+                orderItemAssoc = null
+            }
+            returnItemCounter++
+        }
+    } else {
+        Long orderItemCounter = (Long) 1
+        for (GenericValue orderItem : orderItems) {
+            Map orderItemAssocMap = [toOrderId: parameters.orderId, toOrderItemSeqId: orderItem.orderItemSeqId]
+            Long returnItemCounter = (Long) 1
+            for (GenericValue returnItem : returnItems) {
+                if (orderItemCounter == returnItemCounter) {
+                    orderItemAssocMap.orderId = parameters.originOrderId
+                    orderItemAssocMap.orderItemSeqId = returnItem.orderItemSeqId
+                } else if (orderItemCounter > returnItemSize) {
+                    orderItemAssocMap.orderId = parameters.originOrderId
+                    orderItemAssocMap.orderItemSeqId = returnItem.orderItemSeqId
+                }
+                returnItemCounter++
+            }
+            orderItemAssocMap.shipGroupSeqId = "_NA_"
+            orderItemAssocMap.toShipGroupSeqId = "_NA_"
+            orderItemAssocMap.orderItemAssocTypeId = "EXCHANGE"
+            GenericValue orderItemAssoc = makeValue("OrderItemAsscoc")
+            orderItemAssoc.setPKFields(orderItemAssocMap)
+            GenericValue orderItemAssocValue = from("OrderItemAssoc").where(orderItemAssoc).queryOne()
+            if (!orderItemAssocValue) {
+                orderItemAssoc.create()
+                orderItemAssocMap = null
+            }
+            orderItemCounter++
+        }
+    }
+    return success()
+}
+
+/**
+ * When one or more product is received directly through receive inventory or
+ * refund return then add these product(s) back to category,
+ * if they does not have any active category
+ * @return
+ */
+def addProductsBackToCategory() {
+    if (parameters.inventoryItemId) {
+        GenericValue inventoryItem = from("InventoryItem").where(parameters).queryOne()
+        GenericValue product = delegator.getRelatedOne("Product", inventoryItem, false)
+        List productCategoryMembers = delegator.getRelated("ProductCategoryMember",
+                null, ["-thruDate"], product, false)
+        // check whether this product is associated to any category, if not just skip
+        if (productCategoryMembers) {
+            List pcms = EntityUtil.filterByDate(productCategoryMembers)
+            // check if this product is associated to any active category,
+            // if not found then activate the most recent inactive category
+            if (!pcms) {
+                Map pcm = [:]
+                pcm << productCategoryMembers.get(0)
+                pcm.thruDate = null
+                run service:"updateProductToCategory", with: pcm
+            }
+        }
+    } else {
+        if (parameters.returnId) {
+            List returnItems = from("ReturnItem")
+                    .where(returnId: parameters.returnId,
+                            returnTypeId: "RTN_REFUND")
+                    .queryList()
+            if (returnItems) {
+                for (GenericValue returnItem : returnItems) {
+                    GenericValue product = delegator.getRelatedOne("Product", returnItem, false)
+                    List productCategoryMembers = delegator.getRelated("ProductCategoryMember",
+                            null, ["-thruDate"], product, false)
+                    // check whether this product is associated to any category, if not just skip
+                    if (productCategoryMembers) {
+                        List pcms = EntityUtil.filterByDate(productCategoryMembers)
+                        // check if this product is associated to any active category,
+                        // if not found then activate the most recent inactive category
+                        if (!pcms) {
+                            Map pcm = [:]
+                            pcm << productCategoryMembers.get(0)
+                            pcm.thruDate = null
+                            run service:"updateProductToCategory", with: pcm
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return success()
+}
+
+/**
+ * Create ReturnHeader and ReturnItem Status
+ * @return
+ */
+def createReturnStatus() {
+    GenericValue newEntity = makeValue("ReturnStatus")
+    if (!parameters.returnItemSeqId) {
+        GenericValue returnHeader = from("ReturnHeader").where(parameters).queryOne()
+        newEntity.statusId = returnHeader.statusId
+    } else {
+        GenericValue returnItem = from("ReturnItem").where(parameters).queryOne()
+        newEntity.returnItemSeqId = returnItem.returnItemSeqId
+        newEntity.statusId = returnItem.statusId
+    }
+    newEntity.returnStatusId = delegator.getNextSeqId("ReturnStatus")
+    newEntity.returnId = parameters.returnId
+    newEntity.changeByUserLoginId = userLogin.userLoginId
+    newEntity.statusDatetime = UtilDateTime.nowTimestamp()
+    newEntity.create()
+    return success()
+}
+
+/**
+ * Update ReturnContactMech
+ * @return
+ */
+def updateReturnContactMech() {
+    GenericValue returnContactMechMap = makeValue("ReturnContactMech")
+    returnContactMechMap.setPKFields(parameters)
+    GenericValue returnHeader = from("ReturnHeader").where(parameters).queryOne()
+    Map createReturnContactMechMap = [returnId: parameters.returnId,
+                                      contactMechPurposeTypeId: parameters.contactMechPurposeTypeId,
+                                      contactMechId: parameters.contactMechId]
+    List returnContactMechList = from("ReturnContactMech").where(createReturnContactMechMap).queryList()
+    // If returnContactMechList value is null then create new entry in ReturnContactMech entity
+    if (!returnContactMechList) {
+        if ("SHIPPING_LOCATION" == parameters.contactMechPurposeTypeId) {
+            returnHeader.originContactMechId = createReturnContactMechMap.contactMechId
+            returnHeader.store()
+        }
+        run service:"createReturnContactMech", with: createReturnContactMechMap
+    }
+    returnContactMechMap.store()
+    return success()
+}
+
+/**
+ * Create the return item for rental (which items has product type is ASSET_USAGE_OUT_IN)
+ * @return
+ */
+def createReturnItemForRental() {
+    Map result = success()
+    GenericValue orderHeader = from("OrderHeader").where(orderId: parameters.orderId).queryOne()
+    
+    if ("SALES_ORDER" == orderHeader.orderTypeId) {
+        GenericValue orderRole = from("OrderRole")
+                .where(orderId: orderHeader.orderId,
+                        roleTypeId: "BILL_TO_CUSTOMER")
+                .queryFirst()
+        GenericValue productStore = delegator.getRelatedOne("ProductStore", orderHeader, false)
+        
+        Map createReturnCtx = [:]
+        if (productStore?.inventoryFacilityId) {
+            createReturnCtx.destinationFacilityId = productStore.inventoryFacilityId
+        }
+        
+        /*
+         * changed from minilang since there seems to be no purpose
+         * 
+         * if (productStore?.reqReturnInventoryReceive) {
+         *     updateHeaderCtx.needsInventoryReceive = productStore.reqReturnInventoryReceive
+         * } else {
+         *     updateHeaderCtx.needsInventoryReceive = "N"
+         * }
+         */
+        
+        createReturnCtx.orderId = orderHeader.orderId
+        createReturnCtx.currencyUomId = orderHeader.currencyUom
+        createReturnCtx.fromPartyId = orderRole.partyId
+        createReturnCtx.toPartyId = productStore.payToPartyId
+        createReturnCtx.returnHeaderTypeId = "CUSTOMER_RETURN"
+        createReturnCtx.returnReasonId = "RTN_NORMAL_RETURN"
+        createReturnCtx.returnTypeId = "RTN_RENTAL"
+        createReturnCtx.returnItemTypeId = "RET_FDPROD_ITEM"
+        createReturnCtx.expectedItemStatus = "INV_RETURNED"
+        createReturnCtx.returnPrice = (BigDecimal) 0
+        
+        List orderItems = from("OrderItemAndProduct")
+                .where(orderId: orderHeader.orderId,
+                        statusId: "ITEM_COMPLETED",
+                        productTypeId: "ASSET_USAGE_OUT_IN")
+                .queryList()
+        for (GenericValue orderItem : orderItems) {
+            createReturnCtx.productId = orderItem.productId
+            createReturnCtx.orderItemSeqId = orderItem.orderItemSeqId
+            createReturnCtx.description = orderItem.itemDescription
+            createReturnCtx.returnQuantity = orderItem.quantity
+            Map serviceResult = run service:"createReturnAndItemOrAdjustment", with: createReturnCtx
+            String returnId = serviceResult.returnId
+            if (returnId) {
+                createReturnCtx.returnId = returnId
+                // changed from minilang: added returnId to result since it's a required outgoing parameter
+                result.returnId = returnId
+            }
+        }
+    }
+    return result
+}
+
+def private informError(String label) {
+    String errorMessage = UtilProperties.getMessage("OrderErrorUiLabels", label, parameters.locale)
+    logError(errorMessage)
+    return error(errorMessage)
+}
diff --git a/applications/order/minilang/order/OrderReturnServices.xml b/applications/order/minilang/order/OrderReturnServices.xml
deleted file mode 100644
index 1786c0d..0000000
--- a/applications/order/minilang/order/OrderReturnServices.xml
+++ /dev/null
@@ -1,1186 +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="createReturnHeader" short-description="Create a ReturnHeader">
-        <now-timestamp field="nowTimestamp"/>
-
-        <if>
-            <condition>
-                <and>
-                    <not><if-has-permission permission="ORDERMGR" action="_CREATE"/></not>
-                    <not><if-compare-field field="userLogin.partyId" to-field="parameters.fromPartyId" operator="equals"/></not>
-                </and>
-            </condition>
-            <then>
-                <add-error><fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunCreateReturnHeader"/></add-error>
-            </then>
-        </if>
-        <set field="returnHeaderTypeId" from-field="parameters.returnHeaderTypeId"/>
-        <if-empty field="parameters.toPartyId">
-            <!-- no toPartyId was specified. use destination facility to determine the party of the return -->
-            <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-                <if-not-empty field="parameters.destinationFacilityId">
-                    <entity-one entity-name="Facility" value-field="destinationFacility" auto-field-map="false">
-                        <field-map field-name="facilityId" from-field="parameters.destinationFacilityId"/>
-                    </entity-one>
-                    <set from-field="destinationFacility.ownerPartyId" field="parameters.toPartyId"/>
-                </if-not-empty>
-            </if-compare>
-        <else>
-            <!-- make sure that the party to return to is an INTERNAL_ORGANIZATIO for customer return and SUPPLIER for vendor return else stop -->
-            <if-compare field="returnHeaderTypeId" operator="contains" value="CUSTOMER_">
-                <entity-one entity-name="PartyRole" value-field="partyRole" use-cache="true" auto-field-map="false">
-                    <field-map field-name="partyId" from-field="parameters.toPartyId"/>
-                    <field-map field-name="roleTypeId" value="INTERNAL_ORGANIZATIO"/>
-                </entity-one>
-                <if-empty field="partyRole">
-                    <add-error>
-                        <fail-property resource="OrderErrorUiLabels" property="OrderReturnRequestPartyRoleInternalOrg"/>
-                    </add-error>
-                </if-empty>
-            <else>
-                <entity-one entity-name="PartyRole" value-field="partyRole" use-cache="true" auto-field-map="false">
-                    <field-map field-name="partyId" from-field="parameters.toPartyId"/>
-                    <field-map field-name="roleTypeId" value="SUPPLIER"/>
-                </entity-one>
-                <if-empty field="partyRole">
-                    <add-error>
-                        <fail-property resource="OrderErrorUiLabels" property="OrderReturnRequestPartyRoleSupplier"/>
-                    </add-error>
-                </if-empty>
-            </else>
-            </if-compare>
-         </else>
-        </if-empty>
-        <if-not-empty field="parameters.paymentMethodId">
-            <entity-one entity-name="PaymentMethod" value-field="paymentMethod" use-cache="true" auto-field-map="false">
-                <field-map field-name="paymentMethodId" from-field="parameters.paymentMethodId"/>
-            </entity-one>
-            <if-empty field="paymentMethod">
-                <add-error>
-                    <fail-property resource="OrderErrorUiLabels" property="OrderReturnRequestPaymentMethodId"/>
-                </add-error>
-            </if-empty>
-        </if-not-empty>
-        <check-errors/>
-
-        <!-- check the needs (auto) inventory receive flag (default to N, meaning that return won't automatically be considered Received when Accepted) -->
-        <if-empty field="parameters.needsInventoryReceive">
-            <set field="parameters.needsInventoryReceive" value="N"/>
-        </if-empty>
-
-        <make-value entity-name="ReturnHeader" value-field="newEntity"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-
-        <!-- If PartyAcctgPreference.useInvoiceIdForReturns is Y, get the ID from the getNextInvoiceId service -->
-        <set field="partyAccountingPreferencesCallMap.organizationPartyId" from-field="parameters.toPartyId"/>
-        <set field="systemMap.userLoginId" value="system"/>
-        <find-by-primary-key  entity-name="UserLogin" map="systemMap" value-field="systemLogin"/>
-        <set field="partyAccountingPreferencesCallMap.userLogin" from-field="systemLogin"/>
-        <call-service service-name="getPartyAccountingPreferences" in-map-name="partyAccountingPreferencesCallMap">
-             <result-to-field result-name="partyAccountingPreference" field="partyAcctgPreference"/>
-        </call-service>
-        <if-compare field="partyAcctgPreference.useInvoiceIdForReturns" operator="equals" value="Y">
-            <set field="getNextInvoiceIdMap.partyId" from-field="parameters.toPartyId"/>
-            <call-service service-name="getNextInvoiceId" in-map-name="getNextInvoiceIdMap">
-                <result-to-field result-name="invoiceId" field="newEntity.returnId"/>
-            </call-service>
-
-            <else>
-                <sequenced-id sequence-name="ReturnHeader" field="newEntity.returnId"/>
-            </else>
-        </if-compare>
-        <field-to-result field="newEntity.returnId" result-name="returnId"/>
-
-        <if>
-            <condition>
-                <not><if-has-permission permission="ORDERMGR" action="_CREATE"/></not>
-            </condition>
-            <then>
-                <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-                    <set field="newEntity.statusId" value="RETURN_REQUESTED"/>
-                <else>
-                    <set field="newEntity.statusId" value="SUP_RETURN_REQUESTED"/>
-                </else>
-                </if-compare>
-                <set from-field="nowTimestamp" field="newEntity.entryDate"/>
-            </then>
-        </if>
-
-        <if-empty field="newEntity.entryDate">
-            <set from-field="nowTimestamp" field="newEntity.entryDate"/>
-        </if-empty>
-
-        <if-empty field="newEntity.statusId">
-            <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-                <set field="newEntity.statusId" value="RETURN_REQUESTED"/>
-            <else>
-                <set field="newEntity.statusId" value="SUP_RETURN_REQUESTED"/>
-            </else>
-            </if-compare>
-        </if-empty>
-        <set field="newEntity.createdBy" from-field="userLogin.userLoginId"/>
-
-        <create-value value-field="newEntity"/>
-        <set field="responseMessage" value="Return Request #${newEntity.returnId} was created successfully."/>
-        <field-to-result field="responseMessage" result-name="successMessage"/>
-    </simple-method>
-    <simple-method method-name="updateReturnHeader" short-description="Update a ReturnHeader">
-        <entity-one entity-name="ReturnHeader" value-field="returnHeader"/>
-
-        <!-- test the total return amount vs the total order amount -->
-        <if-compare field="parameters.statusId" value="RETURN_ACCEPTED" operator="equals">
-            <!-- get the list of ReturnItems.  Note: return may be associated with many different orders -->
-            <entity-condition entity-name="ReturnItem" list="returnItems" distinct="true">
-                <condition-expr field-name="returnId" from-field="returnHeader.returnId"/>
-            </entity-condition>
-
-            <!-- this block is for debugging and can be removed later -->
-            <!--
-            <log level="verbose" message="Items and adjustments for return ${returnHeader.returnId}"/>
-            <entity-condition entity-name="ReturnAdjustment" list="returnAdjustments" distinct="true">
-                <condition-expr field-name="returnId" operator="equals" from-field="returnHeader.returnId"/>
-            </entity-condition>
-            <iterate list="returnItems" entry="returnItem">
-                <log level="verbose" message="item: ${returnItem.returnItemSeqId} ${returnItem.returnItemTypeId} [${returnItem.description}] ${returnItem.productId} ${returnItem.returnQuantity} ${returnItem.returnPrice}"/>
-            </iterate>
-            <iterate list="returnAdjustments" entry="returnAdjustment">
-                <log level="verbose" message="adjustment: ${returnAdjustment.returnItemSeqId} ${returnAdjustment.returnAdjustmentTypeId} [${returnAdjustment.description}] ${returnAdjustment.amount}"/>
-            </iterate>
-            -->
-            <!-- end debugging block -->
-
-            <!-- this is used to make sure we don't return a negative amount -->
-            <calculate field="returnTotalAmount"><number value="0.0"/></calculate>
-
-            <!-- check them all to make sure that the return total does not exceed order total.  -->
-            <iterate list="returnItems" entry="returnItem">
-              <!-- check, for cross-ship returns, if a payment method is set to guarantee the cross-shipped item(s)..  -->
-              <if>
-                  <condition>
-                      <and>
-                          <if-empty field="returnHeader.paymentMethodId"/>
-                          <if-empty field="parameters.paymentMethodId"/><!-- because we haven't done the set-nonpk-fields yet, check this too -->
-                          <or>
-                              <if-compare field="returnItem.returnTypeId" operator="equals" value="RTN_CSREPLACE"/>
-                              <if-compare field="returnItem.returnTypeId" operator="equals" value="RTN_REPAIR_REPLACE"/>
-                          </or>
-                      </and>
-                  </condition>
-                  <then>
-                      <add-error><fail-property resource="OrderErrorUiLabels" property="OrderReturnPaymentMethodNeededForThisTypeOfReturn"/></add-error>
-                  </then>
-              </if>
-              <check-errors/>
-               <!-- tally up the return total amount -->
-               <calculate field="returnTotalAmount">
-                   <calcop operator="add" field="returnTotalAmount">
-                       <calcop operator="multiply">
-                           <calcop operator="get" field="returnItem.returnPrice"/>
-                           <calcop operator="get" field="returnItem.returnQuantity"/>
-                        </calcop>
-                   </calcop>
-                </calculate>
-
-                <!-- compare return vs order total -->
-                <if-not-empty field="returnItem.orderId">
-                    <set field="returnTotalCtx.orderId" from-field="returnItem.orderId"/>
-                    <!-- no adjustment needed: adjustment is passed in to calculate the effect of an additional item on return total.  -->
-                    <calculate field="returnTotalCtx.adjustment" type="BigDecimal"><number value="0.0"/></calculate>
-                    <call-service service-name="getOrderAvailableReturnedTotal" in-map-name="returnTotalCtx">
-                        <result-to-field result-name="availableReturnTotal" field="availableReturnTotal"/>
-                        <result-to-field result-name="returnTotal" field="returnTotal"/>
-                        <result-to-field result-name="orderTotal" field="orderTotal"/>
-                    </call-service>
-                    <log level="info" message="Available amount for return on order #${returnItem.orderId} is [${availableReturnTotal}] (orderTotal = [${orderTotal}] - returnTotal = [${returnTotal}]"/>
-
-                    <if-compare field="availableReturnTotal" operator="less" value="-0.01" type="BigDecimal">
-                        <add-error><fail-property resource="OrderErrorUiLabels" property="OrderReturnPriceCannotExceedTheOrderTotal"/></add-error>
-                    </if-compare>
-                    <check-errors/>
-                    <else>
-                        <log level="info" message="Not an order based returnItem; unable to check valid amounts!"/>
-                    </else>
-                </if-not-empty>
-            </iterate>
-            <!-- Checking that the Status change is Valid or Not-->
-            <if>
-                <condition>
-                    <and>
-                        <not><if-empty field="parameters.statusId"></if-empty></not>
-                        <if-compare-field operator="not-equals" field="parameters.statusId" to-field="returnHeader.statusId"/>
-                    </and>
-                </condition>
-                <then>
-                    <set field="statusIdTo" from-field="parameters.statusId"/>
-                    <set field="statusId" from-field="returnHeader.statusId"/>
-                    <entity-one entity-name="StatusValidChange" value-field="statusValidChange"/>
-                    <if-empty field="statusValidChange">
-                        <add-error><fail-property resource="OrderErrorUiLabels" property="OrderErrorReturnHeaderItemStatusNotChangedIsNotAValidChange"/></add-error>
-                    </if-empty>
-                    <check-errors/>
-                </then>
-            </if>
-            <entity-and entity-name="ReturnAdjustment" list="returnAdjustments">
-                <field-map field-name="returnId" from-field="returnHeader.returnId"/>
-            </entity-and>
-            <iterate list="returnAdjustments" entry="returnAdjustment">
-                <calculate field="returnTotalAmount">
-                    <calcop operator="add" field="returnTotalAmount">
-                        <calcop operator="get" field="returnAdjustment.amount"/>
-                    </calcop>
-                </calculate>
-            </iterate>
-            <if-compare field="returnTotalAmount" operator="less" value="0" type="BigDecimal">
-                <add-error><fail-property resource="OrderErrorUiLabels" property="OrderReturnTotalCannotLessThanZero"/></add-error>
-            </if-compare>
-            <check-errors/>
-        </if-compare>
-
-        <field-to-result field="returnHeader.statusId" result-name="oldStatusId"/>
-        <set-nonpk-fields map="parameters" value-field="returnHeader"/>
-        <store-value value-field="returnHeader"/>
-    </simple-method>
-
-    <simple-method method-name="createReturnItem" short-description="Create Return Item">
-
-        <set field="lookupPKMap.returnId" from-field="parameters.returnId"/>
-        <find-by-primary-key entity-name="ReturnHeader" map="lookupPKMap" value-field="returnHeader"/>
-
-        <if>
-            <condition>
-                <and>
-                    <not>
-                        <if-has-permission permission="ORDERMGR" action="_CREATE"/>
-                    </not>
-                    <not>
-                        <if-compare-field field="userLogin.partyId" to-field="returnHeader.fromPartyId" operator="equals"/>
-                    </not>
-                </and>
-            </condition>
-            <then>
-                <add-error>
-                    <fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunCreateReturnItem"/>
-                </add-error>
-            </then>
-        </if>
-        <check-errors/>
-
-        <if-empty field="parameters.returnItemTypeId">
-            <add-error>
-                <fail-property resource="OrderErrorUiLabels" property="OrderReturnItemTypeIsNotDefined"/>
-            </add-error>
-            <check-errors/>
-        </if-empty>
-
-        <if>
-            <condition>
-                <and>
-                    <if-empty field="returnHeader.paymentMethodId"/>
-                    <if-compare field="returnHeader.statusId" operator="equals" value="RETURN_ACCEPTED"/>
-                    <or>
-                        <if-compare field="parameters.returnTypeId" operator="equals" value="RTN_CSREPLACE"/>
-                        <if-compare field="parameters.returnTypeId" operator="equals" value="RTN_REPAIR_REPLACE"/>
-                    </or>
-                </and>
-            </condition>
-            <then>
-                <add-error>
-                    <fail-property resource="OrderErrorUiLabels" property="OrderReturnPaymentMethodNeededForThisTypeOfReturn"/>
-                </add-error>
-            </then>
-        </if>
-        <check-errors/>
-
-        <if-compare field="parameters.returnQuantity" operator="equals" value="0" type="BigDecimal">
-            <add-error>
-                <fail-property resource="OrderErrorUiLabels" property="OrderNoReturnQuantityAvailablePreviousReturnsMayExist"/>
-            </add-error>
-            <check-errors/>
-        </if-compare>
-
-        <!-- setup some default values for protection -->
-        <set field="returnableQuantity" value="0" type="BigDecimal"/>
-        <set field="returnablePrice" value="0" type="BigDecimal"/>
-
-        <!-- if an orderItemSeqId is provided, then find the corresponding orderItem  -->
-        <if-not-empty field="parameters.orderItemSeqId">
-            <make-value entity-name="OrderItem" value-field="itemLookup"/>
-            <set-pk-fields map="parameters" value-field="itemLookup"/>
-            <if-not-empty field="parameters.orderItemSeqId">
-                <find-by-primary-key entity-name="OrderItem" value-field="orderItem" map="itemLookup"/>
-                <log level="info" message="Return item is an OrderItem - ${orderItem.orderItemSeqId}"/>
-            </if-not-empty>
-        </if-not-empty>
-
-        <!-- get the returnableQuantity and returnablePrice:
-            for orderItems, it's found by getReturnableQuantity;
-            for adjustments, either order adjustments or manual adjustments, it's always 1 and based on input parameter -->
-        <if-not-empty field="orderItem">
-            <set field="serviceContext.orderItem" from-field="orderItem"/>
-            <call-service service-name="getReturnableQuantity" in-map-name="serviceContext">
-                <result-to-field result-name="returnableQuantity" field="returnableQuantity"/>
-                <result-to-field result-name="returnablePrice" field="returnablePrice"/>
-            </call-service>
-        </if-not-empty>
-
-        <if-compare field="returnableQuantity" value="0" operator="greater" type="BigDecimal">
-            <!-- the user is only allowed to set a returnPrice if he has ORDERMGR_CREATE privilege, otherwise only the returnablePrice calculated by service is used -->
-            <if>
-                <condition>
-                    <not>
-                        <if-has-permission permission="ORDERMGR" action="_CREATE"/>
-                    </not>
-                </condition>
-                <then>
-                    <set from-field="returnablePrice" field="parameters.returnPrice"/>
-                </then>
-            </if>
-
-            <!-- make sure the returnQuantity is not greater than the returnableQuantity from service or the quantity on the original orderItem -->
-            <if-compare-field field="parameters.returnQuantity" to-field="returnableQuantity" operator="greater" type="BigDecimal">
-                <add-error>
-                    <fail-property resource="OrderErrorUiLabels" property="OrderRequestedReturnQuantityNotAvailablePreviousReturnsMayExist"/>
-                </add-error>
-            </if-compare-field>
-            <if-not-empty field="orderItem">
-                <if-compare-field field="parameters.returnQuantity" to-field="orderItem.quantity" operator="greater" type="BigDecimal">
-                    <add-error>
-                        <fail-property resource="OrderErrorUiLabels" property="OrderReturnQuantityCannotExceedTheOrderedQuantity"/>
-                    </add-error>
-                </if-compare-field>
-            </if-not-empty>
-            <if-compare-field field="parameters.returnPrice" to-field="returnablePrice" operator="greater" type="BigDecimal">
-                <add-error>
-                    <fail-property resource="OrderErrorUiLabels" property="OrderReturnPriceCannotExceedThePurchasePrice"/>
-                </add-error>
-            </if-compare-field>
-            <check-errors/>
-
-            <else>
-                <set from-field="parameters.orderId" field="orderId"/>
-                <set from-field="parameters.orderItemSeqId" field="orderItemSeqId"/>
-                <log level="error" message="Order ${orderId} item ${orderItemSeqId} has been returned in full"/>
-                <add-error>
-                    <fail-property resource="OrderErrorUiLabels" property="OrderIllegalReturnItemTypePassed"/>
-                </add-error>
-                <check-errors/>
-            </else>
-        </if-compare>
-
-        <make-value entity-name="ReturnItem" value-field="newEntity"/>
-        <set from-field="parameters.returnId" field="newEntity.returnId"/>
-        <make-next-seq-id seq-field-name="returnItemSeqId" value-field="newEntity"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <set field="newEntity.statusId" value="RETURN_REQUESTED"/> <!-- default status for new return items -->
-        <field-to-result field="newEntity.returnItemSeqId" result-name="returnItemSeqId"/>
-        <create-value value-field="newEntity"/>
-        <refresh-value value-field="newEntity"/>
-
-        <if>
-            <condition>
-                <or>
-                    <if-empty field="parameters.includeAdjustments"/>
-                    <if-compare field="parameters.includeAdjustments" operator="equals" value="Y"/>
-                </or>
-            </condition>
-            <then>
-                <!-- create return adjustments for all adjustments associated with the order item -->
-                <if-not-empty field="orderItem">
-                    <get-related value-field="orderItem" relation-name="OrderAdjustment" list="orderAdjustments"/>
-                    <iterate list="orderAdjustments" entry="orderAdjustment">
-                        <clear-field field="returnAdjCtx"/>
-                        <set field="returnAdjCtx.returnId" from-field="parameters.returnId"/>
-                        <set field="returnAdjCtx.returnItemSeqId" from-field="newEntity.returnItemSeqId"/>
-                        <set field="returnAdjCtx.returnTypeId" from-field="newEntity.returnTypeId"/>
-                        <set field="returnAdjCtx.orderAdjustmentId" from-field="orderAdjustment.orderAdjustmentId"/>
-                        <call-service service-name="createReturnAdjustment" in-map-name="returnAdjCtx"/>
-                    </iterate>
-                </if-not-empty>
-            </then>
-        </if>
-
-    </simple-method>
-
-    <simple-method method-name="updateReturnItem" short-description="Update Return Item">
-        <set from-field="parameters.returnId" field="lookupPKMap.returnId"/>
-        <set from-field="parameters.returnItemSeqId" field="lookupPKMap.returnItemSeqId"/>
-        <find-by-primary-key entity-name="ReturnItem" map="lookupPKMap" value-field="returnItem"/>
-        <set field="originalReturnPrice" from-field="returnItem.returnPrice"/>
-        <set field="originalReturnQuantity" from-field="returnItem.returnQuantity"/>
-        <field-to-result field="returnItem.statusId" result-name="oldStatusId"/>
-
-        <set-nonpk-fields map="parameters" value-field="returnItem"/>
-        <store-value value-field="returnItem"/>
-        <refresh-value value-field="returnItem"/>
-
-        <!-- now update all return adjustments associated with this return item -->
-        <entity-and entity-name="ReturnAdjustment" list="returnAdjustments">
-            <field-map field-name="returnId" from-field="returnItem.returnId"/>
-            <field-map field-name="returnItemSeqId" from-field="returnItem.returnItemSeqId"/>
-        </entity-and>
-        <iterate list="returnAdjustments" entry="returnAdjustment">
-            <log level="info" message="updating returnAdjustment with Id:[${returnAdjustment.returnAdjustmentId}]"/>
-            <set-service-fields service-name="updateReturnAdjustment" map="returnAdjustment" to-map="ctx"/>
-            <set field="ctx.originalReturnPrice" from-field="originalReturnPrice"/>
-            <set field="ctx.originalReturnQuantity" from-field="originalReturnQuantity"/>
-            <set field="ctx.returnTypeId" from-field="returnItem.returnTypeId"/>
-            <call-service service-name="updateReturnAdjustment" in-map-name="ctx" include-user-login="true"/>
-        </iterate>
-
-    </simple-method>
-    <simple-method method-name="updateReturnItemsStatus" short-description="Update Return Items Status">
-        <set from-field="parameters.returnId" field="lookupPKMap.returnId"/>
-        <find-by-and entity-name="ReturnItem" map="lookupPKMap" list="returnItems"/>
-        <iterate list="returnItems" entry="item">
-            <set field="item.statusId" from-field="parameters.statusId"/>
-            <set-service-fields service-name="updateReturnItem" map="item" to-map="serviceInMap"/>
-            <call-service service-name="updateReturnItem" in-map-name="serviceInMap"/>
-            <clear-field field="serviceInMap"/>
-            <clear-field field="item"/>
-        </iterate>
-    </simple-method>
-    <simple-method method-name="removeReturnItem" short-description="Remove Return Item">
-        <entity-one entity-name="ReturnHeader" value-field="returnHeader"/>
-        <if-compare field="returnHeader.returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-            <if-compare field="returnHeader.statusId" operator="not-equals" type="String" value="RETURN_REQUESTED">
-                <add-error><fail-property resource="OrderErrorUiLabels" property="OrderCannotRemoveItemsOnceReturnIsApproved"/></add-error>
-            </if-compare>
-        <else>
-            <if-compare field="returnHeader.statusId" operator="not-equals" type="String" value="SUP_RETURN_REQUESTED">
-                <add-error><fail-property resource="OrderErrorUiLabels" property="OrderCannotRemoveItemsOnceReturnIsApproved"/></add-error>
-            </if-compare>
-        </else>
-        </if-compare>
-        <check-errors/>
-
-        <set from-field="parameters.returnId" field="lookupPKMap.returnId"/>
-        <set from-field="parameters.returnItemSeqId" field="lookupPKMap.returnItemSeqId"/>
-        <find-by-primary-key entity-name="ReturnItem" map="lookupPKMap" value-field="returnItem"/>
-        <!--remove related  adjustments-->
-        <entity-and entity-name="ReturnAdjustment" list="returnAdjustments">
-            <field-map field-name="returnItemSeqId" from-field="returnItem.returnItemSeqId"/>
-            <field-map field-name="returnId" from-field="returnItem.returnId"/>
-        </entity-and>
-        <iterate list="returnAdjustments" entry="returnAdjustment">
-            <set field="removeCtx.returnAdjustmentId" from-field="returnAdjustment.returnAdjustmentId"/>
-            <call-service service-name="removeReturnAdjustment" in-map-name="removeCtx"/>
-        </iterate>
-        <remove-value value-field="returnItem"/>
-    </simple-method>
-
-    <simple-method method-name="createReturnAdjustment" short-description="Create Return Adjustment">
-        <if>
-            <condition>
-                <not><if-has-permission permission="ORDERMGR" action="_CREATE"/></not>
-            </condition>
-            <then>
-                <add-error>
-                    <fail-property resource="OrderErrorUiLabels" property="OrderErrorCreatePermissionError"/>
-                </add-error>
-            </then>
-        </if>
-        <check-errors/>
-
-        <make-value entity-name="ReturnAdjustment" value-field="newEntity"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <sequenced-id sequence-name="ReturnAdjustment" field="newEntity.returnAdjustmentId"/>
-        <field-to-result field="newEntity.returnAdjustmentId" result-name="returnAdjustmentId"/>
-        <create-value value-field="newEntity"/>
-        <set field="responseMessage" value="Return Adjustment #${newEntity.returnAdjustmentId} was created successfully."/>
-        <field-to-result field="responseMessage" result-name="successMessage"/>
-    </simple-method>
-    <simple-method method-name="removeReturnAdjustment" short-description="Remove Return Adjustment">
-        <set from-field="parameters.returnAdjustmentId" field="lookupPKMap.returnAdjustmentId"/>
-        <find-by-primary-key entity-name="ReturnAdjustment" map="lookupPKMap" value-field="returnAdjustment"/>
-        <if-not-empty field="returnAdjustment">
-            <remove-value value-field="returnAdjustment"/>
-        </if-not-empty>
-    </simple-method>
-    <!-- note that this service is designed to be called once for each shipment receipt that is created -->
-    <simple-method method-name="updateReturnStatusFromReceipt" short-description="Update Return Status From ShipmentReceipt">
-        <set from-field="parameters.returnId" field="lookupPKMap.returnId"/>
-        <find-by-primary-key entity-name="ReturnHeader" map="lookupPKMap" value-field="returnHeader"/>
-        <find-by-and entity-name="ShipmentReceipt" map="lookupPKMap" list="shipmentReceipts"/>
-        <iterate list="shipmentReceipts" entry="receipt">
-            <if-empty field="totalsMap[receipt.returnItemSeqId]">
-                <set field="totalsMap[receipt.returnItemSeqId]" value="0" type="BigDecimal"/>
-            </if-empty>
-            <set field="totalsMap[receipt.returnItemSeqId]" from="totalsMap[receipt.returnItemSeqId] + (receipt.quantityAccepted + receipt.quantityRejected)"/>
-        </iterate>
-        <get-related relation-name="ReturnItem" list="returnItems" value-field="returnHeader"/>
-        <iterate-map key="returnItemSeqId" value="value" map="totalsMap">
-            <set field="filterMap.returnItemSeqId" from="returnItemSeqId"/>
-            <filter-list-by-and list="returnItems" map="filterMap" to-list="items"/>
-            <first-from-list list="items" entry="item"/>
-            <set field="item.receivedQuantity" from="value" type="BigDecimal"/>
-            <set-service-fields service-name="updateReturnItem" map="item" to-map="serviceInMap"/>
-            <if-compare-field field="value" to-field="item.returnQuantity" operator="greater-equals" type="BigDecimal">
-                <!-- update the status for the item -->
-                <set field="serviceInMap.statusId" value="RETURN_RECEIVED"/>
-            </if-compare-field>
-
-            <!-- update the returnItem with at least receivedQuantity, and also statusId if applicable -->
-            <call-service service-name="updateReturnItem" in-map-name="serviceInMap"/>
-            <clear-field field="serviceInMap"/>
-            <clear-field field="filterMap"/>
-        </iterate-map>
-        <!-- check to see if all items have been received -->
-        <set field="allReceived" value="true"/>
-        <find-by-and entity-name="ReturnItem" map="lookupPKMap" list="allReturnItems"/>
-        <iterate list="allReturnItems" entry="item">
-            <if-compare field="item.statusId" operator="not-equals" value="RETURN_RECEIVED">
-                <if-not-empty field="item.orderItemSeqId">
-                    <!-- non-order items (i.e. adjustments) are not received -->
-                    <set value="false" field="allReceived"/>
-                </if-not-empty>
-            </if-compare>
-        </iterate>
-
-        <!-- if the items are all received, then update the return header, store the status history change, and set the shipment to received -->
-        <if-compare field="allReceived" operator="equals" value="true">
-
-            <!--  Go through all the items yet again and set their shipment status to PURCH_SHIP_RECEIVED (if it isn't already)
-                This activates SECAS such as creating return invoices. This MUST be done before updating the return header so that
-                the ReturnItemBillings are created and then whatever SECA binds to the return header update will have them. . -->
-            <iterate list="shipmentReceipts" entry="receipt">
-                <get-related-one relation-name="Shipment" value-field="receipt" to-value-field="shipment"/>
-                <if-not-empty field="shipment.shipmentId">
-                    <if-compare field="shipment.statusId" operator="not-equals" value="RETURN_RECEIVED">
-                        <set field="serviceInput.shipmentId" from-field="shipment.shipmentId"/>
-                        <set field="serviceInput.statusId" value="PURCH_SHIP_RECEIVED"/>
-                        <call-service service-name="updateShipment" in-map-name="serviceInput"/>
-                    </if-compare>
-                </if-not-empty>
-            </iterate>
-
-            <!-- update the return header -->
-            <set field="returnHeaderCtx.statusId" value="RETURN_RECEIVED"/>
-            <set from-field="returnHeader.returnId" field="returnHeaderCtx.returnId"/>
-            <call-service service-name="updateReturnHeader" in-map-name="returnHeaderCtx"/>
-        </if-compare>
-
-        <!-- return the current return header status -->
-        <field-to-result field="returnHeader.statusId" result-name="returnHeaderStatus"/>
-    </simple-method>
-
-    <simple-method method-name="quickReturnFromOrder" short-description="Create Quick Return From Order">
-        <if>
-            <condition>
-                <and>
-                    <not><if-has-permission permission="ORDERMGR" action="_CREATE"/></not>
-                    <not><if-compare-field field="userLogin.partyId" to-field="parameters.fromPartyId" operator="equals"/></not>
-                </and>
-            </condition>
-            <then>
-                <add-error><fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunQuickReturnFromOrder"/></add-error>
-            </then>
-        </if>
-        <check-errors/>
-
-        <!-- get primary information from the order header -->
-        <entity-one entity-name="OrderHeader" value-field="orderHeader">
-            <field-map field-name="orderId" from-field="parameters.orderId"/>
-        </entity-one>
-        <set field="returnHeaderTypeId" from-field="parameters.returnHeaderTypeId"/>
-        <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-            <set field="roleTypeId" value="BILL_TO_CUSTOMER"/>
-        <else>
-            <set field="roleTypeId" value="BILL_FROM_VENDOR"/>
-        </else>
-        </if-compare>
-
-        <!-- find the bill to customer; for return's fromPartyId -->
-        <entity-condition entity-name="OrderRole" list="orderRoles">
-            <condition-list combine="and">
-                <condition-expr field-name="orderId" operator="equals" from-field="orderHeader.orderId"/>
-                <condition-expr field-name="roleTypeId" operator="equals" from-field="roleTypeId"/>
-            </condition-list>
-        </entity-condition>
-        <first-from-list list="orderRoles" entry="orderRole"/>
-        <!-- create the return header -->
-        <set from-field="orderHeader.originFacilityId" field="createHeaderCtx.destinationFacilityId"/>
-        <set value="Y" field="updateHeaderCtx.needsInventoryReceive"/>
-        <set from-field="returnHeaderTypeId" field="createHeaderCtx.returnHeaderTypeId"/>
-
-        <!-- get the return to party for customer return and return from party for vendor return from the product store -->
-        <get-related-one relation-name="ProductStore" value-field="orderHeader" to-value-field="productStore"/>
-        <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-            <set field="createHeaderCtx.fromPartyId" from-field="orderRole.partyId"/>
-            <set field="createHeaderCtx.toPartyId" from-field="productStore.payToPartyId"/>
-            <if-empty field="createHeaderCtx.destinationFacilityId">
-                <set field="createHeaderCtx.destinationFacilityId" from-field="productStore.inventoryFacilityId"/>
-            </if-empty>
-        <else>
-            <set field="createHeaderCtx.fromPartyId" from-field="productStore.payToPartyId"/>
-            <set field="createHeaderCtx.toPartyId" from-field="orderRole.partyId"/>
-        </else>
-        </if-compare>
-        <!-- copy over the currency of the order to the currency of the return -->
-        <set from-field="orderHeader.currencyUom" field="createHeaderCtx.currencyUomId"/>
-
-        <call-service service-name="createReturnHeader" in-map-name="createHeaderCtx" include-user-login="true">
-            <result-to-field result-name="returnId"/>
-        </call-service>
-
-        <!-- get the available to return order items -->
-        <entity-condition entity-name="OrderItem" list="orderItems">
-            <condition-list combine="and">
-                <condition-expr field-name="orderId" operator="equals" from-field="orderHeader.orderId"/>
-                <condition-expr field-name="statusId" operator="equals" value="ITEM_COMPLETED"/>
-            </condition-list>
-        </entity-condition>
-
-        <if-empty field="parameters.returnReasonId">
-            <set value="RTN_NOT_WANT" field="parameters.returnReasonId"/>
-        </if-empty>
-        <if-empty field="parameters.returnTypeId">
-            <set value="RTN_REFUND" field="parameters.returnTypeId"/>
-        </if-empty>
-
-        <!-- create the return items -->
-        <iterate list="orderItems" entry="orderItem">
-            <set from-field="returnId" field="newItemCtx.returnId"/>
-            <set from-field="parameters.returnReasonId" field="newItemCtx.returnReasonId"/>
-            <set from-field="parameters.returnTypeId" field="newItemCtx.returnTypeId"/>
-
-            <if-not-empty field="orderItem.productId">
-                <set from-field="orderItem.productId" field="newItemCtx.productId"/>
-            </if-not-empty>
-
-            <set from-field="orderItem.orderId" field="newItemCtx.orderId"/>
-            <set from-field="orderItem.orderItemSeqId" field="newItemCtx.orderItemSeqId"/>
-            <set from-field="orderItem.itemDescription" field="newItemCtx.description"/>
-
-            <!-- get the returnable price and quantity -->
-            <set from-field="orderItem" field="itemCheckMap.orderItem"/>
-            <call-service service-name="getReturnableQuantity" in-map-name="itemCheckMap">
-                <result-to-field result-name="returnableQuantity" field="newItemCtx.returnQuantity"/>
-                <result-to-field result-name="returnablePrice" field="newItemCtx.returnPrice"/>
-            </call-service>
-
-            <!-- get the matching return item type from the order item type -->
-
-            <set from-field="orderItem.orderItemTypeId" field="orderItemTypeId"/>
-            <if-compare field="orderItemTypeId" value="PRODUCT_ORDER_ITEM" operator="equals">
-            <!-- Check if orderItemTypeId equals PRODUCT_ORDER_ITEM, if so, use ProductType and ReturnItemTypeMap to get ReturnItemType-->
-                <entity-one entity-name="Product" value-field="product">
-                    <field-map field-name="productId" from-field="orderItem.productId"/>
-                    <select-field field-name="productTypeId"/>
-                </entity-one>
-                <entity-one entity-name="ReturnItemTypeMap" value-field="returnItemTypeMapping">
-                    <field-map field-name="returnItemMapKey" from-field="product.productTypeId"/>
-                    <field-map field-name="returnHeaderTypeId" from-field="returnHeaderTypeId"/>
-                </entity-one>
-            <else>
-            <!-- if not, try the ReturnItemTypeMap, but this may not actually work, so log a warning -->
-                <log level="warning" message="Trying to find returnItemtype from ReturnItemTypeMap with orderItemtypeId [${orderItem.orderItemTypeId}] for order item [${orderItem}]"/>
-                <entity-one entity-name="ReturnItemTypeMap" value-field="returnItemTypeMapping">
-                   <field-map field-name="returnItemMapKey" from-field="orderItemTypeId"/>
-                   <field-map field-name="returnHeaderTypeId" from-field="returnHeaderTypeId"/>
-                </entity-one>
-            </else>
-            </if-compare>
-
-            <if-empty field="returnItemTypeMapping.returnItemTypeId">
-                <add-error>
-                    <fail-property resource="OrderErrorUiLabels" property="OrderReturnItemTypeOrderItemNoMatching"/>
-                </add-error>
-                <check-errors/>
-            <else>
-                <set from-field="returnItemTypeMapping.returnItemTypeId" field="newItemCtx.returnItemTypeId"/>
-            </else>
-            </if-empty>
-
-            <!-- create the return item -->
-            <if-not-empty field="newItemCtx.orderAdjustmentId">
-                <log level="info" message="Found unexpected orderAdjustment:${newItemCtx.orderAdjustmentId}"/>
-                <clear-field field="newItemCtx.orderAdjustmentId"/>
-            </if-not-empty>
-            <if-compare field="newItemCtx.returnQuantity" value="0" operator="greater" type="BigDecimal">
-                <!-- otherwise, items which have been fully returned would still get passed in and then come back with an error -->
-                <call-service service-name="createReturnItem" in-map-name="newItemCtx" include-user-login="true"/>
-            <else>
-                <log level="info" message="This return item is not going to be created because its returnQuantity is zero: ${newItemCtx}"/>
-            </else>
-            </if-compare>
-        </iterate>
-
-        <!-- create a return adjustment for all order adjustments not attached to a particular orderItem (orderItemSeqId = "_NA_") -->
-        <entity-condition entity-name="OrderAdjustment" list="orderAdjustments">
-            <condition-list combine="and">
-                <condition-expr field-name="orderId" operator="equals" from-field="orderHeader.orderId"/>
-                <condition-expr field-name="orderItemSeqId" operator="equals" value="_NA_"/>
-            </condition-list>
-        </entity-condition>
-        <iterate list="orderAdjustments" entry="orderAdjustment">
-            <clear-field field="returnAdjCtx"/>
-            <set from-field="orderAdjustment.orderAdjustmentId" field="returnAdjCtx.orderAdjustmentId"/>
-            <set from-field="returnId" field="returnAdjCtx.returnId"/>
-            <!--filter out orderAdjustment that have been returned-->
-            <entity-count entity-name="ReturnAdjustment" count-field="returnCount">
-                <condition-expr field-name="orderAdjustmentId" operator="equals" from-field="orderAdjustment.orderAdjustmentId"/>
-            </entity-count>
-            <if-compare field="returnCount" value="0" operator="equals">
-                <log level="info" message="Create new return adjustment: ${returnAdjCtx}"/>
-                <call-service service-name="createReturnAdjustment" in-map-name="returnAdjCtx" include-user-login="true"/>
-            </if-compare>
-        </iterate>
-        <set field="orderAvailableCtx.orderId" from-field="orderHeader.orderId"/>
-        <set field="orderAvailableCtx.countNewReturnItems" value="true" type="Boolean"/> <!-- very important: if this is not set, getOrderAvailableReturnedTotal would not count the return items we just created -->
-        <call-service service-name="getOrderAvailableReturnedTotal" in-map-name="orderAvailableCtx">
-            <result-to-field result-name="availableReturnTotal" field="availableReturnTotal"/>
-            <result-to-field result-name="returnTotal" field="returnTotal"/>
-            <result-to-field result-name="orderTotal" field="orderTotal"/>
-        </call-service>
-        <log level="info" message="OrderTotal [${orderTotal}] - ReturnTotal [${returnTotal}] = available Return Total [${availableReturnTotal}]"/>
-
-        <!-- create a manual balance adjustment based on the difference between order total and return total -->
-        <if-compare field="availableReturnTotal" operator="not-equals" value="0.00" type="BigDecimal">
-            <set value="Balance Adjustment" field="balanceItemCtx.description"/>
-            <set value="RET_MAN_ADJ" field="balanceItemCtx.returnAdjustmentTypeId"/>
-
-            <set from-field="returnId" field="balanceItemCtx.returnId"/>
-            <set field="balanceItemCtx.returnItemSeqId" value="_NA_"/>
-            <set from-field="availableReturnTotal" field="balanceItemCtx.amount" type="BigDecimal"/>
-            <log level="warning" message="Creating a balance adjustment of [${availableReturnTotal}] for return [${returnId}]"/>
-
-            <!-- create the balance adjustment return item -->
-            <call-service service-name="createReturnAdjustment" in-map-name="balanceItemCtx" include-user-login="true"/>
-        </if-compare>
-
-        <!-- update the header status -->
-        <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-            <set field="updateHeaderCtx.statusId" value="RETURN_ACCEPTED"/>
-        <else>
-            <set field="updateHeaderCtx.statusId" value="SUP_RETURN_ACCEPTED"/>
-        </else>
-        </if-compare>
-        <set from-field="returnId" field="updateHeaderCtx.returnId"/>
-        <call-service service-name="updateReturnHeader" in-map-name="updateHeaderCtx" include-user-login="true"/>
-
-        <if-compare field="returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-            <!-- auto-receive this return if we passed in the flag -->
-            <if-compare field="parameters.receiveReturn" operator="equals" value="true" type="Boolean">
-                <set from-field="returnId" field="receiveCtx.returnId"/>
-                <call-service service-name="quickReceiveReturn" in-map-name="receiveCtx"/>
-            <else>
-                <!-- update the header status -->
-                <log level="info" message="Receive flag not set; will handle receiving on entity-sync"/>
-            </else>
-            </if-compare>
-        </if-compare>
-        <field-to-result field="returnId"/>
-    </simple-method>
-
-    <simple-method method-name="createReturnAndItemOrAdjustment" short-description="If returnId is null, create a return; then create Return Item or Adjustment based on the parameters passed in">
-        <if-empty field="parameters.returnId">
-            <set-service-fields service-name="createReturnHeader" map="parameters" to-map="returnHeaderInMap"/>
-            <call-service service-name="createReturnHeader" in-map-name="returnHeaderInMap">
-                <result-to-field result-name="returnId" field="returnId"/>
-            </call-service>
-            <check-errors/>
-            <set field="parameters.returnId" from-field="returnId"/>
-            <field-to-result field="returnId" result-name="returnId"/>
-        </if-empty>
-        <set-service-fields service-name="createReturnItemOrAdjustment" map="parameters" to-map="createReturnItemOrAdjustmentInMap"/>
-        <call-service service-name="createReturnItemOrAdjustment" in-map-name="createReturnItemOrAdjustmentInMap">
-            <result-to-field result-name="returnAdjustmentId" field="returnAdjustmentId"/>
-            <result-to-field result-name="returnItemSeqId" field="returnItemSeqId"/>
-        </call-service>
-        <check-errors/>
-        <field-to-result field="returnAdjustmentId" result-name="returnAdjustmentId"/>
-        <field-to-result field="returnItemSeqId" result-name="returnItemSeqId"/>
-    </simple-method>
-
-    <simple-method method-name="cancelReturnItems" short-description="Update a ReturnItems">
-        <entity-condition entity-name="ReturnItem" list="returnItems" distinct="true">
-            <condition-expr field-name="returnId" operator="equals" from-field="parameters.returnId"/>
-        </entity-condition>
-        <iterate list="returnItems" entry="returnItem">
-            <set field="returnItemMap.returnId" from-field="parameters.returnId"/>
-            <set field="returnItemMap.returnItemSeqId" from-field="returnItem.returnItemSeqId"/>
-            <set field="returnItemMap.statusId" value="RETURN_CANCELLED"/>
-            <call-service service-name="updateReturnItem" in-map-name="returnItemMap"/>
-        </iterate>
-    </simple-method>
-
-    <simple-method method-name="cancelReplacementOrderItems" short-description="Cancel the associated OrderItems of the replacement order, if any.">
-        <entity-one entity-name="ReturnItem" value-field="returnItem"/>
-        <if>
-            <condition>
-                <or>
-                    <if-compare field="returnItem.returnTypeId" operator="equals" value="RTN_REPLACE"/>
-                    <if-compare field="returnItem.returnTypeId" operator="equals" value="RTN_CSREPLACE"/>
-                    <if-compare field="returnItem.returnTypeId" operator="equals" value="RTN_REPAIR_REPLACE"/>
-                </or>
-            </condition>
-            <then>
-                <!-- get the returned order item -->
-                <get-related-one value-field="returnItem" relation-name="OrderItem" to-value-field="orderItem"/>
-                <!-- get the order items of the replacement order associated to the returned item  -->
-                <set field="oiaMap.orderItemAssocTypeId" value="REPLACEMENT"/>
-                <get-related value-field="orderItem" relation-name="FromOrderItemAssoc" map="oiaMap" list="replacementOrderItems"/>
-                <iterate list="replacementOrderItems" entry="replacementOrderItem">
-                    <set field="orderItemMap.orderId" from-field="replacementOrderItem.toOrderId"/>
-                    <set field="orderItemMap.orderItemSeqId" from-field="replacementOrderItem.toOrderItemSeqId"/>
-                    <call-service service-name="cancelOrderItem" in-map-name="orderItemMap"/>
-                </iterate>
-            </then>
-        </if>
-    </simple-method>
-
-    <simple-method method-name="processWaitReplacementReturn" short-description="Process the replacements in a wait return">
-        <set field="inMap.returnId" from-field="parameters.returnId"/>
-        <set field="inMap.returnTypeId" value="RTN_REPLACE"/>
-        <call-service service-name="processReplacementReturn" in-map-name="inMap"/>
-    </simple-method>
-    <simple-method method-name="processCrossShipReplacementReturn" short-description="Process the replacements in a cross-ship return">
-        <set field="inMap.returnId" from-field="parameters.returnId"/>
-        <set field="inMap.returnTypeId" value="RTN_CSREPLACE"/>
-        <call-service service-name="processReplacementReturn" in-map-name="inMap"/>
-    </simple-method>
-    <simple-method method-name="processRepairReplacementReturn" short-description="Process the replacements in a repair return">
-        <set field="inMap.returnId" from-field="parameters.returnId"/>
-        <set field="inMap.returnTypeId" value="RTN_REPAIR_REPLACE"/>
-        <call-service service-name="processReplacementReturn" in-map-name="inMap"/>
-    </simple-method>
-    <simple-method method-name="processWaitReplacementReservedReturn" short-description="Process the replacements in a wait reserved return when the return is accepted and then received">
-        <entity-one entity-name="ReturnHeader" value-field="returnHeader"/>
-        <if-compare field="returnHeader.statusId" operator="equals" value="RETURN_ACCEPTED">
-            <set field="inMap.returnId" from-field="parameters.returnId"/>
-            <set field="inMap.returnTypeId" value="RTN_WAIT_REPLACE_RES"/>
-            <call-service service-name="processReplacementReturn" in-map-name="inMap"/>
-        </if-compare>
-        <if-compare field="returnHeader.statusId" operator="equals" value="RETURN_RECEIVED">
-            <entity-and entity-name="ReturnItem" list="returnItems">
-                <field-map field-name="returnId" from-field="returnHeader.returnId"/>
-                <field-map field-name="returnTypeId" value="RTN_WAIT_REPLACE_RES"/>
-            </entity-and>
-            <if-not-empty field="returnItems">
-                <!-- Get the replacement order and update its status to Approved -->
-                <first-from-list list="returnItems" entry="returnItem"/>
-                <get-related-one relation-name="ReturnItemResponse" value-field="returnItem" to-value-field="returnItemResponse"/>
-                <entity-one entity-name="OrderHeader" value-field="orderHeader" >
-                    <field-map field-name="orderId" from-field="returnItemResponse.replacementOrderId"/>
-                </entity-one>
-                <if-not-empty field="orderHeader">
-                    <if-compare field="orderHeader.statusId" operator="equals" value="ORDER_HOLD">
-                        <set field="changeOrderStatusMap.statusId" value="ORDER_APPROVED"/>
-                        <set field="changeOrderStatusMap.orderId" from-field="returnItemResponse.replacementOrderId"/>
-                        <set field="changeOrderStatusMap.setItemStatus" value="Y"/>
-                        <call-service service-name="changeOrderStatus" in-map-name="changeOrderStatusMap"/>
-                    </if-compare>
-                    <if-compare field="orderHeader.statusId" operator="equals" value="ORDER_CANCELLED">
-                        <set field="createOrderMap.returnId" from-field="parameters.returnId"/>
-                        <set field="createOrderMap.returnTypeId" value="RTN_WAIT_REPLACE_RES"/>
-                        <call-service service-name="processReplacementReturn" in-map-name="createOrderMap"/>
-                    </if-compare>
-                </if-not-empty>                                
-            </if-not-empty>
-        </if-compare>
-    </simple-method>
-   
-    <simple-method method-name="processReplaceImmediatelyReturn" short-description="Process the replacements in a immediate return">
-        <set field="inMap.returnId" from-field="parameters.returnId"/>
-        <set field="inMap.returnTypeId" value="RTN_REPLACE_IMMEDIAT"/>
-        <call-service service-name="processReplacementReturn" in-map-name="inMap"/>
-    </simple-method> 
-    <simple-method method-name="processRefundOnlyReturn" short-description="Process the refund in a return">
-        <set field="inMap.returnId" from-field="parameters.returnId"/>
-        <set field="inMap.returnTypeId" value="RTN_REFUND"/>
-        <call-service service-name="processRefundReturn" in-map-name="inMap"/>
-    </simple-method> 
-    <simple-method method-name="processRefundImmediatelyReturn" short-description="Process the Immediate refund in a return">
-        <set field="inMap.returnId" from-field="parameters.returnId"/>
-        <set field="inMap.returnTypeId" value="RTN_REFUND_IMMEDIATE"/>
-        <call-service service-name="processRefundReturn" in-map-name="inMap"/>
-    </simple-method> 
-
-    <simple-method method-name="createReturnItemShipment" short-description="Create a ReturnItemShipment">
-        <make-value entity-name="ReturnItemShipment" value-field="newEntity"/>
-        <set-pk-fields map="parameters" value-field="newEntity"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <create-value value-field="newEntity"/>
-    </simple-method>
-
-    <simple-method method-name="getStatusItemsForReturn" short-description="Get the return status associated with customer vs. vendor return">
-        <if-compare field="parameters.returnHeaderTypeId" operator="equals" value="CUSTOMER_RETURN">
-            <entity-and entity-name="StatusItem" list="statusItems">
-                <field-map field-name="statusTypeId" value="ORDER_RETURN_STTS"/>
-            </entity-and>
-            <field-to-result field="statusItems"/>
-        <else>
-            <entity-and entity-name="StatusItem" list="statusItems">
-                <field-map field-name="statusTypeId" value="PORDER_RETURN_STTS"/>
-            </entity-and>
-            <field-to-result field="statusItems"/>
-        </else>
-        </if-compare>
-    </simple-method>
-
-    <simple-method method-name="createExchangeOrderAssoc" short-description="Associate exchange order with original order in OrderItemAssoc entity">
-        <entity-and entity-name="ReturnItem" list="returnItems">
-            <field-map field-name="orderId" from-field="parameters.originOrderId"/>
-            <field-map field-name="returnTypeId" value="RTN_REFUND"/>
-        </entity-and>
-        <set field="returnItemSize" value="${groovy:returnItems.size()}" type="Long"/>
-        <entity-and entity-name="OrderItem" list="orderItems">
-            <field-map field-name="orderId" from-field="parameters.orderId"/>
-        </entity-and>
-        <set field="orderItemSize" value="${groovy:orderItems.size()}" type="Long"/>
-        <if>
-            <condition>
-                <if-compare-field field="returnItemSize" operator="greater" to-field="orderItemSize" type="Long"/>
-            </condition>
-            <then>
-                <set field="returnItemCounter" value="1" type="Long"/>
-                <iterate list="returnItems" entry="returnItem">
-                    <set field="orderItemAssocMap.orderId" from-field="parameters.originOrderId"/>
-                    <set field="orderItemAssocMap.orderItemSeqId" from-field="returnItem.orderItemSeqId"/>
-                    <set field="orderItemCounter" value="1" type="Long"/>
-                    <iterate list="orderItems" entry="orderItem">
-                        <if>
-                            <condition>
-                                <if-compare-field field="returnItemCounter" operator="equals" to-field="orderItemCounter" type="Long"/>
-                            </condition>
-                            <then>
-                                <set field="orderItemAssocMap.toOrderId" from-field="parameters.orderId"/>
-                                <set field="orderItemAssocMap.toOrderItemSeqId" from-field="orderItem.orderItemSeqId"/>
-                            </then>
-                        <else-if>
-                            <condition>
-                                <if-compare-field field="returnItemCounter" operator="greater" to-field="orderItemSize" type="Long"/>
-                            </condition>
-                            <then>
-                                <set field="orderItemAssocMap.toOrderId" from-field="parameters.orderId"/>
-                                <set field="orderItemAssocMap.toOrderItemSeqId" from-field="orderItem.orderItemSeqId"/>
-                            </then>
-                        </else-if>
-                        </if>
-                        <set field="orderItemCounter" value="${orderItemCounter+1}" type="Long"/>
-                    </iterate>
-                    <set field="orderItemAssocMap.shipGroupSeqId" value="_NA_"/>
-                    <set field="orderItemAssocMap.toShipGroupSeqId" value="_NA_"/>
-                    <set field="orderItemAssocMap.orderItemAssocTypeId" value="EXCHANGE"/>
-                    <make-value entity-name="OrderItemAssoc" value-field="orderItemAssoc"/>
-                    <set-pk-fields map="orderItemAssocMap" value-field="orderItemAssoc"/>
-                    <find-by-primary-key entity-name="OrderItemAssoc" map="orderItemAssoc" value-field="orderItemAssocValue"/>
-                    <if-empty field="orderItemAssocValue">
-                        <create-value value-field="orderItemAssoc"/>
-                        <clear-field field="orderItemAssoc"/>
-                    </if-empty>
-                    <set field="returnItemCounter" value="${returnItemCounter+1}" type="Long"/>
-                </iterate>
-            </then>
-            <else>
-                <set field="orderItemCounter" value="1" type="Long"/>
-                <iterate list="orderItems" entry="orderItem">
-                    <set field="orderItemAssocMap.toOrderId" from-field="parameters.orderId"/>
-                    <set field="orderItemAssocMap.toOrderItemSeqId" from-field="orderItem.orderItemSeqId"/>
-                    <set field="returnItemCounter" value="1" type="Long"/>
-                    <iterate list="returnItems" entry="returnItem">
-                        <if>
-                            <condition>
-                                <if-compare-field field="orderItemCounter" operator="equals" to-field="returnItemCounter" type="Long"/>
-                            </condition>
-                            <then>
-                                <set field="orderItemAssocMap.orderId" from-field="parameters.originOrderId"/>
-                                <set field="orderItemAssocMap.orderItemSeqId" from-field="returnItem.orderItemSeqId"/>
-                            </then>
-                        <else-if>
-                            <condition>
-                                <if-compare-field field="orderItemCounter" operator="greater" to-field="returnItemSize" type="Long"/>
-                            </condition>
-                            <then>
-                                <set field="orderItemAssocMap.orderId" from-field="parameters.originOrderId"/>
-                                <set field="orderItemAssocMap.orderItemSeqId" from-field="returnItem.orderItemSeqId"/>
-                            </then>
-                        </else-if>
-                        </if>
-                        <set field="returnItemCounter" value="${returnItemCounter+1}" type="Long"/>
-                    </iterate>
-                    <set field="orderItemAssocMap.shipGroupSeqId" value="_NA_"/>
-                    <set field="orderItemAssocMap.toShipGroupSeqId" value="_NA_"/>
-                    <set field="orderItemAssocMap.orderItemAssocTypeId" value="EXCHANGE"/>
-                    <make-value entity-name="OrderItemAssoc" value-field="orderItemAssoc"/>
-                    <set-pk-fields map="orderItemAssocMap" value-field="orderItemAssoc"/>
-                    <find-by-primary-key entity-name="OrderItemAssoc" map="orderItemAssoc" value-field="orderItemAssocValue"/>
-                    <if-empty field="orderItemAssocValue">
-                        <create-value value-field="orderItemAssoc"/>
-                        <clear-field field="orderItemAssocMap"/>
-                    </if-empty>
-                    <set field="orderItemCounter" value="${orderItemCounter+1}" type="Long"/>
-                </iterate>
-            </else>
-        </if>
-    </simple-method>
-
-    <simple-method method-name="addProductsBackToCategory" short-description="When one or more product is received directly through receive inventory or refund return then add these product(s) back to category, if they does not have any active category">
-        <if-not-empty field="parameters.inventoryItemId">
-            <entity-one entity-name="InventoryItem" value-field="inventoryItem"/>
-            <get-related-one relation-name="Product" value-field="inventoryItem" to-value-field="product"/>
-            <set field="orderBy[]" value="-thruDate"/>
-            <get-related relation-name="ProductCategoryMember" value-field="product" list="productCategoryMembers" order-by-list="orderBy"/>
-            <!-- check whether this product is associated to any category, if not just skip -->
-            <if-not-empty field="productCategoryMembers">
-                <filter-list-by-date list="productCategoryMembers" to-list="pcms"/>
-                <!-- check if this product is associated to any active category, if not found then activate the most recent inactive category -->
-                <if-empty field="pcms">
-                    <first-from-list list="productCategoryMembers" entry="pcm"/>
-                    <clear-field field="pcm.thruDate"/>
-                    <set-service-fields service-name="updateProductToCategory" map="pcm" to-map="updateProductToCategoryMap"/>
-                    <call-service service-name="updateProductToCategory" in-map-name="updateProductToCategoryMap"/>
-                </if-empty>
-            </if-not-empty>
-        <else>
-            <if-not-empty field="parameters.returnId">
-                <entity-and entity-name="ReturnItem" list="returnItems">
-                    <field-map field-name="returnId" from-field="parameters.returnId"/>
-                    <field-map field-name="returnTypeId" value="RTN_REFUND"/>
-                </entity-and>
-                <if-not-empty field="returnItems">
-                    <iterate list="returnItems" entry="returnItem">
-                        <get-related-one relation-name="Product" value-field="returnItem" to-value-field="product"/>
-                        <set field="orderBy[]" value="-thruDate"/>
-                        <get-related relation-name="ProductCategoryMember" value-field="product" list="productCategoryMembers" order-by-list="orderBy"/>
-                        <!-- check whether this product is associated to any category, if not just skip -->
-                        <if-not-empty field="productCategoryMembers">
-                            <filter-list-by-date list="productCategoryMembers" to-list="pcms"/>
-                            <!-- check if this product is associated to any active category, if not found then activate the most recent inactive category -->
-                            <if-empty field="pcms">
-                                <first-from-list list="productCategoryMembers" entry="pcm"/>
-                                <clear-field field="pcm.thruDate"/>
-                                <set-service-fields service-name="updateProductToCategory" map="pcm" to-map="updateProductToCategoryMap"/>
-                                <call-service service-name="updateProductToCategory" in-map-name="updateProductToCategoryMap"/>
-                            </if-empty>
-                        </if-not-empty>
-                    </iterate>
-                </if-not-empty>
-            </if-not-empty>
-        </else>
-        </if-not-empty>
-    </simple-method>
-    
-    <simple-method method-name="createReturnStatus" short-description="Create ReturnHeader and ReturnItem Status">
-        <make-value entity-name="ReturnStatus" value-field="newEntity"/>
-        <if-empty field="parameters.returnItemSeqId">
-            <entity-one entity-name="ReturnHeader" value-field="returnHeader"/>
-            <set field="newEntity.statusId" from-field="returnHeader.statusId"/>
-        <else>
-            <entity-one entity-name="ReturnItem"  value-field="returnItem"/>
-            <set field="newEntity.returnItemSeqId" from-field="returnItem.returnItemSeqId"/>
-            <set field="newEntity.statusId" from-field="returnItem.statusId"/>
-        </else>
-        </if-empty>
-        <sequenced-id sequence-name="ReturnStatus" field="newEntity.returnStatusId"/>
-        <set field="newEntity.returnId" from-field="parameters.returnId"/>
-        <set field="newEntity.changeByUserLoginId" from-field="userLogin.userLoginId"/>
-        <now-timestamp field="newEntity.statusDatetime"/>
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    
-    <simple-method method-name="updateReturnContactMech" short-description="Update ReturnContactMech">
-        <make-value entity-name="ReturnContactMech" value-field="returnContactMechMap"/>
-
-        <set-pk-fields map="parameters" value-field="returnContactMechMap"/>
-        <entity-one entity-name="ReturnHeader" value-field="returnHeader"/>
-        <set from-field="parameters.returnId" field="createReturnContactMechMap.returnId"/>
-        <set from-field="parameters.contactMechPurposeTypeId" field="createReturnContactMechMap.contactMechPurposeTypeId"/>
-        <set from-field="parameters.contactMechId" field="createReturnContactMechMap.contactMechId"/>
-  
-        <find-by-and entity-name="ReturnContactMech" map="createReturnContactMechMap" list="returnContactMechList"/>
-        <!-- If returnContactMechList value is null then create new entry in ReturnContactMech entity-->
-        <if-empty field="returnContactMechList">
-            <if-compare field="parameters.contactMechPurposeTypeId" operator="equals" value="SHIPPING_LOCATION">
-                <set field="returnHeader.originContactMechId" from-field="createReturnContactMechMap.contactMechId"/>
-                <store-value value-field="returnHeader"/>
-            </if-compare>
-            <call-service service-name="createReturnContactMech" in-map-name="createReturnContactMechMap" include-user-login="true"/>
-            <set from-field="parameters.returnId" field="deleteReturnContactMechMap.returnId"/>
-            <set from-field="parameters.oldContactMechId" field="deleteReturnContactMechMap.contactMechId"/>
-            <set from-field="parameters.contactMechPurposeTypeId" field="deleteReturnContactMechMap.contactMechPurposeTypeId"/>
-            <call-service service-name="deleteReturnContactMech" in-map-name="deleteReturnContactMechMap" include-user-login="true"/>
-        </if-empty>
-        <store-value value-field="returnContactMechMap"/>
-     </simple-method>
-
-    <simple-method method-name="createReturnItemForRental" short-description="Create the return item for rental (which items has product type is ASSET_USAGE_OUT_IN)">
-        <entity-one entity-name="OrderHeader" value-field="orderHeader">
-            <field-map field-name="orderId" from-field="parameters.orderId"/>
-        </entity-one>
-
-        <if-compare operator="equals" value="SALES_ORDER" field="orderHeader.orderTypeId">
-            <entity-condition entity-name="OrderRole" list="orderRoles">
-                <condition-list combine="and">
-                    <condition-expr field-name="orderId" operator="equals" from-field="orderHeader.orderId"/>
-                    <condition-expr field-name="roleTypeId" operator="equals" value="BILL_TO_CUSTOMER"/>
-                </condition-list>
-            </entity-condition>
-            <first-from-list list="orderRoles" entry="orderRole"/>
-
-            <get-related-one relation-name="ProductStore" value-field="orderHeader" to-value-field="productStore"/>
-
-            <if-not-empty field="productStore.inventoryFacilityId">
-                <set field="createReturnCtx.destinationFacilityId" from-field="productStore.inventoryFacilityId"/>
-            </if-not-empty>
-
-            <if-not-empty field="productStore.reqReturnInventoryReceive">
-                <set field="updateHeaderCtx.needsInventoryReceive" from-field="productStore.reqReturnInventoryReceive"/>
-            <else>
-                <set field="updateHeaderCtx.needsInventoryReceive" value="N"/>
-            </else>
-            </if-not-empty>
-
-            <set field="createReturnCtx.orderId" from-field="orderHeader.orderId"/>
-            <set field="createReturnCtx.currencyUomId" from-field="orderHeader.currencyUom"/>
-            <set field="createReturnCtx.fromPartyId" from-field="orderRole.partyId"/>
-            <set field="createReturnCtx.toPartyId" from-field="productStore.payToPartyId"/>
-            <set field="createReturnCtx.returnHeaderTypeId" value="CUSTOMER_RETURN"/>
-            <set field="createReturnCtx.returnReasonId" value="RTN_NORMAL_RETURN"/>
-            <set field="createReturnCtx.returnTypeId" value="RTN_RENTAL"/>
-            <set field="createReturnCtx.returnItemTypeId" value="RET_FDPROD_ITEM"/>
-            <set field="createReturnCtx.expectedItemStatus" value="INV_RETURNED"/>
-            <set field="createReturnCtx.returnPrice" value="0.00" type="BigDecimal"/>
-
-            <entity-condition entity-name="OrderItemAndProduct" list="orderItems">
-                <condition-list combine="and">
-                    <condition-expr field-name="orderId" operator="equals" from-field="orderHeader.orderId"/>
-                    <condition-expr field-name="statusId" operator="equals" value="ITEM_COMPLETED"/>
-                    <condition-expr field-name="productTypeId" operator="equals" value="ASSET_USAGE_OUT_IN"/>
-                </condition-list>
-            </entity-condition>
-            <iterate list="orderItems" entry="orderItem">
-                <set field="createReturnCtx.productId" from-field="orderItem.productId"/>
-                <set field="createReturnCtx.orderItemSeqId" from-field="orderItem.orderItemSeqId"/>
-                <set field="createReturnCtx.description" from-field="orderItem.itemDescription"/>
-                <set field="createReturnCtx.returnQuantity" from-field="orderItem.quantity"/>
-                <call-service service-name="createReturnAndItemOrAdjustment" in-map-name="createReturnCtx" include-user-login="true">
-                    <result-to-field result-name="returnId" field="returnId"/>
-                </call-service>
-                <if-not-empty field="returnId">
-                    <set field="createReturnCtx.returnId" from-field="returnId"/>
-                </if-not-empty>
-            </iterate>
-        </if-compare>
-    </simple-method>
-</simple-methods>
diff --git a/applications/order/servicedef/services_return.xml b/applications/order/servicedef/services_return.xml
index c64296f..c9cb8b5 100644
--- a/applications/order/servicedef/services_return.xml
+++ b/applications/order/servicedef/services_return.xml
@@ -24,8 +24,8 @@ under the License.
     <version>1.0</version>
 
     <!-- Order Return Services -->
-    <service name="quickReturnOrder" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="quickReturnFromOrder">
+    <service name="quickReturnOrder" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="quickReturnFromOrder">
         <description>Quick Return Order</description>
         <attribute name="orderId" type="String" mode="IN" optional="false"/>
         <attribute name="returnReasonId" type="String" mode="IN" optional="true"/>
@@ -34,15 +34,15 @@ under the License.
         <attribute name="receiveReturn" type="Boolean" mode="IN" optional="true"/>
         <attribute name="returnId" type="String" mode="OUT" optional="false"/>
     </service>
-    <service name="createReturnHeader" default-entity-name="ReturnHeader" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="createReturnHeader">
+    <service name="createReturnHeader" default-entity-name="ReturnHeader" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="createReturnHeader">
         <description>Create a new ReturnHeader</description>
         <auto-attributes include="pk" mode="OUT" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <override name="returnHeaderTypeId" optional="false"/>
     </service>
-    <service name="updateReturnHeader" default-entity-name="ReturnHeader" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="updateReturnHeader">
+    <service name="updateReturnHeader" default-entity-name="ReturnHeader" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="updateReturnHeader">
         <description>Update a ReturnHeader</description>
         <permission-service service-name="returnPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -55,8 +55,8 @@ under the License.
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
 
-    <service name="createReturnItem" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="createReturnItem">
+    <service name="createReturnItem" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="createReturnItem">
         <description>Create a new ReturnItem in the RETURN_REQUESTED status, based on returnableQuantity and returnablePrice from the
                      getReturnableQuantity service.  This can be called by the customer to request a return for himself or by a user with
                      ORDERMGR_CREATE, but, if the former, the returnPrice will be overriden by the returnablePrice from getReturnableQuantity.</description>
@@ -71,23 +71,23 @@ under the License.
         <override name="orderId" optional="false"/>
         <override name="returnQuantity" optional="false"/>
     </service>
-    <service name="updateReturnItem" engine="simple" default-entity-name="ReturnItem"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="updateReturnItem">
+    <service name="updateReturnItem" engine="groovy" default-entity-name="ReturnItem"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="updateReturnItem">
         <description>Update a ReturnItem and related adjustments</description>
         <permission-service service-name="returnPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <attribute name="oldStatusId" type="String" mode="OUT" optional="false"/>
     </service>
-    <service name="updateReturnItemsStatus" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="updateReturnItemsStatus">
+    <service name="updateReturnItemsStatus" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="updateReturnItemsStatus">
         <description>Update ReturnItem(s) Status</description>
         <permission-service service-name="returnPermissionCheck" main-action="UPDATE"/>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
         <attribute name="statusId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="removeReturnItem" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="removeReturnItem">
+    <service name="removeReturnItem" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="removeReturnItem">
         <description>Remove a ReturnItem and related adjustments</description>
         <permission-service service-name="returnPermissionCheck" main-action="DELETE"/>
         <auto-attributes entity-name="ReturnItem" include="pk" mode="IN" optional="false"/>
@@ -103,15 +103,15 @@ under the License.
                 the responseAmount is reached or all items are paid.</description>
         <attribute name="returnItemResponseId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="cancelReturnItems" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="cancelReturnItems">
+    <service name="cancelReturnItems" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="cancelReturnItems">
         <description>Cancel ReturnItems and set their status to "RETURN_CANCELLED"</description>
         <permission-service service-name="returnPermissionCheck" main-action="UPDATE"/>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
     </service>
 
-    <service name="cancelReplacementOrderItems" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="cancelReplacementOrderItems">
+    <service name="cancelReplacementOrderItems" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="cancelReplacementOrderItems">
         <description>Cancel the associated OrderItems of the replacement order, if any.</description>
         <permission-service service-name="returnPermissionCheck" main-action="UPDATE"/>
         <auto-attributes entity-name="ReturnItem" include="pk" mode="IN" optional="false"/>
@@ -136,13 +136,13 @@ under the License.
         <attribute name="originalReturnQuantity" type="BigDecimal" mode="IN" optional="true"/>
         <override name="returnAdjustmentId" optional="false"/>
     </service>
-    <service name="removeReturnAdjustment" engine="simple" location="component://order/minilang/order/OrderReturnServices.xml"
-                 invoke="removeReturnAdjustment">
+    <service name="removeReturnAdjustment" engine="entity-auto" default-entity-name="ReturnAdjustment"
+                 invoke="delete">
         <description>Simple remove service</description>
         <permission-service service-name="returnPermissionCheck" main-action="DELETE"/>
         <auto-attributes entity-name="ReturnAdjustment" include="pk" mode="IN" optional="false"/>
     </service>
-    <service name="createReturnAndItemOrAdjustment" engine="simple" location="component://order/minilang/order/OrderReturnServices.xml"
+    <service name="createReturnAndItemOrAdjustment" engine="groovy" location="component://order/groovyScripts/order/OrderReturnServices.groovy"
                  invoke="createReturnAndItemOrAdjustment">
         <description>If returnId is null, create a return; then create Return Item or Adjustment based on the parameters passed in</description>
         <auto-attributes mode="IN" include="nonpk" entity-name="ReturnHeader" optional="true"/>
@@ -238,38 +238,38 @@ under the License.
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
         <attribute name="returnTypeId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="processWaitReplacementReturn" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="processWaitReplacementReturn">
+    <service name="processWaitReplacementReturn" engine="groovy" auth="true"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="processWaitReplacementReservedReturn">
         <description>Process the replacements in a wait return</description>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="processWaitReplacementReservedReturn" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="processWaitReplacementReservedReturn">
+    <service name="processWaitReplacementReservedReturn" engine="groovy" auth="true"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="processWaitReplacementReservedReturn">
         <description>Process the replacements in a wait reserved return when the return is accepted and then received</description>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="processCrossShipReplacementReturn" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="processCrossShipReplacementReturn">
+    <service name="processCrossShipReplacementReturn" engine="groovy" auth="true"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="processCrossShipReplacementReturn">
         <description>Process the replacements in a cross-ship return</description>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="processRepairReplacementReturn" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="processRepairReplacementReturn">
+    <service name="processRepairReplacementReturn" engine="groovy" auth="true"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="processRepairReplacementReturn">
         <description>Process the replacements in a repair return</description>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="processReplaceImmediatelyReturn" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="processReplaceImmediatelyReturn">
+    <service name="processReplaceImmediatelyReturn" engine="groovy" auth="true"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="processReplaceImmediatelyReturn">
         <description>Process the replacements in a Immediate Return</description>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="processRefundOnlyReturn" engine="simple"  auth="true"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="processRefundOnlyReturn">
+    <service name="processRefundOnlyReturn" engine="groovy"  auth="true"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="processRefundOnlyReturn">
         <description>Process the Refund in a return</description>    
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="processRefundImmediatelyReturn" engine="simple"  auth="true"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="processRefundImmediatelyReturn">
+    <service name="processRefundImmediatelyReturn" engine="groovy"  auth="true"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="processRefundImmediatelyReturn">
         <description>Process the Immediate Refund in a return</description>    
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
     </service>
@@ -285,8 +285,8 @@ under the License.
     </service>
 
     <!-- other return services -->
-    <service name="updateReturnStatusFromReceipt" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="updateReturnStatusFromReceipt">
+    <service name="updateReturnStatusFromReceipt" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="updateReturnStatusFromReceipt">
         <description>Update return/item status when items have been received</description>
         <permission-service service-name="returnPermissionCheck" main-action="UPDATE"/>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
@@ -325,35 +325,34 @@ under the License.
         <attribute name="paymentId" type="String" mode="OUT" optional="false"/>
     </service>
 
-    <service name="createReturnItemShipment" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="createReturnItemShipment">
+    <service name="createReturnItemShipment" engine="entity-auto" default-entity-name="ReturnItemShipment" invoke="create">
         <description>Create a new ReturnItemShipment</description>
         <permission-service service-name="returnPermissionCheck" main-action="CREATE"/>
-        <auto-attributes entity-name="ReturnItemShipment" include="all" mode="IN" optional="false"/>
+        <auto-attributes include="all" mode="IN" optional="false"/>
     </service>
 
-    <service name="getStatusItemsForReturn" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="getStatusItemsForReturn">
+    <service name="getStatusItemsForReturn" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="getStatusItemsForReturn">
         <description>Get the return status associated with customer/vendor return</description>
         <attribute name="returnHeaderTypeId" type="String" mode="IN" optional="false"/>
         <attribute name="statusItems" type="List" mode="OUT" optional="false"/>
     </service>
 
-    <service name="createExchangeOrderAssoc" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="createExchangeOrderAssoc">
+    <service name="createExchangeOrderAssoc" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="createExchangeOrderAssoc">
         <description>Associate exchange order with original order in OrderItemAssoc entity</description>
         <attribute name="orderId" type="String" mode="IN" optional="false"/>
         <attribute name="originOrderId" type="String" mode="IN" optional="false"/>
     </service>
 
-    <service name="addProductsBackToCategory" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="addProductsBackToCategory">
+    <service name="addProductsBackToCategory" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="addProductsBackToCategory">
         <description>Add product(s) back to category if it has no active category</description>
         <attribute name="returnId" type="String" mode="IN" optional="true"/>
         <attribute name="inventoryItemId" type="String" mode="IN" optional="true"/>
     </service>
-    <service name="createReturnStatus" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="createReturnStatus">
+    <service name="createReturnStatus" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="createReturnStatus">
         <description>Create Return Status</description>
         <attribute name="returnId" type="String" mode="IN" optional="false"/>
         <attribute name="returnItemSeqId" type="String" mode="IN" optional="true"/>
@@ -365,8 +364,8 @@ under the License.
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="updateReturnContactMech" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="updateReturnContactMech" auth="true" default-entity-name="ReturnContactMech">
+    <service name="updateReturnContactMech" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="updateReturnContactMech" auth="true" default-entity-name="ReturnContactMech">
         <description>Update Return Contact Mech</description>
         <permission-service service-name="returnPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -378,8 +377,8 @@ under the License.
     </service>
 
     <!-- Item Return Service -->
-    <service name="createReturnItemForRental" engine="simple"
-            location="component://order/minilang/order/OrderReturnServices.xml" invoke="createReturnItemForRental">
+    <service name="createReturnItemForRental" engine="groovy"
+            location="component://order/groovyScripts/order/OrderReturnServices.groovy" invoke="createReturnItemForRental">
         <description>Create the return item for rental (which items has product type is ASSET_USAGE_OUT_IN)</description>
         <attribute name="orderId" type="String" mode="IN" optional="false"/>
         <attribute name="returnId" type="String" mode="OUT" optional="false"/>