You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by pg...@apache.org on 2020/06/19 15:01:45 UTC

[ofbiz-framework] branch trunk updated: Improved: Migrate checkCreateOrderRequirement service to groovy (OFBIZ-9984)

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

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


The following commit(s) were added to refs/heads/trunk by this push:
     new 7c8aab3  Improved: Migrate checkCreateOrderRequirement service to groovy (OFBIZ-9984)
7c8aab3 is described below

commit 7c8aab3d9d92fb3d52661ef436f767516609cad0
Author: Gil Portenseigne <gi...@nereide.fr>
AuthorDate: Wed Jun 3 10:10:25 2020 +0200

    Improved: Migrate checkCreateOrderRequirement service to groovy
    (OFBIZ-9984)
    
    This commit migrate also dependent method and remove createRequirementFromItemATP service
---
 applications/order/config/OrderErrorUiLabels.xml   |  16 ---
 .../order/OrderRequirementServices.groovy          |  72 +++++++++++++
 .../order/minilang/order/OrderServices.xml         | 116 ---------------------
 applications/order/minilang/test/OrderTests.xml    |  18 +---
 .../order/servicedef/services_requirement.xml      |  22 ++--
 5 files changed, 80 insertions(+), 164 deletions(-)

diff --git a/applications/order/config/OrderErrorUiLabels.xml b/applications/order/config/OrderErrorUiLabels.xml
index 941e334..f655423 100644
--- a/applications/order/config/OrderErrorUiLabels.xml
+++ b/applications/order/config/OrderErrorUiLabels.xml
@@ -4020,22 +4020,6 @@
         <value xml:lang="zh">安全错误:要运行 createQuoteItem,你必须具有 ORDERMGR_CREATE 或 ORDERMGR_ADMIN 权限</value>
         <value xml:lang="zh-TW">安全錯誤:要運行 createQuoteItem,你必須具有 ORDERMGR_CREATE 或 ORDERMGR_ADMIN 權限</value>
     </property>
-    <property key="OrderSecurityErrorToRunCreateRequirementFromItemATP">
-        <value xml:lang="ar">خطأ أمني: لتشغيل  createRequirementFromItemATP يجب أن يكون لديك صلاحية ORDERMGR_CREATE أو ORDERMGR_ADMIN</value>
-        <value xml:lang="de">Berechtigungsfehler: Um 'createRequirementFromItemATP' auszuführen müssen Sie die ORDERMGR_CREATE oder ORDERMGR_ADMIN Berechtigungen haben</value>
-        <value xml:lang="en">Security Error: to run createRequirementFromItemATP you must have the ORDERMGR_CREATE or ORDERMGR_ADMIN permission</value>
-        <value xml:lang="es">Error de seguridad: Para ejecutar createRequirementFromItemATP debe contar con los permisos ORDERMGR_CREATE o ORDERMGR_ADMIN</value>
-        <value xml:lang="fr">Erreur de sécurité : pour exécuter createRequirementFromItemATP, vous devez avoir l'autorisation d'administrer ou de créer la commande</value>
-        <value xml:lang="it">Errore Sicurezza : per eseguire createRequirementFromItemATP tu devi avere il permesso ORDERMGR_CREATE o ORDERMGR_ADMIN</value>
-        <value xml:lang="ja">セキュリティエラー: createRequirementFromItemATPの実行には ORDERMGR_CREATE または ORDERMGR_ADMIN 権限が必要です</value>
-        <value xml:lang="pt-BR">Erro de segurança: para rodar createRequirementFromItemATP você deve ter a permissão ORDERMGR_CREATE ou ORDERMGR_ADMIN</value>
-        <value xml:lang="ro">Eroare Siguranta : pentru executarea createRequirementFromItemATP tu trebuie sa ai permisul ORDERMGR_CREATE sau ORDERMGR_ADMIN</value>
-        <value xml:lang="ru">Ошибка безопасности: для выполнения createRequirementFromItemATP у вас должны быть права ORDERMGR_CREATE или ORDERMGR_ADMIN </value>
-        <value xml:lang="th">Security Error: ความปลอดภัยผิดพลาด ! ถึงการดำเนินการ createRequirementFromItemATP คุณต้องมี ORDERMGR_CREATE หรือ ORDERMGR_ADMIN อนุญาต</value>
-        <value xml:lang="vi">Lỗi phân quyền: để thực thi dịch vụ createRequirementFromItemATP bạn cần có quyền ORDERMGR_CREATE hoặc ORDERMGR_ADMIN</value>
-        <value xml:lang="zh">安全错误:要运行 createRequirementFromItemATP,你必须具有 ORDERMGR_CREATE 或 ORDERMGR_ADMIN 权限</value>
-        <value xml:lang="zh-TW">安全錯誤:要運行 createRequirementFromItemATP,你必須具有 ORDERMGR_CREATE 或 ORDERMGR_ADMIN 權限</value>
-    </property>
     <property key="OrderSecurityErrorToRunCreateReturnHeader">
         <value xml:lang="ar">خطأ أمني: لتشغيل  createReturnHeader يجب أن يكون لديك صلاحية ORDERMGR_CREATE أو ORDERMGR_ADMIN</value>
         <value xml:lang="de">Berechtigungsfehler: Um 'createReturnHeader' auszuführen müssen Sie die ORDERMGR_CREATE oder ORDERMGR_ADMIN Berechtigungen haben</value>
