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..6c33975637e 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..2ad18f1689b 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,48 @@
*/
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 org.apache.ofbiz.service.ModelService
+import org.apache.ofbiz.service.ServiceUtil
import java.sql.Timestamp
+/**
+ * Service to create OrderHeader
+ */
+Map createOrderHeader() {
+ String orderId
+ Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
+ if (!(security.hasEntityPermission('ORDERMGR', '_CREATE', parameters.userLogin))) {
+ return error(label('OrderErrorUiLabels', 'OrderSecurityErrorToRunCreateOrderShipment'))
+ }
+
+ GenericValue orderHeader = makeValue('OrderHeader')
+ if (parameters.orderId) {
+ orderId = parameters.orderId
+ } else {
+ orderId = delegator.getNextSeqId('OrderHeader')
+ }
+ orderHeader.orderId = orderId
+ orderHeader.setNonPKFields(parameters)
+
+ orderHeader.statusId = orderHeader.statusId ?: 'ORDER_CREATED'
+ orderHeader.orderDate = orderHeader.orderDate ?: nowTimestamp
+ orderHeader.entryDate = orderHeader.entryDate ?: nowTimestamp
+ orderHeader.create()
+ return success([orderId: orderId])
+}
+
/**
* Service to get the next OrderId
*/
@@ -63,14 +98,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 +117,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 = roleTypeId ?: 'PLACING_CUSTOMER'
+ String orderTypeId = orderTypeId ?: 'SALES_ORDER'
+ String statusId = statusId ?: 'ORDER_COMPLETED'
//find the existing exchange rates
- exprBldr = new EntityConditionBuilder()
+ EntityConditionBuilder exprBldr = new EntityConditionBuilder()
EntityCondition condition = exprBldr.AND {
EQUALS(partyId: partyId)
@@ -128,14 +157,827 @@ 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()
+ Map result = success()
result.totalGrandAmount = orderInfo ? orderInfo.totalGrandAmount : BigDecimal.ZERO
result.totalSubRemainingAmount = orderInfo ? orderInfo.totalSubRemainingAmount : BigDecimal.ZERO
result.totalOrders = orderInfo ? orderInfo.totalOrders : 0L
return result
}
+
+/**
+ * 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
+
+ if (partyAcctgPreference.lastOrderNumber) {
+ partyAcctgPreference.lastOrderNumber ++
+ } else {
+ partyAcctgPreference.lastOrderNumber = 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.valueOf(0).setScale(3)
+ 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.valueOf(0).setScale(3)
+ for (GenericValue adjustment : adjustments) {
+ if (adjustment.productPromoId && !adjustment.orderAdjustmentId) {
+ newOrderAdjustmentTotal = newOrderAdjustmentTotal.add(adjustment.getBigDecimal('amount').setScale(3))
+ }
+ }
+
+ // 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: [userLogin: context.userLogin,
+ 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: [
+ userLogin: context.userLogin,
+ 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: [userLogin: context.userLogin, *: parameters]
+ if (parameters.oldContactMechId) {
+ run service: 'removeOrderContactMech', with: [userLogin: context.userLogin,
+ 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() {
+ Map result = success()
+ GenericValue orderItemShipGroup = from('OrderItemShipGroup')
+ .where('orderId', parameters.orderId,
+ 'contactMechId', parameters.oldContactMechId)
+ .queryFirst()
+ List orderByList = [ (orderItemShipGroup.maySplit == 'Y' ? '+' : '-') + 'promisedDatetime']
+ GenericValue orderItemShipGroupInvRes = from('OrderItemShipGrpInvRes')
+ .where('orderId', parameters.orderId,
+ 'shipGroupSeqId', parameters.shipGroupSeqId)
+ .orderBy(orderByList)
+ .queryFirst()
+ result.estimatedShipDate = orderItemShipGroupInvRes.promisedDatetime
+ return result
+}
+
+/*
+ * 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
+ Map result = run service: 'createOrderPaymentPreference', with: [
+ userLogin: context.userLogin,
+ orderId: parameters.orderId,
+ maxAmount: parameters.maxAmount,
+ paymentMethodId: parameters.paymentMethodId,
+ paymentMethodTypeId: paymentMethod.paymentMethodTypeId]
+ return result
+}
+
+/*
+ * Gets an order status
+ */
+Map getOrderStatus() {
+ Map result = success()
+ GenericValue order = from('OrderHeader').where(parameters).queryOne()
+ if (!order) {
+ return error(label('OrderErrorUiLabels', 'OrderOrderIdDoesNotExists'))
+ }
+ result.statusId = order.statusId
+ return result
+}
+
+/*
+ * Check if an Order is on Back Order
+ */
+Map checkOrderIsOnBackOrder() {
+ Map result = success()
+ boolean isBackOrder = false
+ EntityCondition condition = EntityCondition.makeCondition([
+ EntityCondition.makeCondition('orderId', parameters.orderId),
+ EntityCondition.makeCondition('quantityNotAvailable', EntityOperator.NOT_EQUAL, null),
+ EntityCondition.makeCondition('quantityNotAvailable', EntityOperator.GREATER_THAN_EQUAL_TO, BigDecimal.ZERO)],
+ EntityOperator.AND)
+ List orderItemShipGrpInvResList = from('OrderItemShipGrpInvRes')
+ .where(condition)
+ .queryList()
+ if (orderItemShipGrpInvResList) {
+ isBackOrder = true
+ }
+ result.isBackOrder = isBackOrder
+ return result
+}
+
+/*
+ * Creates a new Order Item Change record
+ */
+Map createOrderItemChange() {
+ Map result = success()
+ GenericValue newEntity = makeValue('OrderItemChange', parameters)
+ newEntity.orderItemChangeId = delegator.getNextSeqId('OrderItemChange')
+ if (!parameters.changeDatetime) {
+ newEntity.changeDatetime = UtilDateTime.nowTimestamp()
+ }
+ if (!parameters.changeUserLogin) {
+ newEntity.changeUserLogin = userLogin.userLoginId
+ }
+ newEntity.create()
+ result.orderItemChangeId = newEntity.orderItemChangeId
+ return result
+}
+
+/*
+ * Create and update a Shipping Address
+ */
+Map createUpdateShippingAddress() {
+ Map result = success()
+ 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'
+ result = run service: 'createPartyPostalAddress', with: shipToAddressCtx
+ parameters.shipToContactMechId = result.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
+ result = run service: 'createPartyPostalAddress', with: shipToAddressCtx
+ parameters.shipToContactMechId = result.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) {
+ Map serviceInMap = dispatcher.getDispatchContext().makeValidContext('expirePartyContactMechPurpose', ModelService.IN_PARAM, pcmp)
+ result = run service: 'expirePartyContactMechPurpose', with: serviceInMap
+ }
+ Map serviceContext = [*: parameters,
+ partyId: partyId,
+ contactMechId: parameters.shipToContactMechId,
+ contactMechPurposeTypeId: 'SHIPPING_LOCATION']
+ result = run service: 'createPartyContactMechPurpose', with: serviceContext
+ }
+ if (parameters.setDefaultShipping == 'Y') {
+ result = 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) {
+ Map serviceInMap = dispatcher.getDispatchContext().makeValidContext('expirePartyContactMechPurpose', ModelService.IN_PARAM, pcmp)
+ result = run service: 'expirePartyContactMechPurpose', with: serviceInMap
+ }
+ Map serviceContext = [*: shipToAddressCtx,
+ partyId: partyId,
+ contactMechId: null,
+ contactMechPurposeTypeId: 'SHIPPING_LOCATION']
+ result = run service: 'createPartyPostalAddress', with: serviceContext
+ parameters.shipToContactMechId = result.contactMechId
+ logInfo("Shipping address updated with contactMechId ${shipToAddressCtx.shipToContactMechId}")
+ }
+ } else {
+ shipToAddressCtx.userLogin = parameters.userLogin
+ result = run service: 'updatePartyPostalAddress', with: shipToAddressCtx
+ parameters.shipToContactMechId = result.contactMechId
+ logInfo("Shipping address updated with contactMechId ${shipToAddressCtx.shipToContactMechId}")
+ }
+ }
+ result.contactMechId = parameters.shipToContactMechId
+ return result
+}
+
+/*
+ * Create and update Billing Address
+ */
+Map createUpdateBillingAddress() {
+ Map result = success()
+ 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) {
+ Map serviceInMap = dispatcher.getDispatchContext().makeValidContext('deletePartyContactMech', ModelService.IN_PARAM, pcmp)
+ result = run service: 'deletePartyContactMech', with: serviceInMap
+ }
+ if (keepAddressBook == 'N') {
+ result = 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']
+ result = 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']
+ result = run service: 'createPartyContactMechPurpose', with: serviceContext
+ }
+ parameters.billToContactMechId = parameters.shipToContactMechId
+ } else {
+ if (parameters.billToContactMechId) {
+ if (parameters.shipToContactMechId == parameters.billToContactMechId) {
+ Map serviceContext = [*: billToAddressCtx,
+ contactMechId: null,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ result = run service: 'createPartyPostalAddress', with: serviceContext
+ parameters.billToContactMechId = result.contactMechId
+
+ List pcmpList = from('PartyContactMechPurpose')
+ .where(partyId: partyId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION')
+ .filterByDate()
+ .queryList()
+ for (GenericValue pcmp: pcmpList) {
+ Map serviceInMap = dispatcher.getDispatchContext().makeValidContext('deletePartyContactMech', ModelService.IN_PARAM, pcmp)
+ result = run service: 'expirePartyContactMechPurpose', with: serviceInMap
+ }
+ serviceContext = [*: parameters,
+ partyId: partyId,
+ contactMechId: parameters.billToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ result = run service: 'createPartyContactMechPurpose', with: serviceContext
+ logInfo("Billing address updated with contactMechId ${parameters.billToContactMechId}")
+ } else {
+ if (keepAddressBook == 'N') {
+ billToAddressCtx.userLogin = parameters.userLogin
+ result = run service: 'updatePartyPostalAddress', with: billToAddressCtx
+ parameters.billToContactMechId = result.contactMechId
+ } else if (keepAddressBook == 'Y') {
+ GenericValue newValue = makeValue('PostalAddress', billToAddressCtx)
+ GenericValue oldValue = from('PostalAddress').where(parameters).queryOne()
+ if (newValue != oldValue) {
+ billToAddressCtx.contactMechId = null
+ result = run service: 'createPartyPostalAddress', with: billToAddressCtx
+ parameters.billToContactMechId = result.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) {
+ Map serviceInMap = dispatcher.getDispatchContext().makeValidContext('expirePartyContactMechPurpose', ModelService.IN_PARAM, pcmp)
+ result = run service: 'expirePartyContactMechPurpose', with: serviceInMap
+ }
+ Map serviceContext = [*: parameters,
+ partyId: partyId,
+ contactMechId: parameters.billToContactMechId,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ result = run service: 'createPartyContactMechPurpose', with: serviceContext
+ }
+ if (parameters.setDefaultBilling == 'Y') {
+ result = run service: 'setPartyProfileDefaults', with: [ partyId: partyId,
+ productStoreId: parameters.productStoreId,
+ defaultBillAddr: parameters.billToContactMechId]
+ }
+ } else {
+ Map serviceContext = [*: billToAddressCtx,
+ contactMechPurposeTypeId: 'BILLING_LOCATION']
+ result = run service: 'createPartyPostalAddress', with: serviceContext
+ parameters.billToContactMechId = result.contactMechId
+ logInfo("Billing address created with contactmechId ${parameters.billToContactMechId}")
+ }
+ }
+ result.contactMechId = parameters.billToContactMechId
+ return result
+}
+
+/*
+ * Create and update credit card
+ */
+Map createUpdateCreditCard() {
+ Map result = success()
+ 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 : ''
+ result = run service: 'updateCreditCard', with: [ *: parameters,
+ paymentMethodId: paymentMethodId]
+ paymentMethodId = result.paymentMethodId
+ } else {
+ // call create Credit Card
+ result = run service: 'createCreditCard', with: [ *: parameters]
+ paymentMethodId = result.paymentMethodId
+ }
+ result.paymentMethodId = paymentMethodId
+ return result
+}
+
+/*
+ * 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() {
+ Map result = success()
+ Timestamp nowTimestamp = UtilDateTime.nowTimestamp()
+ if (parameters.facilityId && parameters.orderId) {
+ GenericValue orderSupplier = from('OrderHeaderItemAndRoles')
+ .where(orderId: parameters.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 && parameters.orderId) {
+ GenericValue order = from('OrderHeader').where(parameters).queryOne()
+ // Do not update lastPrice if an agreement has been used on the order
+ if (order.agreementId) {
+ // TODO replace by orderPItemPriceInfo analyse when it will support agreement
+ return result
+ }
+ List orderItems = from('OrderItem')
+ .where(orderId: parameters.orderId)
+ .queryList()
+ Map itemPriceMap = parameters.itemPriceMap
+ Map overridePriceMap = parameters.overridePriceMap
+ List