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 2021/09/11 10:47:16 UTC

[ofbiz-framework] branch 228 created (now de1e9e4)

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

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


      at de1e9e4  Improved: Convert ShoppingListServices.xml mini lang to groovy (OFBIZ-11602)

This branch includes the following new commits:

     new de1e9e4  Improved: Convert ShoppingListServices.xml mini lang to groovy (OFBIZ-11602)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[ofbiz-framework] 01/01: Improved: Convert ShoppingListServices.xml mini lang to groovy (OFBIZ-11602)

Posted by nm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit de1e9e4bb4ef8cf48bf6853a128bd7cf4250e200
Author: Wiebke Pätzold <Wi...@ecomify.de>
AuthorDate: Fri Aug 21 16:08:08 2020 +0200

    Improved: Convert ShoppingListServices.xml mini lang to groovy (OFBIZ-11602)
---
 .../shoppinglist/ShoppingListServices.groovy       | 332 +++++++++++++++++++
 .../minilang/shoppinglist/ShoppingListServices.xml | 364 ---------------------
 .../order/servicedef/services_shoppinglist.xml     |  40 +--
 3 files changed, 352 insertions(+), 384 deletions(-)

diff --git a/applications/order/groovyScripts/shoppinglist/ShoppingListServices.groovy b/applications/order/groovyScripts/shoppinglist/ShoppingListServices.groovy
new file mode 100644
index 0000000..656a7ce
--- /dev/null
+++ b/applications/order/groovyScripts/shoppinglist/ShoppingListServices.groovy
@@ -0,0 +1,332 @@
+/*
+ * 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 org.apache.ofbiz.base.util.UtilDateTime
+import org.apache.ofbiz.base.util.UtilProperties
+import org.apache.ofbiz.entity.GenericValue
+import org.apache.ofbiz.service.ServiceUtil
+
+
+/**
+ * Create a ShoppingList
+ * @return
+ */
+def createShoppingList() {
+    GenericValue newEntity = makeValue("ShoppingList")
+    newEntity.setNonPKFields(parameters)
+    newEntity.partyId = newEntity.partyId ?: userLogin.partyId
+    newEntity.shoppingListTypeId = newEntity.shoppingListTypeId ?: "SLT_WISH_LIST"
+    newEntity.isPublic = newEntity.isPublic ?: "N"
+
+    if (!newEntity.listName) {
+        newEntity.listName = UtilProperties.getMessage("OrderUiLabels", "OrderNewShoppingList", parameters.locale) ?: "New Shopping List"
+    }
+
+    if (!newEntity.isActive) {
+        newEntity.isActive = newEntity.shoppingListTypeId == "SLT_AUTO_REODR" ? "N" : "Y"
+    }
+
+    newEntity.shoppingListId = delegator.getNextSeqId("ShoppingList")
+    newEntity.create()
+
+    Map result = success()
+    result.shoppingListId = newEntity.shoppingListId
+    result.successMessage = UtilProperties.getMessage("OrderUiLabels", "OrderShoppingListCreatedSuccessfully", parameters.locale)
+    return result
+}
+
+/**
+ * Update a ShoppingList
+ * @return
+ */
+def updateShoppingList() {
+    GenericValue shoppingList = from("ShoppingList").where(parameters).queryOne()
+    shoppingList.setNonPKFields(parameters)
+
+    // don't let auto-reorders be active unless there is some recurrence info
+    if (shoppingList.shoppingListTypeId == "SLT_AUTO_REODR" &&
+            (!shoppingList.recurrenceInfoId ||
+                    !shoppingList.paymentMethodId ||
+                    !shoppingList.contactMechId ||
+                    !shoppingList.shipmentMethodTypeId)) {
+        shoppingList.isActive =  "N"
+    }
+    shoppingList.store()
+
+    Map result = success()
+    result.successMessage = UtilProperties.getMessage("OrderUiLabels", "OrderShoppingListUpdatedSuccessfully", parameters.locale)
+    return result
+}
+
+/**
+ * Create a ShoppingList Item
+ * @return
+ */
+def createShoppingListItem() {
+    Map result = success()
+    List shoppingListItems = from("ShoppingListItem")
+            .where(productId: parameters.productId,
+                    shoppingListId: parameters.shoppingListId)
+            .queryList()
+    if (!shoppingListItems) {
+        GenericValue shoppingList = from("ShoppingList").where(parameters).queryOne()
+        GenericValue product = from("Product").where(parameters).queryOne()
+        if (!product) {
+            return error(UtilProperties.getMessage("ProductUiLabels", "ProductErrorProductNotFound", parameters.locale))
+        }
+        GenericValue newEntity = makeValue("ShoppingListItem")
+        newEntity.setNonPKFields(parameters)
+        newEntity.shoppingListId = parameters.shoppingListId
+        delegator.setNextSubSeqId(newEntity, "shoppingListItemSeqId", 5, 1)
+        newEntity.create()
+
+        result.shoppingListItemSeqId = newEntity.shoppingListItemSeqId
+        updateLastAdminModified(shoppingList, userLogin)
+    } else {
+        GenericValue shoppingListItem = shoppingListItems[0]
+
+        shoppingListItem.quantity = shoppingListItem.quantity ?: (BigDecimal) 0.0
+        parameters.quantity = parameters.quantity ?: (BigDecimal) 0.0
+
+        BigDecimal totalQty = shoppingListItem.quantity + parameters.quantity
+        Map serviceResult = run service: "updateShoppingListItem", with: [*       : shoppingListItem,
+                                                                          quantity: totalQty]
+        if (!ServiceUtil.isSuccess(serviceResult)) {
+            return error(serviceResult.errorMessage)
+        }
+        result.shoppingListItemSeqId = shoppingListItem.shoppingListItemSeqId
+    }
+    return result
+}
+
+/**
+ * Update a ShoppingListItem
+ * @return
+ */
+def updateShoppingListItem() {
+    GenericValue shoppingList = from("ShoppingList").where(parameters).queryOne()
+    GenericValue shoppingListItem = from("ShoppingListItem").where(parameters).queryOne()
+    shoppingListItem.setNonPKFields(parameters)
+    shoppingListItem.store()
+
+    updateLastAdminModified(shoppingList, userLogin)
+    return success()
+}
+
+/**
+ * Remove a ShoppingListItem
+ * @return
+ */
+def removeShoppingListItem() {
+    GenericValue shoppingList = from("ShoppingList").where(parameters).queryOne()
+    GenericValue shoppingListItem = from("ShoppingListItem").where(parameters).queryOne()
+    shoppingListItem.remove()
+
+    updateLastAdminModified(shoppingList, userLogin)
+    return success()
+}
+
+private void updateLastAdminModified(GenericValue shoppingList, GenericValue userLogin) {
+    if (shoppingList.partyId != userLogin.partyId) {
+        shoppingList.lastAdminModified = UtilDateTime.nowTimestamp()
+        shoppingList.store()
+    }
+}
+
+/**
+ * Adds a shopping list item if one with the same productId does not exist
+ * @return
+ */
+def addDistinctShoppingListItem() {
+    Map result = success()
+    List shoppingListItemList = from("ShoppingListItem").where(shoppingListId: parameters.shoppingListId).queryList()
+
+    for (GenericValue shoppingListItem : shoppingListItemList) {
+        if (parameters.productId == shoppingListItem.productId) {
+            result.shoppingListItemSeqId = shoppingListItem.shoppingListItemSeqId
+            return result
+        }
+    }
+    Map serviceResult = run service:"createShoppingListItem", with: parameters
+    if (!ServiceUtil.isSuccess(serviceResult)) {
+        return error(serviceResult.errorMessage)
+    }
+
+    result.shoppingListItemSeqId = serviceResult.shoppingListItemSeqId
+    return result
+}
+
+/**
+ * Calculate Deep Total Price for a ShoppingList
+ * @return
+ */
+def calculateShoppingListDeepTotalPrice() {
+    Map result = success()
+    Map serviceResult = run service: "checkShoppingListItemSecurity", with: parameters
+    if (!ServiceUtil.isSuccess(serviceResult)) {
+        return error(serviceResult.errorMessage)
+    }
+    if (!serviceResult.hasPermission) {
+        return error(UtilProperties.getMessage("OrderErrorUiLabels", "OrderSecurityErrorToRunForAnotherParty", parameters.locale))
+    }
+    Map calcPriceInBaseMap = [prodCatalogId: parameters.prodCatalogId, webSiteId: parameters.webSiteId]
+    ['partyId', 'productStoreId', 'productStoreGroupId', 'currencyUomId', 'autoUserLogin'].each {
+        if (parameters[it]) {
+            calcPriceInBaseMap[it] = parameters[it]
+        }
+    }
+
+    BigDecimal totalPrice = (BigDecimal) 0.0
+    from("ShoppingListItem")
+            .where(shoppingListId: parameters.shoppingListId)
+            .cache()
+            .queryList()
+            .each {
+                BigDecimal itemPrice = it.modifiedPrice
+                if (!itemPrice) {
+                    GenericValue product = from("Product").where(productId: it.productId).cache().queryOne()
+                    Map serviceResultCPP = run service: "calculateProductPrice", with: [*       : calcPriceInBaseMap,
+                                                                                        product : product,
+                                                                                        quantity: it.quantity]
+                    if (!ServiceUtil.isSuccess(serviceResultCPP)) {
+                        return error(serviceResultCPP.errorMessage)
+                    }
+                    itemPrice = serviceResultCPP.price
+                }
+                BigDecimal shoppingListItemQuantity = it.quantity ?: (BigDecimal) 1.0
+                totalPrice += (itemPrice * shoppingListItemQuantity)
+            }
+
+    from("ShoppingList")
+            .where(parentShoppingListId: parameters.shoppingListId,
+                    partyId: userLogin.partyId)
+            .cache()
+            .queryList()
+            .each {
+                Map serviceResultCSLDTP = run service: "calculateShoppingListDeepTotalPrice", with: [*             : calcPriceInBaseMap,
+                                                                                                     shoppingListId: it.shoppingListId]
+                if (!ServiceUtil.isSuccess(serviceResultCSLDTP)) {
+                    return error(serviceResultCSLDTP.errorMessage)
+                }
+                totalPrice += serviceResultCSLDTP.totalPrice
+            }
+
+    result.totalPrice = totalPrice
+    return result
+}
+
+/**
+ * Checks security on a ShoppingList
+ * @return
+ */
+def checkShoppingListSecurity() {
+    if (userLogin && (userLogin.userLoginId != "anonymous") &&
+            parameters.partyId && (userLogin.partyId != parameters.partyId)
+            && !security.hasEntityPermission("PARTYMGR", "_${parameters.permissionAction}", parameters.userLogin)) {
+        return error(UtilProperties.getMessage("OrderErrorUiLabels", "OrderSecurityErrorToRunForAnotherParty", parameters.locale))
+    }
+
+    Map result = success()
+    result.hasPermission = true
+    return result
+}
+
+/**
+ * Checks security on a ShoppingListIte
+ * @return
+ */
+def checkShoppingListItemSecurity() {
+    GenericValue shoppingList = from("ShoppingList").where(parameters).queryOne()
+    if (shoppingList?.partyId && userLogin.partyId != shoppingList.partyId &&
+            !security.hasEntityPermission("PARTYMGR", "_${parameters.permissionAction}", parameters.userLogin)) {
+        return error(UtilProperties.getMessage("OrderErrorUiLabels",
+                "OrderSecurityErrorToRunForAnotherParty",
+                [parentMethodName: parameters.parentMethodName,
+                 permissionAction: parameters.permissionAction],
+                parameters.locale))
+    }
+
+    Map result = success()
+    result.hasPermission = true
+    return result
+}
+
+/**
+ * Add suggestions to a shopping list
+ * @return
+ */
+def addSuggestionsToShoppingList() {
+    Map result = success()
+    String shoppingListId
+    // first check the ProductStore.enableAutoSuggestionList indicator
+    GenericValue orderHeader = from("OrderHeader").where(parameters).queryOne()
+    if (!(orderHeader?.productStoreId)) {
+        return result
+    }
+    GenericValue productStore = from("ProductStore").where(productStoreId: orderHeader.productStoreId).cache().queryOne()
+    if (productStore.enableAutoSuggestionList != "Y") {
+        return result
+    }
+
+    GenericValue orderRole = from ("OrderRole").where(orderId: parameters.orderId, roleTypeId: "PLACING_CUSTOMER").queryFirst()
+    GenericValue shoppingList = from("ShoppingList").where(partyId: orderRole.partyId, listName: "Auto Suggestions").queryFirst()
+    if (!shoppingList) {
+        Map createShoppingListInMap = [partyId           : orderRole.partyId,
+                                       listName          : "Auto Suggestions",
+                                       shoppingListTypeId: "SLT_WISH_LIST",
+                                       productStoreId    : parameters.productStoreId]
+        Map serviceResultCSL = dispatcher.runSync("createShoppingList", createShoppingListInMap, 7200, true)
+        if (!ServiceUtil.isSuccess(serviceResultCSL)) {
+            return error(serviceResultCSL.errorMessage)
+        }
+        shoppingListId = serviceResultCSL.serviceResult
+    } else {
+        shoppingListId = shoppingList.shoppingListId
+    }
+    List orderItemList = from ("OrderItem").where(orderId: parameters.orderId).orderBy("orderItemSeqId").queryList()
+    for (GenericValue orderItem : orderItemList) {
+        if (orderItem.productId) {
+            linkProductToShoppingList(orderItem.productId, shoppingListId)
+            GenericValue product = from("Product").where(productId: orderItem.productId).cache().queryOne()
+            if (product.isVariant == "Y") {
+                GenericValue virtualProductAssoc = from("ProductAssoc")
+                        .where(productIdTo: orderItem.productId,
+                                productAssocTypeId: "PRODUCT_VARIANT")
+                        .filterByDate()
+                        .queryFirst()
+                if (virtualProductAssoc) {
+                    linkProductToShoppingList(virtualProductAssoc.productIdTo, shoppingListId)
+                }
+            }
+        }
+    }
+    return result
+}
+
+private List<GenericValue> linkProductToShoppingList(String productId, String shoppingListId) {
+    from("ProductAssoc")
+            .where(productId: productId,
+                    productAssocTypeId: "PRODUCT_COMPLEMENT")
+            .filterByDate()
+            .queryList().each {
+        run service: "addDistinctShoppingListItem", with: [productId     : it.productIdTo,
+                                                           shoppingListId: shoppingListId,
+                                                           quantity      : (BigDecimal) 1]
+    }
+}
diff --git a/applications/order/minilang/shoppinglist/ShoppingListServices.xml b/applications/order/minilang/shoppinglist/ShoppingListServices.xml
deleted file mode 100644
index b2d54af..0000000
--- a/applications/order/minilang/shoppinglist/ShoppingListServices.xml
+++ /dev/null
@@ -1,364 +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="createShoppingList" short-description="Create a ShoppingList" login-required="false">
-        <make-value entity-name="ShoppingList" value-field="newEntity"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-
-        <if-empty field="newEntity.partyId">
-            <set from-field="userLogin.partyId" field="newEntity.partyId"/>
-        </if-empty>
-
-        <if-empty field="newEntity.shoppingListTypeId">
-            <set value="SLT_WISH_LIST" field="newEntity.shoppingListTypeId"/>
-        </if-empty>
-
-        <if-empty field="newEntity.listName">
-            <property-to-field field="newEntity.listName"
-                resource="OrderUiLabels" property="OrderNewShoppingList" default="New Shopping List"/>
-        </if-empty>
-
-        <if-empty field="newEntity.isPublic">
-            <set value="N" field="newEntity.isPublic"/>
-        </if-empty>
-
-        <if-empty field="newEntity.isActive">
-            <if-compare field="newEntity.shoppingListTypeId" operator="equals" value="SLT_AUTO_REODR">
-                <set value="N" field="newEntity.isActive"/>
-            <else>
-                <set value="Y" field="newEntity.isActive"/>
-            </else>
-            </if-compare>
-        </if-empty>
-
-        <sequenced-id sequence-name="ShoppingList" field="newEntity.shoppingListId"/>
-        <field-to-result field="newEntity.shoppingListId" result-name="shoppingListId"/>
-        <create-value value-field="newEntity"/>
-        <property-to-field resource="OrderUiLabels" property="OrderShoppingListCreatedSuccessfully" field="successMessage"/>
-        <field-to-result  field="successMessage"/>
-    </simple-method>
-
-    <simple-method method-name="updateShoppingList" short-description="Update a ShoppingList">
-        <entity-one entity-name="ShoppingList" value-field="shoppingList"/>
-
-        <set-nonpk-fields map="parameters" value-field="shoppingList"/>
-
-        <!-- don't let auto-reorders be active unless there is some recurrence info -->
-        <if>
-            <condition>
-                <and>
-                    <if-compare field="shoppingList.shoppingListTypeId" operator="equals" value="SLT_AUTO_REODR"/>
-                    <or>
-                        <if-empty field="shoppingList.recurrenceInfoId"/>
-                        <if-empty field="shoppingList.paymentMethodId"/>
-                        <if-empty field="shoppingList.contactMechId"/>
-                        <if-empty field="shoppingList.shipmentMethodTypeId"/>
-                    </or>
-                </and>
-            </condition>
-            <then>
-                <set value="N" field="shoppingList.isActive"/>
-            </then>
-        </if>
-
-        <store-value value-field="shoppingList"/>
-        <property-to-field resource="OrderUiLabels" property="OrderShoppingListUpdatedSuccessfully" field="successMessage"/>
-        <field-to-result  field="successMessage"/>
-    </simple-method>
-    <simple-method method-name="createShoppingListItem" short-description="Create a ShoppingList Item" login-required="false">
-        <entity-and entity-name="ShoppingListItem" list="shoppingListItems">
-            <field-map field-name="productId" from-field="parameters.productId"></field-map>
-            <field-map field-name="shoppingListId" from-field="parameters.shoppingListId"></field-map>
-        </entity-and>
-        <if-empty field="shoppingListItems">
-            <set field="parentMethodName" value="createShoppingListItem"/>
-            <set field="permissionAction" value="CREATE"/>
-            <entity-one entity-name="ShoppingList" value-field="shoppingList"/>
-
-            <entity-one entity-name="Product" value-field="product"/>
-            <if-empty field="product">
-                <add-error> <fail-property resource="ProductUiLabels" property="ProductErrorProductNotFound"/> </add-error>
-                <check-errors/>
-            </if-empty>
-            <make-value entity-name="ShoppingListItem" value-field="newEntity"/>
-            <set from-field="parameters.shoppingListId" field="newEntity.shoppingListId"/>
-            <make-next-seq-id value-field="newEntity" seq-field-name="shoppingListItemSeqId" numeric-padding="5"/>
-
-            <set-nonpk-fields map="parameters" value-field="newEntity"/>
-            <field-to-result field="newEntity.shoppingListItemSeqId" result-name="shoppingListItemSeqId"/>
-            <create-value value-field="newEntity"/>
-
-            <if-compare-field field="shoppingList.partyId" to-field="userLogin.partyId" operator="not-equals">
-                <now-timestamp field="shoppingList.lastAdminModified"/>
-                <store-value value-field="shoppingList"/>
-            </if-compare-field>
-        <else>
-            <first-from-list list="shoppingListItems" entry="shoppingListItem"/>
-            <calculate field="totalquantity" >
-                <calcop operator="add" field="shoppingListItem.quantity">
-                    <calcop operator="get" field="parameters.quantity"/>
-                </calcop>
-            </calculate>
-            <field-to-result field="shoppingListItem.shoppingListItemSeqId" result-name="shoppingListItemSeqId"/>
-            <set-service-fields service-name="updateShoppingListItem" map="shoppingListItem" to-map="shoppingListItemParameters"/>
-            <set field="shoppingListItemParameters.quantity" from-field="totalquantity"/>
-            <call-service service-name="updateShoppingListItem" in-map-name="shoppingListItemParameters"/>
-        </else>
-        </if-empty>
-    </simple-method>
-
-    <simple-method method-name="updateShoppingListItem" short-description="Update a ShoppingListItem">
-        <entity-one entity-name="ShoppingList" value-field="shoppingList"/>
-        <entity-one entity-name="ShoppingListItem" value-field="shoppingListItem"/>
-        <set-nonpk-fields map="parameters" value-field="shoppingListItem"/>
-        <store-value value-field="shoppingListItem"/>
-
-        <if-compare-field field="shoppingList.partyId" to-field="userLogin.partyId" operator="not-equals">
-            <now-timestamp field="shoppingList.lastAdminModified"/>
-            <store-value value-field="shoppingList"/>
-        </if-compare-field>
-    </simple-method>
-
-    <simple-method method-name="removeShoppingListItem" short-description="Remove a ShoppingListItem">
-        <entity-one entity-name="ShoppingList" value-field="shoppingList"/>
-        <entity-one entity-name="ShoppingListItem" value-field="shoppingListItem"/>
-        <remove-value value-field="shoppingListItem"/>
-
-        <if-compare-field field="shoppingList.partyId" to-field="userLogin.partyId" operator="not-equals">
-            <now-timestamp field="shoppingList.lastAdminModified"/>
-            <store-value value-field="shoppingList"/>
-        </if-compare-field>
-    </simple-method>
-
-    <simple-method method-name="addDistinctShoppingListItem"
-                   short-description="Adds a shopping list item if one with the same productId does not exist">
-        <entity-condition entity-name="ShoppingListItem" list="shoppingListItemList">
-            <condition-expr field-name="shoppingListId" from-field="parameters.shoppingListId"/>
-        </entity-condition>
-
-        <iterate list="shoppingListItemList" entry="shoppingListItem">
-            <if-compare-field field="parameters.productId" to-field="shoppingListItem.productId" operator="equals">
-                <field-to-result field="shoppingListItem.shoppingListItemSeqId" result-name="shoppingListItemSeqId"/>
-                <return />
-            </if-compare-field>
-        </iterate>
-        <call-service service-name="createShoppingListItem" in-map-name="parameters">
-            <result-to-result result-name="shoppingListItemSeqId"/>
-        </call-service>
-    </simple-method>
-
-    <simple-method method-name="calculateShoppingListDeepTotalPrice" short-description="Calculate Deep Total Price for a ShoppingList">
-        <set-service-fields service-name="checkShoppingListItemSecurity" map="parameters" to-map="serviceInMap"/>
-        <call-service service-name="checkShoppingListItemSecurity" in-map-name="serviceInMap">
-            <result-to-field result-name="hasPermission" field="hasPermission"/>
-        </call-service>
-        <if-compare field="hasPermission" operator="equals" value="false" type="Boolean">
-            <add-error><fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunForAnotherParty"/></add-error>
-        </if-compare>
-        <check-errors/>
-
-        <set from-field="parameters.prodCatalogId" field="calcPriceInBaseMap.prodCatalogId"/>
-        <set from-field="parameters.webSiteId" field="calcPriceInBaseMap.webSiteId"/>
-        <set from-field="parameters.partyId" field="calcPriceInBaseMap.partyId"/>
-        <set from-field="parameters.productStoreId" field="calcPriceInBaseMap.productStoreId"/>
-        <set from-field="parameters.productStoreGroupId" field="calcPriceInBaseMap.productStoreGroupId"/>
-        <set from-field="parameters.currencyUomId" field="calcPriceInBaseMap.currencyUomId"/>
-        <set from-field="parameters.autoUserLogin" field="calcPriceInBaseMap.autoUserLogin"/>
-
-        <entity-and entity-name="ShoppingListItem" list="shoppingListItems" use-cache="true">
-            <field-map field-name="shoppingListId" from-field="parameters.shoppingListId"/>
-        </entity-and>
-
-        <set field="totalPrice" type="BigDecimal" value="0.0"/>
-        <iterate list="shoppingListItems" entry="shoppingListItem">
-            <entity-one entity-name="Product" value-field="product" use-cache="true" auto-field-map="false">
-                <field-map field-name="productId" from-field="shoppingListItem.productId"/>
-            </entity-one>
-
-            <map-to-map map="calcPriceInBaseMap" to-map="calcPriceInMap"/>
-            <set field="calcPriceInMap.product" from-field="product"/>
-            <set field="calcPriceInMap.quantity" from-field="shoppingListItem.quantity"/>
-            <if-not-empty field="shoppingListItem.modifiedPrice">
-                <call-service service-name="calculateProductPrice" in-map-name="calcPriceInMap">
-                    <result-to-field result-name="price" field="calcPriceOutMap.price"/>
-                </call-service>
-            </if-not-empty>
-            <set field="itemPrice" from-field="shoppingListItem.modifiedPrice" default-value="${calcPriceOutMap.price}"/>
-            <calculate field="totalPrice">
-                <calcop operator="add" field="totalPrice"/>
-                <calcop operator="multiply">
-                    <calcop operator="get" field="itemPrice"/>
-                    <calcop operator="get" field="shoppingListItem.quantity"/>
-                </calcop>
-            </calculate>
-            <clear-field field="calcPriceInMap"/>
-        </iterate>
-
-        <entity-and entity-name="ShoppingList" list="childshoppingLists" use-cache="true">
-            <field-map field-name="parentShoppingListId" from-field="parameters.shoppingListId"/>
-            <field-map field-name="partyId" from-field="userLogin.partyId"/>
-        </entity-and>
-        <iterate list="childshoppingLists" entry="childshoppingList">
-            <map-to-map map="calcPriceInBaseMap" to-map="calcChildPriceInMap"/>
-            <set from-field="childshoppingList.shoppingListId" field="calcChildPriceInMap.shoppingListId"/>
-            <call-service service-name="calculateShoppingListDeepTotalPrice" in-map-name="calcChildPriceInMap">
-                <result-to-field result-name="totalPrice" field="calcPriceOutMap.totalPrice"/>
-            </call-service>
-            <calculate field="totalPrice">
-                <calcop operator="get" field="totalPrice"/>
-                <calcop operator="get" field="calcPriceOutMap.totalPrice"/>
-            </calculate>
-            <clear-field field="calcChildPriceInMap"/>
-        </iterate>
-
-        <field-to-result field="totalPrice" result-name="totalPrice"/>
-    </simple-method>
-
-    <simple-method method-name="checkShoppingListSecurity" short-description="Checks security on a ShoppingList">
-        <set field="hasPermission" value="false" type="Boolean"/>
-        <if>
-            <condition>
-                <and>
-                    <not><if-empty field="userLogin"/></not>
-                    <not><if-compare field="userLogin.userLoginId" operator="equals" value="anonymous"/></not>
-                    <not><if-empty field="parameters.partyId"/></not>
-                    <not><if-compare-field to-field="userLogin.partyId" field="parameters.partyId" operator="equals"/></not>
-                    <not><if-has-permission permission="PARTYMGR" action="_${permissionAction}"/></not>
-                </and>
-            </condition>
-            <then>
-                <add-error><fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunForAnotherParty"/></add-error>
-            </then>
-            <else>
-                <set field="hasPermission" value="true" type="Boolean"/>
-            </else>
-        </if>
-        <field-to-result field="hasPermission"/>
-    </simple-method>
-    <simple-method method-name="checkShoppingListItemSecurity" short-description="Checks security on a ShoppingListItem">
-        <set field="hasPermission" value="false" type="Boolean"/>
-        <entity-one entity-name="ShoppingList" value-field="shoppingList"/>
-        <if>
-            <condition>
-                <and>
-                    <not><if-empty field="shoppingList.partyId"/></not>
-                    <not><if-compare-field field="userLogin.partyId" to-field="shoppingList.partyId" operator="equals"/></not>
-                    <not><if-has-permission permission="PARTYMGR" action="_${permissionAction}"/></not>
-                </and>
-            </condition>
-            <then>
-                <add-error><fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunForAnotherParty"/></add-error>
-            </then>
-            <else>
-                <set field="hasPermission" value="true" type="Boolean"/>
-            </else>
-        </if>
-        <field-to-result field="hasPermission"/>
-    </simple-method>
-    <simple-method method-name="addSuggestionsToShoppingList" short-description="Add suggestions to a shopping list">
-        <!-- first check the ProductStore.enableAutoSuggestionList indicator -->
-        <entity-one entity-name="OrderHeader" value-field="orderHeader"/>
-        <if-empty field="orderHeader.productStoreId"><return/></if-empty>
-
-        <entity-one entity-name="ProductStore" value-field="productStore" auto-field-map="false">
-            <field-map field-name="productStoreId" from-field="orderHeader.productStoreId"/>
-        </entity-one>
-        <if-compare field="productStore.enableAutoSuggestionList" operator="not-equals" value="Y"><return/></if-compare>
-
-        <entity-condition entity-name="OrderRole" list="orderRoleList">
-            <condition-list combine="and">
-                <condition-expr field-name="orderId" from-field="parameters.orderId"/>
-                <condition-expr field-name="roleTypeId" value="PLACING_CUSTOMER"/>
-            </condition-list>
-        </entity-condition>
-        <first-from-list list="orderRoleList" entry="orderRole"/>
-
-        <entity-condition entity-name="ShoppingList" list="shoppingListList">
-            <condition-list combine="and">
-                <condition-expr field-name="partyId" from-field="orderRole.partyId"/>
-                <condition-expr field-name="listName" value="Auto Suggestions"/>
-            </condition-list>
-        </entity-condition>
-        <first-from-list list="shoppingListList" entry="shoppingList"/>
-        <if-empty field="shoppingList">
-            <set field="createShoppingListInMap.partyId" from-field="orderRole.partyId"/>
-            <set field="createShoppingListInMap.listName" value="Auto Suggestions"/>
-            <set field="createShoppingListInMap.shoppingListTypeId" value="SLT_WISH_LIST"/>
-            <set field="createShoppingListInMap.productStoreId" from-field="parameters.productStoreId"/>
-            <call-service service-name="createShoppingList" in-map-name="createShoppingListInMap" require-new-transaction="true">
-                <result-to-field result-name="shoppingListId"/>
-            </call-service>
-        <else>
-            <set field="shoppingListId" from-field="shoppingList.shoppingListId"/>
-        </else>
-        </if-empty>
-
-        <entity-condition entity-name="OrderItem" list="orderItemList">
-            <condition-expr field-name="orderId" from-field="parameters.orderId"/>
-            <order-by field-name="orderItemSeqId"/>
-        </entity-condition>
-        <iterate list="orderItemList" entry="orderItem">
-            <if-not-empty field="orderItem.productId">
-                <entity-condition entity-name="ProductAssoc" list="compProductAssocList" filter-by-date="true">
-                    <condition-list combine="and">
-                        <condition-expr field-name="productId" from-field="orderItem.productId"/>
-                        <condition-expr field-name="productAssocTypeId" value="PRODUCT_COMPLEMENT"/>
-                    </condition-list>
-                </entity-condition>
-                <iterate list="compProductAssocList" entry="compProductAssoc">
-                    <clear-field field="shoppingListParameters"/>
-                    <set field="shoppingListParameters.productId" from-field="compProductAssoc.productIdTo"/>
-                    <set field="shoppingListParameters.shoppingListId" from-field="shoppingListId"/>
-                    <set field="shoppingListParameters.quantity" value="1" type="BigDecimal"/>
-                    <call-service service-name="addDistinctShoppingListItem" in-map-name="shoppingListParameters"/>
-                </iterate>
-                <entity-one entity-name="Product" value-field="product" auto-field-map="false" >
-                    <field-map field-name="productId" from-field="orderItem.productId"/>
-                </entity-one>
-                <if-compare field="product.isVariant" operator="equals" value="Y">
-                    <entity-condition entity-name="ProductAssoc" list="virtualProductAssocList" filter-by-date="true">
-                        <condition-list combine="and">
-                            <condition-expr field-name="productIdTo" from-field="orderItem.productId"/>
-                            <condition-expr field-name="productAssocTypeId" value="PRODUCT_VARIANT"/>
-                        </condition-list>
-                    </entity-condition>
-                    <first-from-list list="virtualProductAssocList" entry="virtualProductAssoc"/>
-                    <if-not-empty field="virtualProductAssoc">
-                        <entity-condition entity-name="ProductAssoc" list="compProductAssocList" filter-by-date="true">
-                            <condition-list combine="and">
-                                <condition-expr field-name="productId" from-field="virtualProductAssoc.productId"/>
-                                <condition-expr field-name="productAssocTypeId" value="PRODUCT_COMPLEMENT"/>
-                            </condition-list>
-                        </entity-condition>
-                        <iterate list="compProductAssocList" entry="compProductAssoc">
-                            <clear-field field="shoppingListParameters"/>
-                            <set field="shoppingListParameters.productId" from-field="compProductAssoc.productIdTo"/>
-                            <set field="shoppingListParameters.shoppingListId" from-field="shoppingListId"/>
-                            <set field="shoppingListParameters.quantity" value="1" type="BigDecimal"/>
-                            <call-service service-name="addDistinctShoppingListItem" in-map-name="shoppingListParameters"/>
-                        </iterate>
-                    </if-not-empty>
-                </if-compare>
-            </if-not-empty>
-        </iterate>
-    </simple-method>
-</simple-methods>
diff --git a/applications/order/servicedef/services_shoppinglist.xml b/applications/order/servicedef/services_shoppinglist.xml
index 43758d9..71b1c02 100644
--- a/applications/order/servicedef/services_shoppinglist.xml
+++ b/applications/order/servicedef/services_shoppinglist.xml
@@ -30,16 +30,16 @@ under the License.
         <auto-attributes mode="IN" entity-name="ShoppingList" include="nonpk" optional="true"/>
         <attribute name="shippingMethodString" type="String" mode="IN" optional="true"/>
     </service>