diff --git a/applications/order/groovyScripts/order/OrderRequirementServices.groovy b/applications/order/groovyScripts/order/OrderRequirementServices.groovy
new file mode 100644
index 0000000..8dbafd6
--- /dev/null
+++ b/applications/order/groovyScripts/order/OrderRequirementServices.groovy
@@ -0,0 +1,72 @@
+/*
+ * 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.entity.GenericValue
+
+/*
+ * Create OrderRequirementCommitment and Requirement for items with automatic requirement upon ordering
+ */
+def checkCreateOrderRequirement() {
+    def reqMap = getProductRequirementMethod()
+    GenericValue order = reqMap.order
+    if (order.orderTypeId == 'SALES_ORDER' && reqMap.requirementMethodId == 'PRODRQM_AUTO') {
+        createRequirementAndCommitment()
+    }
+    success()
+}
+
+def getProductRequirementMethod() {
+    GenericValue order = from('OrderHeader').where(parameters).queryOne()
+    GenericValue product = from('Product').where(parameters).queryOne()
+    String requirementMethodId = product ? product.requirementMethodId : ''
+    if (!requirementMethodId && product) {
+        boolean isMarketingPkg = EntityTypeUtil.hasParentType(delegator, 'ProductType', 'productTypeId',
+                                                              product.productTypeId, 'parentTypeId', 'MARKETING_PKG')
+        if (!isMarketingPkg && product.productTypeId != 'DIGITAL_GOOD' && order) {
+            productStore = from('ProductStore').where(productStoreId: order.productStoreId).queryOne()
+            requirementMethodId = productStore ? productStore.requirementMethodEnumId : ''
+        }
+    }
+    return [order: order, requirementMethodId: requirementMethodId]
+
+}
+
+/*
+ * create a requirement and commitment for it
+ */
+def createRequirementAndCommitment() {
+    Map createRequirement = [requirementTypeId: 'PRODUCT_REQUIREMENT']
+    Map returnMap = success()
+
+    GenericValue order = from('OrderHeader').where(orderId: orderId).queryOne()
+    if (order) {
+        GenericValue productStore = from('ProductStore').where(productStoreId: order.productStoreId).queryOne()
+        if (productStore.inventoryFacilityId) {
+            createRequirement.facilityId = productStore.inventoryFacilityId
+        }
+        Map result = run service: 'createRequirement', with: createRequirement
+        returnMap.requirementId = result.requirementId
+        // create the OrderRequirementCommitment to record the Requirement created for an order item 
+
+        run service: 'createOrderRequirementCommitment', with: [*:parameters, requirementId: result.requirementId]
+    }
+    return returnMap
+}
+
diff --git a/applications/order/minilang/order/OrderServices.xml b/applications/order/minilang/order/OrderServices.xml
index 6906b73..f24b297 100644
--- a/applications/order/minilang/order/OrderServices.xml
+++ b/applications/order/minilang/order/OrderServices.xml
@@ -22,27 +22,6 @@ under the License.
         xmlns="http://ofbiz.apache.org/Simple-Method" xsi:schemaLocation="http://ofbiz.apache.org/Simple-Method http://ofbiz.apache.org/dtds/simple-methods.xsd">
 
     <!-- order requirement methods -->
