This is an automated email from the ASF dual-hosted git repository. danwatford 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 7b8eb1c3ca Improved: Ported createInventoryItem service to groovy (OFBIZ-12174) 7b8eb1c3ca is described below commit 7b8eb1c3cad526255c8acbc56ed549671c8e17df Author: Sebastian Berg <sebastian.b...@ecomify.de> AuthorDate: Wed Mar 1 10:26:59 2023 +0000 Improved: Ported createInventoryItem service to groovy (OFBIZ-12174) Changes made as part of porting InventoryServices implementation from minilang to groovy. Thanks: Sebastian Berg for implementation --- .../product/inventory/InventoryServices.groovy | 96 ++++++++++++- .../product/inventory/InventoryServices.xml | 154 --------------------- .../product/servicedef/services_facility.xml | 10 +- 3 files changed, 95 insertions(+), 165 deletions(-) diff --git a/applications/product/groovyScripts/product/inventory/InventoryServices.groovy b/applications/product/groovyScripts/product/inventory/InventoryServices.groovy index 9905610a28..5519d47d69 100644 --- a/applications/product/groovyScripts/product/inventory/InventoryServices.groovy +++ b/applications/product/groovyScripts/product/inventory/InventoryServices.groovy @@ -1,6 +1,3 @@ -import org.apache.ofbiz.base.util.UtilProperties -import org.apache.ofbiz.service.ServiceUtil - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -20,6 +17,10 @@ import org.apache.ofbiz.service.ServiceUtil * under the License. */ +import org.apache.ofbiz.base.util.UtilProperties +import org.apache.ofbiz.entity.GenericValue +import org.apache.ofbiz.service.ServiceUtil + /** * Check Facility Related Permission * @@ -97,3 +98,92 @@ def checkProductFacilityRelatedPermission() { } } +/** + * Create an InventoryItem + * @return + */ +def createInventoryItem() { + + GenericValue product = from("Product").where(productId: parameters.productId).queryOne() + + // Check if this product can or not have a lotId + if (product.lotIdFilledIn == "Mandatory" && !parameters.lotId) { + return error(label("ProductErrorUiLabels", "ProductLotIdMandatory", [parameters: parameters])) + } else if (product.lotIdFilledIn == "Forbidden" && parameters.lotId) { + return error(label("ProductErrorUiLabels", "ProductLotIdForbidden", [parameters: parameters])) + } + + // If this InventoryItem is returned by a manufacturing task, don't create a lot + if (parameters.isReturned == "N" && parameters.lotId) { + // Create the lot if if doesn't already exist. + List<GenericValue> lotList = from("Lot").where(lotId: parameters.lotId).queryList() + if (!lotList) { + GenericValue lot = makeValue("Lot") + lot.lotId = parameters.lotId + lot.create() + } + } + + GenericValue inventoryItem = makeValue("InventoryItem") + // TODO: make sure availableToPromiseTotal and quantityOnHandTotal are not changed + inventoryItem.setNonPKFields(parameters) + + if (!inventoryItem.facilityId) { + return error(label("ProductUiLabels", "FacilityInventoryItemsMissingFacilityId")) + } + + // if inventoryItem's ownerPartyId is empty, get the ownerPartyId from the facility + if (!inventoryItem.ownerPartyId) { + GenericValue facility = delegator.getRelatedOne("Facility", inventoryItem, false) + inventoryItem.ownerPartyId = facility.ownerPartyId + // if inventoryItem's ownerPartyId is still empty, return an error message + if (!inventoryItem.ownerPartyId) { + return error(label("ProductUiLabels", "FacilityInventoryItemsMissingOwnerPartyId")) + } + } + + // if inventoryItem's currencyUomId is empty, get the currencyUomId + // from the party accounting preferences of the owner of the inventory item + if (!inventoryItem.currencyUomId) { + Map partyAccountingPreferencesCallMap = [organizationPartyId: inventoryItem.ownerPartyId] + Map serviceResult = run service: "getPartyAccountingPreferences", with: partyAccountingPreferencesCallMap + Map accPref = serviceResult.partyAccountingPreference + inventoryItem.currencyUomId = accPref.baseCurrencyUomId + if (!inventoryItem.currencyUomId) { + inventoryItem.currencyUomId = UtilProperties.getPropertyValue('general.properties', 'currency.uom.id.default') + } + // if inventoryItem's currencyUomId is still empty, return an error message + if (!inventoryItem.currencyUomId) { + return error(label("ProductUiLabels", "FacilityInventoryItemsMissingCurrencyId")) + } + } + + // if inventoryItem's unitCost is empty, get the product's standard + // cost by calling the getProductCost service + if (!inventoryItem.unitCost) { + // TODO: create a new service getProductStdCost that calls getProductCost + Map inputMap = [productId: inventoryItem.productId, currencyUomId: inventoryItem.currencyUomId, costComponentTypePrefix: "EST_STD"] + Map productCostResult = run service: "getProductCost", with: inputMap + if (!ServiceUtil.isSuccess(productCostResult)) { + return productCostResult + } + inventoryItem.unitCost = productCostResult.productCost + } + + // if inventoryItem's unitCost is still empty, or negative return an error message + // TODO/WARNING: getProductCost returns 0 even if no std costs are found + if (!inventoryItem.unitCost && inventoryItem.unitCost != (BigDecimal) 0) { + return error(label("ProductUiLabels", "FacilityInventoryItemsMissingUnitCost")) + } + + // if you don't want inventory item with unitCost = 0, change the operator + // attribute from "less" to "less-equals". + if (inventoryItem.unitCost < (BigDecimal) 0) { + return error(label("ProductUiLabels", "FacilityInventoryItemsNegativeUnitCost")) + } + + inventoryItem.inventoryItemId = delegator.getNextSeqId("InventoryItem") + inventoryItem.create() + + return success([inventoryItemId: inventoryItem.inventoryItemId]) +} diff --git a/applications/product/minilang/product/inventory/InventoryServices.xml b/applications/product/minilang/product/inventory/InventoryServices.xml index 2faa942cbc..bf3525e132 100644 --- a/applications/product/minilang/product/inventory/InventoryServices.xml +++ b/applications/product/minilang/product/inventory/InventoryServices.xml @@ -22,72 +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"> <!-- InventoryItem methods --> - <simple-method method-name="createInventoryItem" short-description="Create an InventoryItem"> - - <!-- Create a lot before --> - <entity-one value-field="product" entity-name="Product"> - <field-map field-name="productId" from-field="parameters.productId"/> - </entity-one> - - <!-- Check if this product can or not have a lotId --> - <if> - <condition> - <and> - <if-compare operator="equals" value="Mandatory" field="product.lotIdFilledIn" /> - <if-empty field="parameters.lotId" /> - </and> - </condition> - <then> - <add-error> - <fail-property resource="ProductErrorUiLabels" property="ProductLotIdMandatory"/> - </add-error> - </then> - </if> - - <if> - <condition> - <and> - <if-compare operator="equals" value="Forbidden" field="product.lotIdFilledIn" /> - <not> - <if-empty field="parameters.lotId" /> - </not> - </and> - </condition> - <then> - <add-error> - <fail-property resource="ProductErrorUiLabels" property="ProductLotIdForbidden"/> - </add-error> - </then> - </if> - - <check-errors /> - - <!-- If this InventoryItem is returned by a manufacturing task, don't create a lot --> - <if-compare operator="equals" value="N" field="parameters.isReturned"> - <if-not-empty field="parameters.lotId"> - <!-- Check if the lot already exists --> - <entity-and entity-name="Lot" list="lotList"> - <field-map field-name="lotId" from-field="parameters.lotId" /> - </entity-and> - <if-empty field="lotList"> - <make-value entity-name="Lot" value-field="lot"/> - <set field="lot.lotId" from-field="parameters.lotId"/> - <create-value value-field="lot"/> - </if-empty> - </if-not-empty> - </if-compare> - - <make-value entity-name="InventoryItem" value-field="inventoryItem"/> - <!-- TODO: make sure availableToPromiseTotal and quantityOnHandTotal are not changed --> - <set-nonpk-fields map="parameters" value-field="inventoryItem"/> - - <call-simple-method method-name="inventoryItemCheckSetDefaultValues"/> - <check-errors/> - - <sequenced-id sequence-name="InventoryItem" field="inventoryItem.inventoryItemId"/> - <create-value value-field="inventoryItem"/> - <field-to-result field="inventoryItem.inventoryItemId" result-name="inventoryItemId"/> - </simple-method> <simple-method method-name="createInventoryItemCheckSetAtpQoh" short-description="createInventoryItemCheckSetAtpQoh" login-required="false"> <if> <condition> @@ -105,94 +39,6 @@ under the License. </then> </if> </simple-method> - <simple-method method-name="inventoryItemCheckSetDefaultValues" short-description="Check and, if empty, fills with default values ownerPartyId, currencyUomId, unitCost" login-required="false"> - <if-empty field="inventoryItem"> - <entity-one entity-name="InventoryItem" value-field="inventoryItem"/> - <set field="updateInventoryItem" value="Y"/> - </if-empty> - <!-- if all the inventoryItem's fields are already filled, return with success --> - <if> - <condition> - <and> - <not><if-empty field="inventoryItem.facilityId"/></not> - <not><if-empty field="inventoryItem.ownerPartyId"/></not> - <not><if-empty field="inventoryItem.currencyUomId"/></not> - <not><if-empty field="inventoryItem.unitCost"/></not> - </and> - </condition> - <then> - <return/> - </then> - </if> - <if-empty field="inventoryItem.facilityId"> - <add-error> - <fail-property resource="ProductUiLabels" property="FacilityInventoryItemsMissingFacilityId"/> - </add-error> - <check-errors/> - </if-empty> - <!-- if inventoryItem's ownerPartyId is empty, get the ownerPartyId from the facility --> - <if-empty field="inventoryItem.ownerPartyId"> - <get-related-one value-field="inventoryItem" relation-name="Facility" to-value-field="facility"/> - <set field="inventoryItem.ownerPartyId" from-field="facility.ownerPartyId"/> - <!-- if inventoryItem's ownerPartyId is still empty, return an error message --> - <if-empty field="inventoryItem.ownerPartyId"> - <add-error> - <fail-property resource="ProductUiLabels" property="FacilityInventoryItemsMissingOwnerPartyId"/> - </add-error> - <check-errors/> - </if-empty> - </if-empty> - <!-- if inventoryItem's currencyUomId is empty, get the currencyUomId - from the party accounting preferences of the owner of the inventory item --> - <if-empty field="inventoryItem.currencyUomId"> - <set field="partyAccountingPreferencesCallMap.organizationPartyId" from-field="inventoryItem.ownerPartyId"/> - <call-service service-name="getPartyAccountingPreferences" in-map-name="partyAccountingPreferencesCallMap"> - <result-to-field result-name="partyAccountingPreference" field="accPref"/> - </call-service> - <set field="inventoryItem.currencyUomId" from-field="accPref.baseCurrencyUomId"/> - <if-empty field="inventoryItem.currencyUomId"> - <property-to-field resource="general" property="currency.uom.id.default" field="inventoryItem.currencyUomId"/> - </if-empty> - <!-- if inventoryItem's currencyUomId is still empty, return an error message --> - <if-empty field="inventoryItem.currencyUomId"> - <add-error> - <fail-property resource="ProductUiLabels" property="FacilityInventoryItemsMissingCurrencyId"/> - </add-error> - <check-errors/> - </if-empty> - </if-empty> - <!-- if inventoryItem's unitCost is empty, get the product's standard - cost by calling the getProductCost service --> - <if-empty field="inventoryItem.unitCost"> - <set from-field="inventoryItem.productId" field="inputMap.productId"/> - <set from-field="inventoryItem.currencyUomId" field="inputMap.currencyUomId"/> - <set value="EST_STD" field="inputMap.costComponentTypePrefix"/> <!-- TODO: create a new service getProductStdCost that calls getProductCost --> - <call-service service-name="getProductCost" in-map-name="inputMap"> - <result-to-field result-name="productCost" field="inventoryItem.unitCost"/> - </call-service> - </if-empty> - <!-- if inventoryItem's unitCost is still empty, or negative return an error message --> - <!-- TODO/WARNING: getProductCost returns 0 even if no std costs are found --> - <if-empty field="inventoryItem.unitCost"> - <add-error> - <fail-property resource="ProductUiLabels" property="FacilityInventoryItemsMissingUnitCost"/> - </add-error> - </if-empty> - <check-errors/> - <!-- if you don't want inventory item with unitCost = 0, change the operator - attribute from "less" to "less-equals". - --> - <if-compare field="inventoryItem.unitCost" operator="less" value="0" type="BigDecimal"> - <add-error> - <fail-property resource="ProductUiLabels" property="FacilityInventoryItemsNegativeUnitCost"/> - </add-error> - </if-compare> - <check-errors/> - <if-not-empty field="updateInventoryItem"> - <store-value value-field="inventoryItem"/> - </if-not-empty> - </simple-method> - <simple-method method-name="updateInventoryItem" short-description="Update an InventoryItem"> <make-value entity-name="InventoryItem" value-field="lookupPKMap"/> <set-pk-fields map="parameters" value-field="lookupPKMap"/> diff --git a/applications/product/servicedef/services_facility.xml b/applications/product/servicedef/services_facility.xml index d97e2eabaf..f0696c83b3 100644 --- a/applications/product/servicedef/services_facility.xml +++ b/applications/product/servicedef/services_facility.xml @@ -35,8 +35,8 @@ under the License. <implements service="permissionInterface"/> </service> <!-- Product Inventory Services --> - <service name="createInventoryItem" default-entity-name="InventoryItem" engine="simple" - location="component://product/minilang/product/inventory/InventoryServices.xml" invoke="createInventoryItem" auth="true"> + <service name="createInventoryItem" default-entity-name="InventoryItem" engine="groovy" + location="component://product/groovyScripts/product/inventory/InventoryServices.groovy" invoke="createInventoryItem" auth="true"> <description>Create an InventoryItem</description> <permission-service service-name="facilityGenericPermission" main-action="CREATE"/> <auto-attributes include="pk" mode="OUT" optional="false"/> @@ -105,12 +105,6 @@ under the License. </attribute> </service> - <service name="inventoryItemCheckSetDefaultValues" default-entity-name="InventoryItem" engine="simple" - location="component://product/minilang/product/inventory/InventoryServices.xml" invoke="inventoryItemCheckSetDefaultValues" auth="false"> - <description>Check and, if empty, fills with default values ownerPartyId, currencyUomId, unitCost</description> - <attribute name="inventoryItemId" type="String" mode="IN" optional="true"/> - <attribute name="inventoryItem" type="Map" mode="IN" optional="true"/> - </service> <service name="createInventoryItemDetail" default-entity-name="InventoryItemDetail" engine="simple" location="component://product/minilang/product/inventory/InventoryServices.xml" invoke="createInventoryItemDetail" auth="true"> <description>Create an createInventoryItemDetail - note that the quantityOnHand and availableToPromise are relative (positive or negative) and will be added to the corresponding value on the given InventoryItem</description>