-    <service name="createShoppingList" engine="simple" auth="false"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="createShoppingList">
+    <service name="createShoppingList" engine="groovy" auth="false"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="createShoppingList">
         <description>Create a shopping list entity</description>
         <permission-service service-name="checkShoppingListSecurity" main-action="CREATE"/>
         <implements service="createShoppingListRecurrence"/>
         <implements service="shoppingListInterface"/>
         <attribute name="shoppingListId" type="String" mode="OUT" optional="false"/>
     </service>
-    <service name="updateShoppingList" engine="simple" auth="true"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="updateShoppingList">
+    <service name="updateShoppingList" engine="groovy" auth="true"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="updateShoppingList">
         <description>Update a shopping list entity</description>
         <permission-service service-name="checkShoppingListSecurity" main-action="UPDATE"/>
         <implements service="createShoppingListRecurrence"/>
@@ -51,14 +51,14 @@ under the License.
         <permission-service service-name="checkShoppingListSecurity" main-action="DELETE"/>
         <attribute name="shoppingListId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="checkShoppingListSecurity" engine="simple" auth="false"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="checkShoppingListSecurity">
+    <service name="checkShoppingListSecurity" engine="groovy" auth="false"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="checkShoppingListSecurity">
         <description>Checks security on a ShoppingList</description>
         <implements service="permissionInterface"/>
         <attribute name="partyId" type="String" mode="IN" optional="true"/>
     </service>