-    <simple-method method-name="createRequirementAndCommitment" short-description="create a requirement and commitment for it">
-        <set value="PRODUCT_REQUIREMENT" field="inputMap.requirementTypeId"/>
-
-        <!-- Include the facilityId corresponding to this order by looking up the ProductStore -->
-        <entity-one entity-name="OrderHeader" value-field="orderHeader" auto-field-map="true"/>
-        <get-related-one value-field="orderHeader" relation-name="ProductStore" to-value-field="productStore" use-cache="true"/>
-        <if-not-empty field="productStore.inventoryFacilityId">
-            <set from-field="productStore.inventoryFacilityId" field="inputMap.facilityId"/>
-        </if-not-empty>
-
-        <call-service service-name="createRequirement" in-map-name="inputMap">
-            <result-to-field result-name="requirementId" field="parameters.requirementId"/>
-        </call-service>
-
-        <!-- create the OrderRequirementCommitment to record the Requirement created for an order item -->
-        <set-service-fields service-name="createOrderRequirementCommitment" map="parameters" to-map="orderReqCommitParams"/>
-        <call-service service-name="createOrderRequirementCommitment" in-map-name="orderReqCommitParams"/>
-
-        <field-to-result field="parameters.requirementId" result-name="requirementId"/>
-    </simple-method>
-
     <simple-method method-name="getProductFacilityAndQuantities" short-description="finds ProductFacility and QOH, ATP inventory for an inventoryItem">
         <!-- Get the ProductFacility for the minimum stock level -->
         <entity-one entity-name="ProductFacility" value-field="productFacility">
@@ -86,22 +65,6 @@ under the License.
         </if-empty>
     </simple-method>
 
-    <simple-method method-name="checkCreateOrderRequirement" short-description="Create OrderRequirementCommitment and Requirement">
-        <check-permission permission="ORDERMGR" action="_CREATE">
-            <fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunCheckCreateOrderRequirement"/>
-        </check-permission>
-        <check-errors/>
-        <call-simple-method method-name="getProductRequirementMethod"/>
-        <if-compare field="order.orderTypeId" operator="equals" value="SALES_ORDER">
-            <if-compare field="requirementMethodId" operator="equals" value="PRODRQM_AUTO">
-                <!-- create the requirement -->
-                <set from-field="parameters.productId" field="inputMap.productId"/>
-                <set from-field="parameters.quantity" field="inputMap.quantity"/>
-                <call-simple-method method-name="createRequirementAndCommitment"/>
-            </if-compare>
-        </if-compare>
-    </simple-method>
-
     <simple-method method-name="checkCreateStockRequirementQoh" short-description="Create a Requirement if QOH goes under the minimum stock level">
         <check-permission permission="ORDERMGR" action="_CREATE">
             <fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunCheckCreateStockRequirement"/>
@@ -202,85 +165,6 @@ under the License.
         </if-compare>
     </simple-method>
 
