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"/>