-    <service name="calculateShoppingListDeepTotalPrice" engine="simple" auth="true"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="calculateShoppingListDeepTotalPrice">
+    <service name="calculateShoppingListDeepTotalPrice" engine="groovy" auth="true"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="calculateShoppingListDeepTotalPrice">
         <description>Remove a shopping list entity</description>
         <attribute name="shoppingListId" type="String" mode="IN" optional="false"/>
         <attribute name="prodCatalogId" type="String" mode="IN" optional="false"/>
@@ -116,8 +116,8 @@ under the License.
         <attribute name="quantityPurchased" type="BigDecimal" mode="IN" optional="true"/>
         <attribute name="configId" type="String" mode="IN" optional="true"/>
     </service>
-    <service name="createShoppingListItem" engine="simple" auth="false"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="createShoppingListItem">
+    <service name="createShoppingListItem" engine="groovy" auth="false"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="createShoppingListItem">
         <description>Create a shopping list item</description>
         <permission-service service-name="checkShoppingListItemSecurity" main-action="CREATE"/>
         <implements service="shoppingListItemInterface"/>
@@ -126,34 +126,34 @@ under the License.
         <attribute name="productId" type="String" mode="IN" optional="false"/>
         <attribute name="shoppingListItemSeqId" type="String" mode="OUT" optional="false"/>
     </service>