-    <simple-method method-name="createRequirementFromItemATP" short-description="Create a Requirement for an item based on ATP inventory quantity and minimum">
-        <!-- NOTE DEJ20090902: this service is not called anywhere, instead the createATPRequirementsForOrder service (written in Java) is called; why this is the case I don't know... -->
-        <check-permission permission="ORDERMGR" action="_CREATE">
-            <fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunCreateRequirementFromItemATP"/>
-        </check-permission>
-        <check-errors/>
-
-        <!-- assumes that inventoryItemId is one of the parameters and get the inventory item of the reservation -->
-        <entity-one entity-name="InventoryItem" value-field="inventoryItem" auto-field-map="true"/>
-
-        <!-- find the requirement method for this product -->
-        <set from-field="inventoryItem.productId" field="parameters.productId"/>
-        <call-simple-method method-name="getProductRequirementMethod"/>
-
-        <if-compare field="requirementMethodId" operator="equals" value="PRODRQM_ATP">
-            <!-- get the ATP, QOH quantities and the product facility's minimum stock -->
-            <call-simple-method method-name="getProductFacilityAndQuantities"/>
-
-            <if-empty field="productFacility">
-                <set field="minimumStock" value="0"/>
-                <else>
-                    <set field="minimumStock" from-field="productFacility.minimumStock"/>
-                </else>
-            </if-empty>
-            <!-- are we below minimum stock?  this service is supposed to be called after inventory is reserved, so inventory should have been updated already -->
-            <if-compare-field field="availableToPromiseTotal" to-field="minimumStock" operator="less" type="BigDecimal">
-                <!-- what is the right quantity?  It is the lesser of the actual quantity and the quantity required to bring us back up to minimum stock -->
-                <calculate field="quantityShortfall">
-                    <calcop operator="subtract" field="minimumStock">
-                        <calcop operator="get" field="availableToPromiseTotal"/>
-                    </calcop>
-                </calculate>
-                <if-compare-field field="quantityShortfall" operator="less" to-field="parameters.quantity" type="BigDecimal">
-                    <set from-field="quantityShortfall" field="inputMap.quantity"/>
-                <else>
-                    <set from-field="parameters.quantity" field="inputMap.quantity"/>
-                </else>
-                </if-compare-field>
-
-                <!-- TODO: we're not supporting the reorderQuantity of the productFacility.  It seems that altering the requirement quantity
-                    due to reorder quantities would affect the ability to link requirements and hence PO items back to the original order.
-                    If we can support it while at the same time linking requirements back to the original sales order, that would be better. -->
-                <set from-field="parameters.productId" field="inputMap.productId"/>
-                <set from-field="inventoryItem.facilityId" field="inputMap.facilityId"/>
-
-                <!-- Retrieve and total the quantities of existing requirements for the product/facility -->
-                <entity-condition entity-name="Requirement" list="requirements">
-                    <condition-list combine="and">
-                        <condition-expr field-name="productId" operator="equals" from-field="parameters.productId"/>
-                        <condition-expr field-name="requirementTypeId" operator="equals" value="PRODUCT_REQUIREMENT"/>
-                        <condition-expr field-name="facilityId" operator="equals" from-field="facilityId"/>
-                        <condition-expr field-name="statusId" operator="not-equals" value="REQ_ORDERED"/>
-                        <condition-expr field-name="statusId" operator="not-equals" value="REQ_REJECTED"/>
-                    </condition-list>
-                </entity-condition>
-                <iterate list="requirements" entry="requirement">
-                    <calculate field="existingRequirementTotal">
-                        <calcop operator="get" field="existingRequirementTotal"/>
-                        <calcop operator="get" field="requirement.quantity"/>
-                    </calculate>
-                </iterate>
-
-                <!-- Subtract the total quantity of existing requirements from the required quantity to determine if a new requirement needs to be created -->
-                <calculate field="newRequirementTotal">
-                    <calcop operator="subtract" field="inputMap.quantity">
-                        <calcop operator="get" field="existingRequirementTotal"/>
-                    </calcop>
-                </calculate>
-
-                <!-- If a new requirement needs to be created, create it for the difference between the required quantity and the total quantity of existing requirements -->
-                <if-compare field="newRequirementTotal" operator="greater-equals" value="0">
-                    <set from-field="inputMap.quantity" field="newRequirementTotal"/>
-                    <call-simple-method method-name="createRequirementAndCommitment"/>
-                </if-compare>
-
-            </if-compare-field>
-        </if-compare>
-    </simple-method>
-
     <simple-method method-name="checkCreateProductRequirementForFacility" short-description="Create Requirements for all the products in a facility with QOH under the minimum stock level">
         <check-permission permission="ORDERMGR" action="_CREATE">
             <fail-property resource="OrderErrorUiLabels" property="OrderSecurityErrorToRunCheckCreateStockRequirement"/>
diff --git a/applications/order/minilang/test/OrderTests.xml b/applications/order/minilang/test/OrderTests.xml
index 7800ab7..2d15880 100644
--- a/applications/order/minilang/test/OrderTests.xml
+++ b/applications/order/minilang/test/OrderTests.xml
@@ -110,22 +110,6 @@ under the License.
         </assert>
         <check-errors/>
     </simple-method>
