diff --git a/applications/order/minilang/customer/CheckoutMapProcs.xml b/applications/order/minilang/customer/CheckoutMapProcs.xml
index 50d4c35b9d8..8f74f5dad9e 100644
--- a/applications/order/minilang/customer/CheckoutMapProcs.xml
+++ b/applications/order/minilang/customer/CheckoutMapProcs.xml
@@ -48,96 +48,6 @@ under the License.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/applications/order/minilang/order/OrderServices.xml b/applications/order/minilang/order/OrderServices.xml
deleted file mode 100644
index 1147b39bce1..00000000000
--- a/applications/order/minilang/order/OrderServices.xml
+++ /dev/null
@@ -1,978 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/applications/order/servicedef/services.xml b/applications/order/servicedef/services.xml
index 74b9ed49c2f..a9bb6a723a2 100644
--- a/applications/order/servicedef/services.xml
+++ b/applications/order/servicedef/services.xml
@@ -483,8 +483,8 @@ under the License.
-
+
Remove all existing order adjustments, recalc them and persist in OrderAdjustment.
@@ -560,8 +560,8 @@ under the License.
-
+
Compute and return the OrderItemShipGroup estimated ship date based on the associated items.
@@ -608,9 +608,11 @@ under the License.
-
- Toggle Order Note and make it either Public or Private
+
+ Update OrderHeader
+
+
+
@@ -698,8 +700,8 @@ under the License.
-
+
Gets the order status
@@ -867,23 +869,25 @@ under the License.
-
+
-
+
Create OrderHeader
-
+
Update OrderHeader
+
+
+
@@ -924,8 +928,9 @@ under the License.
-
+
+
Updates OrderItemShipGroup. The shipmentMethod field is of the format ${shipmentMethodTypeId}@${carrierPartyId}
@@ -942,8 +947,8 @@ under the License.
-
+
Update Order Contact Mech
@@ -993,8 +998,8 @@ under the License.
-
+
Add Payment Method to Order.From this servicewe will call the createOrderPaymentPreference service to create OrderPaymentPreference
@@ -1152,8 +1157,8 @@ under the License.
-
+
Check if an Order is on Back Order
@@ -1201,8 +1206,8 @@ under the License.
-
+
Creates a new OrderItemChange record
@@ -1216,8 +1221,8 @@ under the License.
This is done by looking for all subscriptions which are active and where the automaticExtend flag is set to "Y"
-
+
Creates new shipping address and update existing address
@@ -1257,8 +1262,8 @@ under the License.
-
+
Creates new billing address and update existing address
@@ -1279,8 +1284,8 @@ under the License.
-
+
Create/Update credit card
@@ -1322,8 +1327,8 @@ under the License.
-
+
Sets unit price as last price for product
@@ -1337,13 +1342,13 @@ under the License.
-
+
Cancels those back orders from suppliers whose cancel back order date (cancelBackOrderDate) has passed the current date
-
+
Compare order's shipping amount and new shipping amount(based on weight and dimension of packages).If new shipping amount is more then or less than default percentage (defined in shipment.properties) of Order's shipping amount, then shipping method and shipping charges are updated. And if new shipping amount is not more then or less than default percentage (defined in shipment.properties)% of Order's shipping amount then only shipping method is updated.Also updates record in ShipmentRouteSegment entity
@@ -1447,8 +1452,8 @@ under the License.
-
+
Calculate ATP and QOH According For each facility
@@ -1498,8 +1503,8 @@ under the License.
-
+
Create Order Payment Application
@@ -1552,8 +1557,8 @@ under the License.
-
+
Move order items between ship groups
diff --git a/applications/order/src/main/groovy/org/apache/ofbiz/order/customer/CheckoutMapProcs.groovy b/applications/order/src/main/groovy/org/apache/ofbiz/order/customer/CheckoutMapProcs.groovy
new file mode 100644
index 00000000000..849726ae770
--- /dev/null
+++ b/applications/order/src/main/groovy/org/apache/ofbiz/order/customer/CheckoutMapProcs.groovy
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.ofbiz.order.customer
+
+static Map shipToAddress(Map parameters) {
+ Map processedMap = [:]
+ if (parameters.shipToContactMechId) {
+ processedMap.contactMechId = parameters.shipToContactMechId
+ }
+ if (parameters.shipToName) {
+ processedMap.toName = parameters.shipToName
+ }
+ if (parameters.shipToAttnName) {
+ processedMap.attnName = parameters.shipToAttnName
+ }
+ if (parameters.shipToAddress1) {
+ processedMap.address1 = parameters.shipToAddress1
+ } else {
+ return error(label('PartyUiLabels', 'PartyAddressLine1MissingError'))
+ }
+ if (parameters.shipToAddress2) {
+ processedMap.address2 = parameters.shipToAddress2
+ }
+ if (parameters.shipToCity) {
+ processedMap.city = parameters.shipToCity
+ } else {
+ return error(label('PartyUiLabels', 'PartyCityMissing'))
+ }
+ if (parameters.shipToStateProvinceGeoId) {
+ processedMap.stateProvinceGeoId = parameters.shipToStateProvinceGeoId
+ } else {
+ return error(label('PartyUiLabels', 'PartyStateMissingError'))
+ }
+ if (parameters.shipToPostalCode) {
+ processedMap.postalCode = parameters.shipToPostalCode
+ } else {
+ return error(label('PartyUiLabels', 'PartyPostalInformationNotFound'))
+ }
+ if (parameters.shipToCountryGeoId) {
+ processedMap.countryGeoId = parameters.shipToCountryGeoId
+ } else {
+ return error(label('PartyUiLabels', 'PartyCountryMissing'))
+ }
+ return processedMap
+}
+
+static Map billToAddress(Map parameters) {
+ Map processedMap = [:]
+ if (parameters.billToContactMechId) {
+ processedMap.contactMechId = parameters.billToContactMechId
+ }
+ if (parameters.billToName) {
+ processedMap.toName = parameters.billToName
+ }
+ if (parameters.billToAttnName) {
+ processedMap.attnName = parameters.billToAttnName
+ }
+ if (parameters.billToAddress1) {
+ processedMap.address1 = parameters.billToAddress1
+ } else {
+ return error(label('PartyUiLabels', 'PartyAddressLine1MissingError'))
+ }
+ if (parameters.billToAddress2) {
+ processedMap.address2 = parameters.billToAddress2
+ }
+ if (parameters.billToCity) {
+ processedMap.city = parameters.billToCity
+ } else {
+ return error(label('PartyUiLabels', 'PartyCityMissing'))
+ }
+ if (parameters.billToStateProvinceGeoId) {
+ processedMap.stateProvinceGeoId = parameters.billToStateProvinceGeoId
+ } else {
+ return error(label('PartyUiLabels', 'PartyStateMissingError'))
+ }
+ if (parameters.billToPostalCode) {
+ processedMap.postalCode = parameters.billToPostalCode
+ } else {
+ return error(label('PartyUiLabels', 'PartyPostalInformationNotFound'))
+ }
+ if (parameters.billToCountryGeoId) {
+ processedMap.countryGeoId = parameters.billToCountryGeoId
+ } else {
+ return error(label('PartyUiLabels', 'PartyCountryMissing'))
+ }
+ return processedMap
+}
\ No newline at end of file
diff --git a/applications/order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy b/applications/order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy
index 41764950d68..c2fd7b665db 100644
--- a/applications/order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy
+++ b/applications/order/src/main/groovy/org/apache/ofbiz/order/order/OrderServicesScript.groovy
@@ -18,13 +18,41 @@
*/
package org.apache.ofbiz.order.order
+import org.apache.ofbiz.base.util.GeneralException
+import org.apache.ofbiz.base.util.ObjectType
import org.apache.ofbiz.base.util.UtilDateTime
+import org.apache.ofbiz.base.util.UtilProperties
import org.apache.ofbiz.entity.GenericValue
import org.apache.ofbiz.entity.condition.EntityCondition
import org.apache.ofbiz.entity.condition.EntityConditionBuilder
+import org.apache.ofbiz.entity.condition.EntityOperator
+import org.apache.ofbiz.order.customer.CheckoutMapProcs
+import org.apache.ofbiz.order.shoppingcart.ShoppingCart
+import org.apache.ofbiz.order.shoppingcart.ShoppingCartItem
import java.sql.Timestamp
+/**
+ * Service to create OrderHeader
+ */
+Map createOrderHeader() {
+ Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
+ if (!(security.hasEntityPermission('ORDERMGR', '_CREATE', parameters.userLogin))) {
+ return error(label('OrderErrorUiLabels', 'OrderSecurityErrorToRunCreateOrderShipment'))
+ }
+
+ GenericValue orderHeader = makeValue('OrderHeader',
+ [orderId: parameters.orderId ?: delegator.getNextSeqId('OrderHeader')])
+ orderHeader.with {
+ setNonPKFields(parameters)
+ statusId = orderHeader.statusId ?: 'ORDER_CREATED'
+ orderDate = orderHeader.orderDate ?: nowTimestamp
+ entryDate = orderHeader.entryDate ?: nowTimestamp
+ create()
+ }
+ return success([orderId: orderHeader.orderId])
+}
+
/**
* Service to get the next OrderId
*/
@@ -49,8 +77,8 @@ Map getNextOrderId() {
String orderIdTemp
if (customMethodName) {
parameters.partyAcctgPreference = partyAcctgPreference
- Map result = run service: customMethodName, with: parameters
- orderIdTemp = result.orderId
+ Map serviceResult = run service: customMethodName, with: parameters
+ orderIdTemp = serviceResult.orderId
} else {
logInfo 'In getNextOrderId sequence by Standard'
// default to the default sequencing: ODRSQ_STANDARD
@@ -63,14 +91,7 @@ Map getNextOrderId() {
}
// use orderIdTemp along with the orderIdPrefix to create the real ID
- String orderId = ''
- if (productStore) {
- orderId += productStore.orderNumberPrefix ?: ''
- }
- if (partyAcctgPreference) {
- orderId += partyAcctgPreference.orderIdPrefix ?: ''
- }
- orderId += orderIdTemp.toString()
+ String orderId = "${productStore?.orderNumberPrefix ?: ''}${partyAcctgPreference?.orderIdPrefix ?: ''}${orderIdTemp as String}"
return success([orderId: orderId])
}
@@ -89,17 +110,18 @@ Map getOrderedSummaryInformation() {
*/
Timestamp fromDate = null, thruDate = null
Timestamp now = UtilDateTime.nowTimestamp()
+ Integer monthsToInclude = parameters.monthsToInclude
if (monthsToInclude) {
thruDate = now
fromDate = UtilDateTime.adjustTimestamp(now, Calendar.MONTH, -monthsToInclude)
}
- roleTypeId = roleTypeId ?: 'PLACING_CUSTOMER'
- orderTypeId = orderTypeId ?: 'SALES_ORDER'
- statusId = statusId ?: 'ORDER_COMPLETED'
+ String roleTypeId = parameters.roleTypeId ?: 'PLACING_CUSTOMER'
+ String orderTypeId = parameters.orderTypeId ?: 'SALES_ORDER'
+ String statusId = parameters.statusId ?: 'ORDER_COMPLETED'
//find the existing exchange rates
- exprBldr = new EntityConditionBuilder()
+ EntityConditionBuilder exprBldr = new EntityConditionBuilder()
EntityCondition condition = exprBldr.AND {
EQUALS(partyId: partyId)
@@ -128,14 +150,778 @@ Map getOrderedSummaryInformation() {
}
}
- orderInfo = select('partyId', 'roleTypeId', 'totalGrandAmount', 'totalSubRemainingAmount', 'totalOrders')
+ GenericValue orderInfo = select('partyId', 'roleTypeId', 'totalGrandAmount', 'totalSubRemainingAmount', 'totalOrders')
.from('OrderHeaderAndRoleSummary').where(condition).queryFirst()
// first set the required OUT fields to zero
- result = success()
- result.totalGrandAmount = orderInfo ? orderInfo.totalGrandAmount : BigDecimal.ZERO
- result.totalSubRemainingAmount = orderInfo ? orderInfo.totalSubRemainingAmount : BigDecimal.ZERO
- result.totalOrders = orderInfo ? orderInfo.totalOrders : 0L
+ return success([
+ totalGrandAmount: orderInfo ? orderInfo.totalGrandAmount : BigDecimal.ZERO,
+ totalSubRemainingAmount: orderInfo ? orderInfo.totalSubRemainingAmount : BigDecimal.ZERO,
+ totalOrders: orderInfo ? orderInfo.totalOrders : 0L])
+}
+
+/**
+ * Service to get enforced Sequence (no gaps, per organization)
+ */
+Map orderSequence_enforced() {
+ logInfo 'In getNextOrderId sequence enum Enforced'
+ GenericValue partyAcctgPreference = parameters.partyAcctgPreference
+ // this is sequential sequencing, we can't skip a number, also it must be a unique sequence per partyIdFrom
+
+ partyAcctgPreference.lastOrderNumber = partyAcctgPreference.lastOrderNumber
+ ? partyAcctgPreference.lastOrderNumber + 1
+ : 1
+
+ partyAcctgPreference.store()
+ return success([orderId: partyAcctgPreference.lastOrderNumber])
+}
+
+/**
+ * Service to automatically create OrderAdjustments
+ */
+Map recreateOrderAdjustments() {
+ GenericValue order = from('OrderHeader').where(context).queryOne()
+
+ // All existing promo order items are cancelled
+ List orderItems = order.getRelated('OrderItem', null, null, false)
+ for (GenericValue orderItem : orderItems) {
+ if (orderItem.isPromo == 'Y' && orderItem.statusId != 'ITEM_CANCELLED') {
+ run service: 'cancelOrderItemNoActions', with: [*: parameters,
+ orderItemSeqId: orderItem.orderItemSeqId]
+ }
+ }
+
+ List orderAdjustments = order.getRelated('OrderAdjustment', null, null, false)
+ // Accumulate the total existing promotional adjustment
+ BigDecimal existingOrderAdjustmentTotal = BigDecimal.ZERO
+ for (GenericValue orderAdjustment : orderAdjustments) {
+ if (orderAdjustment.orderAdjustmentTypeId == 'PROMOTION_ADJUSTMENT' ) {
+ existingOrderAdjustmentTotal = existingOrderAdjustmentTotal.add(orderAdjustment.getBigDecimal('amount').setScale(3))
+ }
+ }
+
+ // Recalculate the promotions for the order
+ Map serviceCtx = [*: parameters,
+ skipInventoryChecks: true,
+ skipProductChecks: true]
+ Map loadCartFromOrderInMap = dispatcher.runSync('loadCartFromOrder', serviceCtx)
+ ShoppingCart cart = loadCartFromOrderInMap.shoppingCart
+ List items = cart.items()
+ for (ShoppingCartItem item : items) {
+ String orderItemSeqId = item.getOrderItemSeqId()
+ if (!orderItemSeqId) {
+ // this is a new (promo) item
+ // a new order item is created
+ GenericValue newOrderItem = makeValue('OrderItem')
+ newOrderItem.with {
+ orderId = parameters.orderId
+ orderItemTypeId = item.getItemType()
+ selectedAmount = item.getSelectedAmount()
+ unitPrice = item.getBasePrice()
+ unitListPrice = item.getListPrice()
+ itemDescription = item.getName(dispatcher)
+ statusId = item.getStatusId()
+ productId = item.getProductId()
+ quantity = item.getQuantity()
+ isModifiedPrice = 'N'
+ isPromo = 'Y'
+ statusId = newOrderItem.statusId ?: 'ITEM_CREATED'
+ }
+ newOrderItem.orderItemSeqId = delegator.getNextSeqId('OrderItem')
+ newOrderItem.create()
+ // And the orderItemSeqId is assigned to the shopping cart item
+ item.setOrderItemSeqId(newOrderItem.orderItemSeqId)
+ }
+ }
+ List adjustments = cart.makeAllAdjustments()
+
+ // Accumulate the new promotion total from the recalculated promotion adjustments
+ BigDecimal newOrderAdjustmentTotal = BigDecimal.ZERO
+ for (GenericValue adjustment : adjustments) {
+ if (adjustment.productPromoId && !adjustment.orderAdjustmentId) {
+ newOrderAdjustmentTotal = newOrderAdjustmentTotal.add(adjustment.getBigDecimal('amount').setScale(3))
+ }
+ }
- return result
+ // Determine the difference between existing and new promotion adjustment totals, if any
+ BigDecimal orderAdjustmentTotalDifference = newOrderAdjustmentTotal.subtract(existingOrderAdjustmentTotal)
+
+ // If the total has changed, create an OrderAdjustment to reflect the fact
+ if (orderAdjustmentTotalDifference != 0) {
+ run service: 'createOrderAdjustment',
+ with: [orderAdjustmentTypeId: 'PROMOTION_ADJUSTMENT',
+ orderId: parameters.orderId,
+ orderItemSeqId: '_NA_',
+ shipGroupSeqId: '_NA_',
+ description: 'Adjustment due to order change',
+ amount: orderAdjustmentTotalDifference
+ ]
+ }
+ return success()
+}
+
+/*
+ * Update OrderContactMech
+ */
+Map updateOrderContactMech() {
+ if (!(security.hasEntityPermission('ORDERMGR', '_UPDATE', parameters.userLogin))) {
+ return error(label('OrderErrorUiLabels', 'OrderSecurityErrorToRunUpdateOrderContactMech'))
+ }
+
+ if (parameters.contactMechPurposeTypeId == 'SHIPPING_LOCATION' &&
+ parameters.contactMechId != parameters.oldContactMechId) {
+ Map orderItemShipGroupMap = [orderId: parameters.orderId]
+ if (parameters.oldContactMechId) {
+ orderItemShipGroupMap.contactMechId = parameters.oldContactMechId
+ }
+ List shipGroupList = from('OrderItemShipGroup')
+ .where(orderItemShipGroupMap)
+ .queryList()
+ if (shipGroupList) {
+ for (GenericValue shipGroup: shipGroupList) {
+ run service: 'updateOrderItemShipGroup', with: [
+ orderId: parameters.orderId,
+ contactMechId: parameters.contactMechId,
+ contactMechPurposeTypeId: parameters.contactMechPurposeTypeId,
+ shipGroupSeqId: shipGroup.shipGroupSeqId,
+ shipmentMethod: "${shipGroup.shipmentMethodTypeId}@${shipGroup.carrierPartyId}@${shipGroup.carrierRoleTypeId}",
+ oldContactMechId: parameters.oldContactMechId]
+ }
+ }
+ } else {
+ List orderContactMechList = from('OrderContactMech')
+ .where(orderId: parameters.orderId,
+ contactMechPurposeTypeId: parameters.contactMechPurposeTypeId,
+ contactMechId: parameters.contactMechId)
+ .queryList()
+ // If orderContactMechList value is null then create new entry in OrderContactMech entity
+ if (!orderContactMechList) {
+ run service: 'createOrderContactMech', with: parameters
+ if (parameters.oldContactMechId) {
+ run service: 'removeOrderContactMech', with: [
+ orderId: parameters.orderId,
+ contactMechId: parameters.oldContactMechId,
+ contactMechPurposeTypeId: parameters.contactMechPurposeTypeId]
+ }
+ }
+ }
+ return success()
+}
+
+/*
+ * Update OrderItemShipGroup
+ */
+Map updateOrderItemShipGroup() {
+ if (!(security.hasEntityPermission('ORDERMGR', '_UPDATE', parameters.userLogin))) {
+ return error(label('OrderErrorUiLabels', 'OrderSecurityErrorToRunUpdateOrderItemShipGroup'))
+ }
+ GenericValue lookedUpValue = from('OrderItemShipGroup')
+ .where(parameters)
+ .queryOne()
+
+ // splitting shipmentMethod request parameter value that contains '@' symbol into
+ // 'shipmentMethodTypeId', 'carrierPartyId' and 'carrierRoleTypeId'.
+ String shipmentMethod = parameters.shipmentMethod
+ if (shipmentMethod != null) {
+ String[] arr = shipmentMethod.split( '@' )
+ parameters.put('shipmentMethodTypeId', arr[0])
+ parameters.put('carrierPartyId', arr[1])
+ parameters.put('carrierRoleTypeId', arr[2])
+ }
+ lookedUpValue.setNonPKFields(parameters)
+
+ Map inputMap = [orderId: parameters.orderId,
+ contactMechPurposeTypeId: parameters.contactMechPurposeTypeId]
+ if (parameters.contactMechId) {
+ inputMap.contactMechId = parameters.contactMechId
+ }
+ List orderContactMechList = from('OrderContactMech')
+ .where(inputMap)
+ .queryList()
+ // If orderContactMechList value is null then create new entry in OrderContactMech entity
+ if (!orderContactMechList && parameters.contactMechId) {
+ run service: 'createOrderContactMech', with: [*: inputMap]
+ }
+ lookedUpValue.store()
+
+ // Remove the old values from OrderContactMech entity with the help of oldContactMechId
+ Map shipGroupLookupMap = [orderId: parameters.orderId]
+ if (parameters.oldContactMechId) {
+ shipGroupLookupMap.contactMechId = parameters.oldContactMechId
+ }
+ List orderItemShipGroupList = from('OrderItemShipGroup')
+ .where(shipGroupLookupMap)
+ .queryList()
+ if (!orderItemShipGroupList) {
+ inputMap.contactMechId = parameters.oldContactMechId
+ run service: 'removeOrderContactMech', with: [*: inputMap]
+ }
+
+ // Update promisedDateTime & currentPromisedDate in OrderItemShipGrpInvRes entity
+ List itemShipGrpInvResList = from('OrderItemShipGrpInvRes')
+ .where('orderId', parameters.orderId,
+ 'shipGroupSeqId', parameters.shipGroupSeqId)
+ .queryList()
+ if (itemShipGrpInvResList) {
+ for (GenericValue orderItemShipGrpInvRes: itemShipGrpInvResList) {
+ orderItemShipGrpInvRes.promisedDatetime = parameters.shipByDate
+ orderItemShipGrpInvRes.currentPromisedDate = parameters.shipByDate
+ orderItemShipGrpInvRes.store()
+ }
+ }
+ return success()
+}
+
+/*
+ * Compute and return the OrderItemShipGroup estimated ship date based on the associated items.
+ */
+Map getOrderItemShipGroupEstimatedShipDate() {
+ GenericValue orderItemShipGroup = from('OrderItemShipGroup')
+ .where('orderId', parameters.orderId,
+ 'contactMechId', parameters.oldContactMechId)
+ .queryFirst()
+ GenericValue orderItemShipGroupInvRes = from('OrderItemShipGrpInvRes')
+ .where('orderId', parameters.orderId,
+ 'shipGroupSeqId', parameters.shipGroupSeqId)
+ .orderBy((orderItemShipGroup.maySplit == 'Y' ? '+' : '-') + 'promisedDatetime')
+ .queryFirst()
+ return success(estimatedShipDate: orderItemShipGroupInvRes.promisedDatetime)
+}
+
+/*
+ * Create a PaymentMethodToOrder
+ */
+Map addPaymentMethodToOrder() {
+ if (!(security.hasEntityPermission('ORDERMGR', '_CREATE', parameters.userLogin))) {
+ return error(label('OrderErrorUiLabels', 'OrderSecurityErrorToRunAddPaymentMethodToOrder'))
+ }
+ GenericValue paymentMethod = from('PaymentMethod')
+ .where('paymentMethodId', parameters.paymentMethodId)
+ .queryOne()
+
+ // In this method we calls createOrderPaymentPreference and returns orderPaymentPreferenceId field to authOrderPaymentPreference
+ return (run service: 'createOrderPaymentPreference', with: [
+ orderId: parameters.orderId,
+ maxAmount: parameters.maxAmount,
+ paymentMethodId: parameters.paymentMethodId,
+ paymentMethodTypeId: paymentMethod.paymentMethodTypeId])
+}
+
+/*
+ * Gets an order status
+ */
+Map getOrderStatus() {
+ GenericValue order = from('OrderHeader').where(parameters).queryOne()
+ return order
+ ? success(statusId: order.statusId)
+ : error(label('OrderErrorUiLabels', 'OrderOrderIdDoesNotExists'))
+}
+
+/*
+ * Check if an Order is on Back Order
+ */
+Map checkOrderIsOnBackOrder() {
+ EntityCondition condition = new EntityConditionBuilder().AND {
+ EQUALS(orderId: parameters.orderId)
+ NOT_EQUAL(quantityNotAvailable: null)
+ GREATER_THAN_EQUAL_TO(quantityNotAvailable: BigDecimal.ZERO)
+ }
+ return success([isBackOrder: from('OrderItemShipGrpInvRes')
+ .where(condition)
+ .queryCount() > 0])
+}
+
+/*
+ * Creates a new Order Item Change record
+ */
+Map createOrderItemChange() {
+ GenericValue newEntity = makeValue('OrderItemChange',
+ [*: parameters,
+ orderItemChangeId: delegator.getNextSeqId('OrderItemChange'),
+ changeDatetime: parameters.changeDatetime ?: UtilDateTime.nowTimestamp(),
+ changeUserLogin: parameters.changeUserLogin ?: userLogin.userLoginId])
+ newEntity.create()
+ return success([orderItemChangeId: newEntity.orderItemChangeId])
+}
+
+/*
+ * Create and update a Shipping Address
+ */
+Map createUpdateShippingAddress() {
+ String contactMechId = parameters.shipToContactMechId
+ String keepAddressBook = parameters.keepAddressBook ?: 'Y'
+ // Call map Processor
+ Map shipToAddressCtx = CheckoutMapProcs.shipToAddress(parameters)
+ String partyId = parameters.partyId
+ shipToAddressCtx.partyId = partyId
+
+ if (!contactMechId) {
+ shipToAddressCtx.contactMechPurposeTypeId = 'SHIPPING_LOCATION'
+ Map serviceResult = run service: 'createPartyPostalAddress', with: shipToAddressCtx
+ parameters.shipToContactMechId = serviceResult.contactMechId
+ logInfo("Shipping address created with contactMechId ${parameters.shipToContactMechId}")
+ } else if (keepAddressBook == 'Y') {
+ GenericValue newValue = makeValue('PostalAddress', shipToAddressCtx)
+ GenericValue oldValue = from('PostalAddress').where(parameters).queryOne()
+ if (newValue != oldValue) {
+ shipToAddressCtx.contactMechId = null
+ Map serviceResult = run service: 'createPartyPostalAddress', with: shipToAddressCtx
+ parameters.shipToContactMechId = serviceResult.contactMechId
+ }
+
+ List pcmpShipList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechId: parameters.shipToContactMechId,
+ contactMechPurposeTypeId: 'SHIPPING_LOCATION')
+ .filterByDate()
+ .queryList()
+ // If purpose does not exists then create
+ if (!pcmpShipList) {
+ List pcmpList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechPurposeTypeId: 'SHIPPING_LOCATION')
+ .filterByDate()
+ .queryList()
+ for (GenericValue pcmp: pcmpList) {
+ run service: 'expirePartyContactMechPurpose', with: pcmp.getAllFields()
+ }
+ run service: 'createPartyContactMechPurpose', with: [*: parameters,
+ partyId: partyId,
+ contactMechId: parameters.shipToContactMechId,
+ contactMechPurposeTypeId: 'SHIPPING_LOCATION']
+ }
+ if (parameters.setDefaultShipping == 'Y') {
+ run service: 'setPartyProfileDefaults', with: [partyId: partyId,
+ productStoreId: parameters.productStoreId,
+ defaultShipAddr: parameters.shipToContactMechId]
+ }
+ } else {
+ shipToAddressCtx.shipToContactMechId = shipToAddressCtx.contactMechId
+ if (shipToAddressCtx.shipToContactMechId == parameters.billToContactMechId) {
+ GenericValue newValue = makeValue('PostalAddress', shipToAddressCtx)
+ GenericValue oldValue = from('PostalAddress').where(parameters).queryOne()
+ if (newValue != oldValue) {
+ List pcmpShipList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechId: shipToAddressCtx.shipToContactMechId,
+ contactMechPurposeTypeId: 'SHIPPING_LOCATION')
+ .filterByDate()
+ .queryList()
+ for (GenericValue pcmp: pcmpShipList) {
+ run service: 'expirePartyContactMechPurpose', with: pcmp.getAllFields()
+ }
+ Map serviceResult = run service: 'createPartyPostalAddress', with: [*: shipToAddressCtx,
+ partyId: partyId,
+ contactMechId: null,
+ contactMechPurposeTypeId: 'SHIPPING_LOCATION']
+ parameters.shipToContactMechId = serviceResult.contactMechId
+ logInfo("Shipping address updated with contactMechId ${shipToAddressCtx.shipToContactMechId}")
+ }
+ } else {
+ shipToAddressCtx.userLogin = parameters.userLogin
+ Map serviceResult = run service: 'updatePartyPostalAddress', with: shipToAddressCtx
+ parameters.shipToContactMechId = serviceResult.contactMechId
+ logInfo("Shipping address updated with contactMechId ${shipToAddressCtx.shipToContactMechId}")
+ }
+ }
+ return success([contactMechId: parameters.shipToContactMechId])
+}
+
+/*
+ * Create and update Billing Address
+ */
+Map createUpdateBillingAddress() {
+ String keepAddressBook = parameters.keepAddressBook ?: 'Y'
+ Map billToAddressCtx = [:]
+ if (parameters.useShippingAddressForBilling != 'Y') {
+ // Call map Processor
+ billToAddressCtx = CheckoutMapProcs.billToAddress(parameters)
+ }
+ String partyId = parameters.partyId
+ billToAddressCtx.partyId = partyId
+
+ if (parameters.useShippingAddressForBilling == 'Y') {
+ if (parameters.billToContactMechId) {
+ if (parameters.shipToContactMechId != parameters.billToContactMechId) {
+ List pcmpList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechId: parameters.billToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION')
+ .filterByDate()
+ .queryList()
+ for (GenericValue pcmp: pcmpList) {
+ run service: 'deletePartyContactMech', with: pcmp.getAllFields()
+ }
+ if (keepAddressBook == 'N') {
+ run service: 'createPartyContactMechPurpose', with: [contactMechId: parameters.billToContactMechId]
+ }
+ // Check that the ship-to address doesn't already have a bill-to purpose
+ pcmpList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechId: parameters.shipToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION')
+ .filterByDate()
+ .queryList()
+ if (!pcmpList) {
+ Map serviceContext = [*: parameters,
+ partyId: partyId,
+ contactMechId: parameters.shipToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ run service: 'createPartyContactMechPurpose', with: serviceContext
+ }
+ logInfo("Billing address updated with contactMechId ${parameters.billToContactMechId}")
+ }
+ } else {
+ Map serviceContext = [*: parameters,
+ partyId: partyId,
+ contactMechId: parameters.shipToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ run service: 'createPartyContactMechPurpose', with: serviceContext
+ }
+ parameters.billToContactMechId = parameters.shipToContactMechId
+ } else {
+ if (parameters.billToContactMechId) {
+ if (parameters.shipToContactMechId == parameters.billToContactMechId) {
+ Map serviceResult = run service: 'createPartyPostalAddress', with: [*: billToAddressCtx,
+ contactMechId: null,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ parameters.billToContactMechId = serviceResult.contactMechId
+
+ List pcmpList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION')
+ .filterByDate()
+ .queryList()
+ for (GenericValue pcmp: pcmpList) {
+ run service: 'expirePartyContactMechPurpose', with: pcmp.getAllFields()
+ }
+ serviceContext = [*: parameters,
+ partyId: partyId,
+ contactMechId: parameters.billToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ run service: 'createPartyContactMechPurpose', with: serviceContext
+ logInfo("Billing address updated with contactMechId ${parameters.billToContactMechId}")
+ } else {
+ if (keepAddressBook == 'N') {
+ billToAddressCtx.userLogin = parameters.userLogin
+ Map serviceResult = run service: 'updatePartyPostalAddress', with: billToAddressCtx
+ parameters.billToContactMechId = serviceResult.contactMechId
+ } else if (keepAddressBook == 'Y') {
+ GenericValue newValue = makeValue('PostalAddress', billToAddressCtx)
+ GenericValue oldValue = from('PostalAddress').where(parameters).queryOne()
+ if (newValue != oldValue) {
+ billToAddressCtx.contactMechId = null
+ Map serviceResult = run service: 'createPartyPostalAddress', with: billToAddressCtx
+ parameters.billToContactMechId = serviceResult.contactMechId
+ }
+ }
+ logInfo("Billing Postal Address created billToContactMechId is ${parameters.billToContactMechId}")
+ }
+ List pcmpBillList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechId: parameters.billToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION')
+ .filterByDate()
+ .queryList()
+ // If purpose does not exists then create
+ if (!pcmpBillList) {
+ List pcmpList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION')
+ .filterByDate()
+ .queryList()
+ for (GenericValue pcmp: pcmpList) {
+ run service: 'expirePartyContactMechPurpose', with: pcmp.getAllFields()
+ }
+ run service: 'createPartyContactMechPurpose', with: [*: parameters,
+ partyId: partyId,
+ contactMechId: parameters.billToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ }
+ if (parameters.setDefaultBilling == 'Y') {
+ run service: 'setPartyProfileDefaults', with: [partyId: partyId,
+ productStoreId: parameters.productStoreId,
+ defaultBillAddr: parameters.billToContactMechId]
+ }
+ } else {
+ Map serviceResult = run service: 'createPartyPostalAddress', with: [*: billToAddressCtx,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ parameters.billToContactMechId = serviceResult.contactMechId
+ logInfo("Billing address created with contactmechId ${parameters.billToContactMechId}")
+ }
+ }
+ return success([contactMechId: parameters.billToContactMechId])
+}
+
+/*
+ * Create and update credit card
+ */
+Map createUpdateCreditCard() {
+ Map serviceResult
+ String paymentMethodId = parameters.paymentMethodId
+ if (paymentMethodId) {
+ // call update Credit Card
+ GenericValue paymentMethod = from('PaymentMethod')
+ .where(partyId: parameters.partyId,
+ paymentMethodTypeId: 'CREDIT_CARD')
+ .orderBy('-fromDate')
+ .queryFirst()
+ paymentMethodId = paymentMethod ? paymentMethod.paymentMethodId : ''
+ serviceResult = run service: 'updateCreditCard', with: [*: parameters,
+ paymentMethodId: paymentMethodId]
+ } else {
+ // call create Credit Card
+ serviceResult = run service: 'createCreditCard', with: parameters
+ }
+ return success(paymentMethodId: serviceResult.paymentMethodId)
+}
+
+/*
+ * Set unitPrice as lastPrice on create purchase order, edit purchase order items and on receive inventory against a purchase order,
+ * but only if the order price didn't come from an agreement
+ */
+Map setUnitPriceAsLastPrice() {
+ GenericValue order = from('OrderHeader').where(parameters).queryOne()
+ if (!order || order.agreementId) {
+ return success()
+ // Do not update lastPrice if an agreement has been used on the order
+ // TODO replace by orderPItemPriceInfo analyse when it will support agreement
+ }
+ Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
+ if (parameters.facilityId) {
+ GenericValue orderSupplier = from('OrderHeaderItemAndRoles')
+ .where(orderId: order.orderId,
+ roleTypeId: 'BILL_FROM_VENDOR',
+ orderTypeId: 'PURCHASE_ORDER')
+ .queryFirst()
+ List supplierProducts = from('SupplierProduct')
+ .where(productId: parameters.productId,
+ partyId: orderSupplier.partyId,
+ availableThruDate: null)
+ .queryList()
+ for (GenericValue supplierProduct: supplierProducts) {
+ if (parameters.orderCurrencyUnitPrice && parameters.orderCurrencyUnitPrice != supplierProduct.lastPrice) {
+ GenericValue newSupplierProduct = supplierProduct.clone()
+ newSupplierProduct.availableFromDate = nowTimestamp
+ newSupplierProduct.lastPrice = parameters.orderCurrencyUnitPrice
+ newSupplierProduct.create()
+ supplierProduct.availableThruDate = nowTimestamp
+ supplierProduct.store()
+ } else if (parameters.unitCost != supplierProduct.lastPrice) {
+ GenericValue newSupplierProduct = supplierProduct.clone()
+ newSupplierProduct.availableFromDate = nowTimestamp
+ newSupplierProduct.lastPrice = parameters.unitCost
+ newSupplierProduct.create()
+ supplierProduct.availableThruDate = nowTimestamp
+ supplierProduct.store()
+ }
+ }
+ } else if (!parameters.orderItems) {
+ List orderItems = from('OrderItem')
+ .where(orderId: order.orderId)
+ .queryList()
+ Map itemPriceMap = parameters.itemPriceMap as Map
+ Map overridePriceMap = parameters.overridePriceMap as Map
+ List