-    <service name="updateShoppingListItem" engine="simple" auth="true"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="updateShoppingListItem">
+    <service name="updateShoppingListItem" engine="groovy" auth="true"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="updateShoppingListItem">
         <description>Update a shopping list item</description>
         <permission-service service-name="checkShoppingListItemSecurity" main-action="UPDATE"/>
         <implements service="shoppingListItemInterface"/>
         <attribute name="shoppingListItemSeqId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="removeShoppingListItem" engine="simple" auth="true"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="removeShoppingListItem">
+    <service name="removeShoppingListItem" engine="groovy" auth="true"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="removeShoppingListItem">
         <description>Remove a shopping list item</description>
         <permission-service service-name="checkShoppingListItemSecurity" main-action="DELETE"/>
         <attribute name="shoppingListId" type="String" mode="IN" optional="false"/>
         <attribute name="shoppingListItemSeqId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="checkShoppingListItemSecurity" engine="simple" auth="false"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="checkShoppingListItemSecurity">
+    <service name="checkShoppingListItemSecurity" engine="groovy" auth="false"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="checkShoppingListItemSecurity">
         <description>Checks security on a ShoppingListItem</description>
         <implements service="permissionInterface"/>
         <attribute name="partyId" type="String" mode="IN" optional="true"/>
         <attribute name="shoppingListId" type="String" mode="IN" optional="true"/>
     </service>
-    <service name="addSuggestionsToShoppingList" engine="simple" auth="true"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="addSuggestionsToShoppingList">
+    <service name="addSuggestionsToShoppingList" engine="groovy" auth="true"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="addSuggestionsToShoppingList">
         <description>Add suggestions to a shopping list</description>
         <attribute name="orderId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="addDistinctShoppingListItem" engine="simple" auth="true"
-            location="component://order/minilang/shoppinglist/ShoppingListServices.xml" invoke="addDistinctShoppingListItem">
+    <service name="addDistinctShoppingListItem" engine="groovy" auth="true"
+            location="component://order/groovyScripts/shoppinglist/ShoppingListServices.groovy" invoke="addDistinctShoppingListItem">
         <description>Adds a shopping list item if one with the same productId does not exist</description>
         <implements service="shoppingListItemInterface"/>
         <attribute name="shoppingListId" type="String" mode="IN" optional="false"/>