-    <simple-method method-name="testCreateRequirementFromItemATP" short-description="Create Requirement From Item ATP" login-required="false">
-        <entity-one entity-name="UserLogin" value-field="userLogin">
-            <field-map field-name="userLoginId" value="system"/>
-        </entity-one>
-        <set-current-user-login value-field="userLogin"/>
-        <set field="serviceCtx.orderId" value="TEST_DEMO10090"/>
-        <set field="serviceCtx.orderItemSeqId" value="00001"/>
-        <set field="serviceCtx.shipGroupSeqId" value="00001"/>
-        <call-service service-name="createRequirementFromItemATP" in-map-name="serviceCtx">
-            <results-to-map map-name="serviceResult"/>
-        </call-service>
-        <assert>
-            <not><if-empty field="serviceResult"/></not>
-        </assert>
-        <check-errors/>
-    </simple-method>
     <simple-method method-name="testCreateAutoRequirementsForOrder" short-description="Create AutoRequirements For Order" login-required="false">
         <entity-one entity-name="UserLogin" value-field="userLogin">
             <field-map field-name="userLoginId" value="system"/>
@@ -154,4 +138,4 @@ under the License.
         </assert>
         <check-errors/>
     </simple-method>
-</simple-methods>
\ No newline at end of file
+</simple-methods>
diff --git a/applications/order/servicedef/services_requirement.xml b/applications/order/servicedef/services_requirement.xml
index a35edb6..4c1522b 100644
--- a/applications/order/servicedef/services_requirement.xml
+++ b/applications/order/servicedef/services_requirement.xml
@@ -110,11 +110,14 @@ under the License.
         <auto-attributes entity-name="OrderRequirementCommitment" include="pk" mode="IN" optional="false"/>
         <auto-attributes entity-name="OrderRequirementCommitment" include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="checkCreateOrderRequirement" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderServices.xml" invoke="checkCreateOrderRequirement">
+    <service name="checkCreateOrderRequirement" engine="groovy" auth="true"
+            location="component://order/groovyScripts/order/OrderRequirementServices.groovy" invoke="checkCreateOrderRequirement">
         <description>Create OrderRequirementCommitment and Requirement for items with automatic requirement upon ordering</description>
-        <attribute name="orderId" type="String" mode="IN" optional="false"/>
-        <attribute name="orderItemSeqId" type="String" mode="IN" optional="false"/>
+        <required-permissions join-type="AND">
+            <check-permission permission="ORDERMGR" action="_CREATE"/>
+        </required-permissions>
+        <attribute name="orderId" type="String" mode="IN"/>
+        <attribute name="orderItemSeqId" type="String" mode="IN"/>
         <attribute name="productId" type="String" mode="IN" optional="true"/>
         <attribute name="quantity" type="BigDecimal" mode="IN" optional="true"/>
         <attribute name="requirementId" type="String" mode="OUT" optional="true"/>
@@ -139,17 +142,6 @@ under the License.
         <attribute name="quantity" type="BigDecimal" mode="IN" optional="true"/>
         <attribute name="requirementId" type="String" mode="OUT" optional="true"/>
     </service>
-    <service name="createRequirementFromItemATP" engine="simple" auth="true"
-            location="component://order/minilang/order/OrderServices.xml" invoke="createRequirementFromItemATP">
-        <description>Create OrderRequirementCommitment and Requirement for items with requirement based on ATP stock levels</description>
-        <attribute name="orderId" type="String" mode="IN" optional="false"/>
-        <attribute name="shipGroupSeqId" type="String" mode="IN" optional="false"/>
-        <attribute name="orderItemSeqId" type="String" mode="IN" optional="false"/>
-        <attribute name="inventoryItemId" type="String" mode="IN" optional="true"/>
-        <attribute name="productId" type="String" mode="IN" optional="true"/>
-        <attribute name="quantity" type="BigDecimal" mode="IN" optional="true"/>
-        <attribute name="requirementId" type="String" mode="OUT" optional="true"/>
-    </service>
 
     <service name="checkCreateProductRequirementForFacility" engine="simple" auth="true"
             location="component://order/minilang/order/OrderServices.xml" invoke="checkCreateProductRequirementForFacility">