This is an automated email from the ASF dual-hosted git repository.
nmalin 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 b134c6b Improved: Convert ProductionRunServices.xml file from mini-lang to groovy DSL (OFBIZ-11395) b134c6b is described below commit b134c6b72fff1d625b0e5c2b88a2933378353596 Author: Nicolas Malin <[hidden email]> AuthorDate: Tue May 19 17:09:34 2020 +0200 Improved: Convert ProductionRunServices.xml file from mini-lang to groovy DSL (OFBIZ-11395) Thanks to Yashwant Dhakad for this patch --- .../jobshopmgt/ProductionRunServices.groovy | 397 +++++++++++++++++ .../minilang/jobshopmgt/ProductionRunServices.xml | 495 --------------------- .../servicedef/services_production_run.xml | 20 +- 3 files changed, 407 insertions(+), 505 deletions(-) diff --git a/applications/manufacturing/groovyScripts/jobshopmgt/ProductionRunServices.groovy b/applications/manufacturing/groovyScripts/jobshopmgt/ProductionRunServices.groovy new file mode 100644 index 0000000..30690ce --- /dev/null +++ b/applications/manufacturing/groovyScripts/jobshopmgt/ProductionRunServices.groovy @@ -0,0 +1,397 @@ +/* + * 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 + +/** + * Assign the selected party to the production run or task. + */ +def createProductionRunPartyAssign() { + parameters.statusId = "PRTYASGN_ASSIGNED" + if (!parameters.workEffortId) { + parameters.workEffortId = parameters.productionRunId + } + + Map serviceResult = run service: "assignPartyToWorkEffort", with: parameters + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + return [successMessage: null, productionRunId: parameters.workEffortId] +} + +/** + *Associate the production run to another production run + */ +def createProductionRunAssoc() { + Map serviceContext = [workEffortAssocTypeId: "WORK_EFF_PRECEDENCY"] + if ("WF_PREDECESSOR" == parameters.workFlowSequenceTypeId) { + serviceContext.workEffortIdFrom = parameters.productionRunIdTo + serviceContext.workEffortIdTo = parameters.productionRunId + } else if ("WF_SUCCESSOR" == parameters.workFlowSequenceTypeId) { + serviceContext.workEffortIdFrom = parameters.productionRunId + serviceContext.workEffortIdTo = parameters.productionRunIdTo + } + + Map serviceResult = run service: "createWorkEffortAssoc", with: serviceContext + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + return success() +} + +/** + *Issues the Inventory for a Production Run Task + */ +def issueProductionRunTask() { + GenericValue workEffort = from("WorkEffort").where(parameters).queryOne() + parameters.failIfItemsAreNotAvailable = parameters.failIfItemsAreNotAvailable ?: "Y" + parameters.failIfItemsAreNotOnHand = parameters.failIfItemsAreNotOnHand ?: "Y" + if (workEffort && "PRUN_CANCELLED" != workEffort.currentStatusId) { + from("WorkEffortGoodStandard") + .where(workEffortId: workEffort.workEffortId, + statusId: "WEGS_CREATED", + workEffortGoodStdTypeId: "PRUNT_PROD_NEEDED") + .filterByDate() + .queryList() + .each { component -> + if (component.productId) { + Map callSvcMap = component.getAllFields() + BigDecimal totalIssuance = 0.0 + from("WorkEffortAndInventoryAssign") + .where(workEffortId: workEffort.workEffortId, + productId: component.productId) + .queryList() + .each { issuance -> + if (issuance.quantity) { + totalIssuance += issuance.quantity + } + } + if (totalIssuance != 0) { + callSvcMap.quantity = component.estimatedQuantity - totalIssuance + } + callSvcMap.reserveOrderEnumId = parameters.reserveOrderEnumId + callSvcMap.description = "BOM Part" + callSvcMap.failIfItemsAreNotAvailable = parameters.failIfItemsAreNotAvailable + callSvcMap.failIfItemsAreNotOnHand = parameters.failIfItemsAreNotOnHand + + Map serviceResult = run service: "issueProductionRunTaskComponent", with: callSvcMap + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + } + logInfo("Issued inventory for workEffortId ${workEffort.workEffortId}") + } + } + return success() +} + +/** + *Issues the Inventory for a Production Run Task Component + */ +def issueProductionRunTaskComponent() { + GenericValue workEffort = from("WorkEffort").where("workEffortId", parameters.workEffortId).queryOne() + GenericValue productionRun = from("WorkEffort").where("workEffortId", workEffort.workEffortParentId).queryOne() + if (['PRUN_CANCELLED', 'PRUN_CLOSED'].contains(productionRun.currentStatusId)) { + return error(UtilProperties.getMessage('ManufacturingUiLabels', + 'ManufacturingAddProdCompInCompCanStatusError', locale)) + } + String productId = parameters.productId + GenericValue workEffortGoodStandard = null + BigDecimal estimatedQuantity = parameters.quantity ?: 0.0 + if (parameters.fromDate) { + workEffortGoodStandard = from("WorkEffortGoodStandard") + .where("workEffortId", parameters.workEffortId, + "productId", parameters.productId, + "fromDate", parameters.fromDate, + "workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED") + .queryOne() + productId = workEffortGoodStandard.productId + if (!parameters.quantity) { + estimatedQuantity = workEffortGoodStandard.estimatedQuantity + } + + if (!productId) { + Map serviceResult = run service: "createWorkEffortGoodStandard", with: [workEffortId: parameters.workEffortId, + productId: parameters.productId, + workEffortGoodStdTypeId: "PRUNT_PROD_NEEDED", + fromDate: parameters.fromDate, + estimatedQuantity: estimatedQuantity, + statusId: "WEGS_CREATED"] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + // if the task is in completed status we want to make WEIA for the added product as well + if ("PRUN_COMPLETED" == workEffort.currentStatusId) { + productId = parameters.productId + } + } + + // kind of like the inventory reservation routine, find InventoryItems to issue from, + // but instead of doing the reservation just create an issuance and an inventory item detail for the change + if (productId) { + String orderBy = "+datetimeReceived" + nowTimestamp = UtilDateTime.nowTimestamp() + + // before we do the find, put together the orderBy list based on which reserveOrderEnumId is specified + switch (parameters.reserveOrderEnumId) { + case "INVRO_FIFO_EXP": + orderBy = "+expireDate" + break + case "INVRO_LIFO_EXP": + orderBy = "-expireDate" + break + case "INVRO_LIFO_REC": + orderBy = "-datetimeReceived" + break + default: + parameters.reserveOrderEnumId = "INVRO_FIFO_REC" + break + } + Map lookupFieldMap = [productId: productId, + facilityId: workEffort.facilityId] + if (parameters.lotId) { + parameters.failIfItemsAreNotAvailable = "Y" + lookupFieldMap.lotId = parameters.lotId + } + if (parameters.locationSeqId) { + lookupFieldMap.locationSeqId = parameters.locationSeqId + } + List inventoryItemList = from("InventoryItem") + .where(lookupFieldMap) + .orderBy(orderBy) + .queryList() + + if (parameters.locationSeqId && parameters.secondaryLocationSeqId) { + lookupFieldMap.locationSeqId = parameters.locationSeqId + inventoryItemList << from("InventoryItem") + .where(lookupFieldMap) + .orderBy(orderBy) + .queryList() + } + + GenericValue lastNonSerInventoryItem = null + parameters.quantityNotIssued = estimatedQuantity + parameters.useReservedItems = "N" + + inventoryItemList.each { inventoryItem -> + issueProductionRunTaskComponentInline(parameters, inventoryItem, lastNonSerInventoryItem) + } + + if (parameters.failIfItemsAreNotAvailable != "Y" && parameters.quantityNotIssued != 0) { + parameters.useReservedItems = "Y" + inventoryItemList.each { inventoryItem -> + if (parameters.quantityNotIssued > 0) { + inventoryItem.refresh() + issueProductionRunTaskComponentInline(parameters, inventoryItem, lastNonSerInventoryItem) + } + } + } + // if quantityNotIssued is not 0, then pull it from the last non-serialized inventory item found, in the quantityNotIssued field + if (parameters.quantityNotIssued != 0) { + if (parameters.failIfItemsAreNotAvailable == "Y" || !parameters.failIfItemsAreNotOnHand) { + GenericValue product + if (productId) { + product = from("Product").where(productId: productId).cache().queryOne() + } + Map paramMap = [productId: productId, + internalName: product ? product.internalName : '', + parameters: parameters] + return ServiceUtil.returnError((UtilProperties.getMessage('ManufacturingUiLabels', + 'ManufacturingMaterialsNotAvailable', paramMap, parameters.locale))) + } + if (lastNonSerInventoryItem) { + Map serviceResult = run service: "assignInventoryToWorkEffort", with: [workEffortId: parameters.workEffortId, + inventoryItemId: lastNonSerInventoryItem.inventoryItemId, + quantity: parameters.quantityNotIssued] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + + // subtract from quantityNotIssued from the availableToPromise and quantityOnHand of existing inventory item + // instead of updating InventoryItem, add an InventoryItemDetail + serviceResult = run service: "createInventoryItemDetail", with: [inventoryItemId: lastNonSerInventoryItem.inventoryItemId, + workEffortId: parameters.workEffortId, + availableToPromiseDiff: -parameters.quantityNotIssued, + quantityOnHandDiff: -parameters.quantityNotIssued, + reasonEnumId: parameters.reasonEnumId, + description: parameters.description] + if (ServiceUtil.isError(serviceResult)) { + return error(ServiceUtil.getErrorMessage(serviceResult)) + } + serviceResult = run service: "balanceInventoryItems", with: [inventoryItemId: lastNonSerInventoryItem.inventoryItemId] + if (ServiceUtil.isError(serviceResult)) { + return error(ServiceUtil.getErrorMessage(serviceResult)) + } + } else { + // no non-ser inv item, create a non-ser InventoryItem with availableToPromise = -quantityNotIssued + Map serviceResult = run service: "createInventoryItem", with: [productId: productId, + facilityId: workEffort.facilityId, + inventoryItemTypeId: "NON_SERIAL_INV_ITEM"] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + String inventoryItemId = serviceResult.inventoryItemId + serviceResult = run service: "assignInventoryToWorkEffort", with: [workEffortId: workEffort.workEffortId, + inventoryItemId: inventoryItemId, + quantity: parameters.quantityNotIssued] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + + // also create a detail record with the quantities + serviceResult = run service: "createInventoryItemDetail", + with: [workEffortId: workEffort.workEffortId, + inventoryItemId: inventoryItemId, + availableToPromiseDiff: -parameters.quantityNotIssued, + quantityOnHandDiff: -parameters.quantityNotIssued, + reasonEnumId: parameters.reasonEnumId, + description: parameters.description] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + parameters.quantityNotIssued = 0.0 + } + } + if (workEffortGoodStandard) { + BigDecimal totalIssuance = 0.0 + from("WorkEffortAndInventoryAssign") + .where("workEffortId", workEffortGoodStandard.workEffortId, + "productId", workEffortGoodStandard.productId) + .queryList() + .each { issuance -> + totalIssuance += issuance.quantity + } + if (workEffortGoodStandard.estimatedQuantity <= totalIssuance) { + workEffortGoodStandard.statusId = "WEGS_COMPLETED" + workEffortGoodStandard.store() + } + } + } + } + return success() +} + + +/** + *Does a issuance for one InventoryItem, meant to be called in-line + */ +def issueProductionRunTaskComponentInline(Map parameters, + GenericValue inventoryItem, + GenericValue lastNonSerInventoryItem) { + + if (parameters.quantityNotIssued > 0) { + if ("SERIALIZED_INV_ITEM" == inventoryItem.inventoryItemTypeId && + "INV_AVAILABLE" == inventoryItem.statusId) { + inventoryItem.statusId = "INV_DELIVERED" + inventoryItem.store() + Map serviceResult = run service: "assignInventoryToWorkEffort", with: [workEffortId: parameters.workEffortId, + inventoryItemId: parameters.inventoryItemId, + quantity: 1] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + parameters.quantityNotIssued = parameters.quantityNotIssued - 1 + } + if ((!inventoryItem.statusId || "INV_AVAILABLE" == inventoryItem.statusId) && + "NON_SERIAL_INV_ITEM" == inventoryItem.inventoryItemTypeId) { + BigDecimal inventoryItemQuantity = "Y" != parameters.useReservedItems ? + inventoryItem.availableToPromiseTotal: + inventoryItem.quantityOnHandTotal + + // reduce atp on inventoryItem if availableToPromise greater than 0, if not the code at the end of this method will handle it + if (inventoryItemQuantity && inventoryItemQuantity > 0) { + parameters.deductAmount = parameters.quantityNotIssued > inventoryItemQuantity ? + inventoryItemQuantity: + parameters.quantityNotIssued + Map serviceResult = run service: "assignInventoryToWorkEffort", with: [workEffortId: parameters.workEffortId, + inventoryItemId: inventoryItem.inventoryItemId, + quantity: parameters.deductAmount] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + + serviceResult = run service: "createInventoryItemDetail", with: [inventoryItemId: inventoryItem.inventoryItemId, + workEffortId: parameters.workEffortId, + availableToPromiseDiff: -parameters.deductAmount, + quantityOnHandDiff: -parameters.deductAmount, + reasonEnumId: parameters.reasonEnumId, + description: parameters.description] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + parameters.quantityNotIssued -= parameters.deductAmount + serviceResult = run service: "balanceInventoryItems", with: [inventoryItemId: inventoryItem.inventoryItemId] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + lastNonSerInventoryItem = inventoryItem + } + } + } + return success() +} + +/** + *Issue one InventoryItem to a WorkEffort + */ +def issueInventoryItemToWorkEffort() { + GenericValue inventoryItem = parameters.inventoryItem + BigDecimal quantityIssued = 0.0 + if ("SERIALIZED_INV_ITEM" == inventoryItem.inventoryItemTypeId && inventoryItem.statusId) { + inventoryItem.statusId = "INV_DELIVERED" + inventoryItem.store() + quantityIssued = 1 + Map serviceResult = run service: "assignInventoryToWorkEffort", with: [workEffortId: parameters.workEffortId, + inventoryItemId: inventoryItem.inventoryItemId, + quantity: quantityIssued] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + } + if ("NON_SERIAL_INV_ITEM" == inventoryItem.inventoryItemTypeId && + inventoryItem.availableToPromiseTotal && + inventoryItem.availableToPromiseTotal > 0) { + + quantityIssued = !parameters.quantity || parameters.quantity > inventoryItem.availableToPromiseTotal ? + parameters.quantity: + inventoryItem.availableToPromiseTotal + Map serviceResult = run service: "assignInventoryToWorkEffort", with: [workEffortId: parameters.workEffortId, + inventoryItemId: inventoryItem.inventoryItemId, + quantity: quantityIssued] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + + serviceResult = run service: "createInventoryItemDetail", with: [inventoryItemId: inventoryItem.inventoryItemId, + workEffortId: parameters.workEffortId, + availableToPromiseDiff: - quantityIssued, + quantityOnHandDiff: - quantityIssued, + reasonEnumId: parameters.reasonEnumId, + description: parameters.description] + if (ServiceUtil.isError(serviceResult)) { + return serviceResult + } + parameters.quantityNotIssued -= parameters.deductAmount + } + return [successMessage: null, finishedProductId: inventoryItem.productId, quantityIssued: quantityIssued] +} \ No newline at end of file diff --git a/applications/manufacturing/minilang/jobshopmgt/ProductionRunServices.xml b/applications/manufacturing/minilang/jobshopmgt/ProductionRunServices.xml deleted file mode 100644 index c98d188..0000000 --- a/applications/manufacturing/minilang/jobshopmgt/ProductionRunServices.xml +++ /dev/null @@ -1,495 +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="createProductionRunPartyAssign" - short-description="Assign the selected party to the production run or task"> - - <set field="parameters.statusId" value="PRTYASGN_ASSIGNED"/> - - <if-empty field="parameters.workEffortId"> - <set field="parameters.workEffortId" from-field="parameters.productionRunId"/> - </if-empty> - - <field-to-result field="parameters.productionRunId" result-name="productionRunId" /> - <call-simple-method method-name="assignPartyToWorkEffort" - xml-resource="component://workeffort/minilang/workeffort/WorkEffortSimpleServices.xml" /> - - </simple-method> - <simple-method method-name="createProductionRunAssoc" short-description="Associate the production run to another production run"> - - <if-compare field="parameters.workFlowSequenceTypeId" operator="equals" value="WF_PREDECESSOR"> - <set field="ctx.workEffortIdFrom" from-field="parameters.productionRunIdTo"/> - <set field="ctx.workEffortIdTo" from-field="parameters.productionRunId"/> - </if-compare> - <if-compare field="parameters.workFlowSequenceTypeId" operator="equals" value="WF_SUCCESSOR"> - <set field="ctx.workEffortIdFrom" from-field="parameters.productionRunId"/> - <set field="ctx.workEffortIdTo" from-field="parameters.productionRunIdTo"/> - </if-compare> - - <set field="ctx.workEffortAssocTypeId" value="WORK_EFF_PRECEDENCY"/> - <call-service service-name="createWorkEffortAssoc" in-map-name="ctx"/> - </simple-method> - - <!-- Warehouse --> - <simple-method method-name="issueProductionRunTask" short-description="Issues the Inventory for a Production Run Task" login-required="false"> - <entity-one entity-name="WorkEffort" value-field="workEffort"/> - <if-empty field="parameters.failIfItemsAreNotAvailable"> - <set field="parameters.failIfItemsAreNotAvailable" value="Y"/> - </if-empty> - <if-empty field="parameters.failIfItemsAreNotOnHand"> - <set field="parameters.failIfItemsAreNotOnHand" value="Y"/> - </if-empty> - <if-not-empty field="workEffort"> - <if-compare value="PRUN_CANCELLED" operator="not-equals" field="workEffort.currentStatusId"> - <set from-field="parameters.workEffortId" field="lookupComponentsMap.workEffortId"/> - <set value="WEGS_CREATED" field="lookupComponentsMap.statusId"/> - <set field="lookupComponentsMap.workEffortGoodStdTypeId" value="PRUNT_PROD_NEEDED"/> - - <find-by-and entity-name="WorkEffortGoodStandard" list="components" map="lookupComponentsMap"/> - <filter-list-by-date list="components"/> - <!-- now go through each work effort good standard and call a service to issue the inventory --> - <iterate list="components" entry="component"> - <if-not-empty field="component.productId"> - <clear-field field="callSvcMap"/> - <set-service-fields service-name="issueProductionRunTaskComponent" map="component" to-map="callSvcMap"/> - <set from-field="reserveOrderEnumId" field="callSvcMap.reserveOrderEnumId"/> - <!-- calculate quantity needed if the produced run quantity is produced partially --> - <entity-and entity-name="WorkEffortAndInventoryAssign" list="issuances"> - <field-map field-name="workEffortId" from-field="workEffort.workEffortId"/> - <field-map field-name="productId" from-field="component.productId"/> - </entity-and> - <set field="totalIssuance" value="0.00" type="BigDecimal"/> - <iterate list="issuances" entry="issuance"> - <calculate field="totalIssuance"> - <calcop operator="add"> - <calcop operator="get" field="issuance.quantity"/> - <calcop operator="get" field="totalIssuance"/> - </calcop> - </calculate> - </iterate> - - <if-compare field="totalIssuance" operator="not-equals" value="0.00"> - <set field="callSvcMap.quantity" value="0.00" type="BigDecimal"/> - <calculate field="callSvcMap.quantity"> - <calcop operator="subtract" field="component.estimatedQuantity"> - <calcop operator="get" field="totalIssuance"/> - </calcop> - </calculate> - </if-compare> - <set field="callSvcMap.description" value="BOM Part"/> - <set field="callSvcMap.failIfItemsAreNotAvailable" from-field="parameters.failIfItemsAreNotAvailable"/> - <set field="callSvcMap.failIfItemsAreNotOnHand" from-field="parameters.failIfItemsAreNotOnHand"/> - <call-service service-name="issueProductionRunTaskComponent" in-map-name="callSvcMap"/> - </if-not-empty> - </iterate> - <log level="info" message="Issued inventory for workEffortId ${workEffort.workEffortId}."/> - </if-compare> - </if-not-empty> - </simple-method> - <simple-method method-name="issueProductionRunTaskComponent" short-description="Issues the Inventory for a Production Run Task Component" login-required="false"> - - <!-- NOTE: the inventory will be issued from the WorkEffort.facilityId --> - <entity-one entity-name="WorkEffort" value-field="workEffort"/> - <entity-one entity-name="WorkEffort" value-field="productionRun"> - <field-map field-name="workEffortId" from-field="workEffort.workEffortParentId"/> - </entity-one> - <if> - <condition> - <or> - <if-compare field="productionRun.currentStatusId" operator="equals" value="PRUN_CANCELLED"/> - <if-compare field="productionRun.currentStatusId" operator="equals" value="PRUN_CLOSED"/> - </or> - </condition> - <then> - <add-error> - <fail-property property="ManufacturingAddProdCompInCompCanStatusError" resource="ManufacturingUiLabels"/> - </add-error> - </then> - </if> - <check-errors/> - - <if-empty field="parameters.fromDate"> - <set field="productId" from-field="parameters.productId"/> - <set from-field="parameters.quantity" field="estimatedQuantity" default-value="0.0" type="BigDecimal"/> - <else> - <entity-one entity-name="WorkEffortGoodStandard" value-field="workEffortGoodStandard" auto-field-map="false"> - <field-map field-name="workEffortId" from-field="parameters.workEffortId"/> - <field-map field-name="productId" from-field="parameters.productId"/> - <field-map field-name="fromDate" from-field="parameters.fromDate"/> - <field-map field-name="workEffortGoodStdTypeId" value="PRUNT_PROD_NEEDED"/> - </entity-one> - <set from-field="workEffortGoodStandard.productId" field="productId"/> - <if-empty field="parameters.quantity"> - <set from-field="workEffortGoodStandard.estimatedQuantity" field="estimatedQuantity"/> - <else> - <set from-field="parameters.quantity" field="estimatedQuantity" default-value="0.0" type="BigDecimal"/> - </else> - </if-empty> - <!-- If no product found in the workEffortGoodStandard then create the entry in workEffortGoodStandard--> - <if-empty field="productId"> - <set field="createWorkEffortGoodStdMap.workEffortId" from-field="parameters.workEffortId" /> - <set field="createWorkEffortGoodStdMap.productId" from-field="parameters.productId"/> - <set field="createWorkEffortGoodStdMap.workEffortGoodStdTypeId" value="PRUNT_PROD_NEEDED"/> - <set field="createWorkEffortGoodStdMap.fromDate" from-field="parameters.fromDate" /> - <set field="createWorkEffortGoodStdMap.estimatedQuantity" from-field="parameters.quantity"/> - <set field="createWorkEffortGoodStdMap.statusId" value="WEGS_CREATED"/> - <call-service service-name="createWorkEffortGoodStandard" in-map-name="createWorkEffortGoodStdMap"/> - <!-- if the task is in completed status we want to make WEIA for the added product as well --> - <if-compare value="workEffort.currentStatusId" operator="equals" field="PRUN_COMPLETED"> - <set field="productId" from-field="parameters.productId"/> - </if-compare> - </if-empty> - </else> - </if-empty> - - <!-- kind of like the inventory reservation routine, find InventoryItems to issue from, but instead of doing the reservation just create an issuance and an inventory item detail for the change --> - <if-not-empty field="productId"> - <now-timestamp field="nowTimestamp"/> - - <!-- before we do the find, put together the orderBy list based on which reserveOrderEnumId is specified --> - <if-compare value="INVRO_FIFO_EXP" operator="equals" field="parameters.reserveOrderEnumId"> - <set value="+expireDate" field="orderByString"/> - <else> - <if-compare value="INVRO_LIFO_EXP" operator="equals" field="parameters.reserveOrderEnumId"> - <set value="-expireDate" field="orderByString"/> - <else> - <if-compare value="INVRO_LIFO_REC" operator="equals" field="parameters.reserveOrderEnumId"> - <set value="-datetimeReceived" field="orderByString"/> - <else> - <!-- the default reserveOrderEnumId is INVRO_FIFO_REC, ie FIFO based on date received --> - <set value="+datetimeReceived" field="orderByString"/> - <set value="INVRO_FIFO_REC" field="parameters.reserveOrderEnumId"/> - </else> - </if-compare> - </else> - </if-compare> - </else> - </if-compare> - <field-to-list field="orderByString" list="orderByList"/> - <set from-field="productId" field="lookupFieldMap.productId"/> - <set from-field="workEffort.facilityId" field="lookupFieldMap.facilityId"/> - - <!-- if lotId is passed, failIfItemsAreNotAvailable is set to automatically set to "Y" --> - <if-not-empty field="parameters.lotId"> - <set field="parameters.failIfItemsAreNotAvailable" value="Y"/> - <set field="lookupFieldMap.lotId" from-field="parameters.lotId"/> - </if-not-empty> - - <!-- if locationSeqId is passed, then only the inventory items in the location are considered --> - <if-not-empty field="parameters.locationSeqId"> - <set from-field="parameters.locationSeqId" field="lookupFieldMap.locationSeqId"/> - </if-not-empty> - <find-by-and entity-name="InventoryItem" map="lookupFieldMap" list="primaryInventoryItemList" order-by-list="orderByList"/> - <set from-field="primaryInventoryItemList" field="inventoryItemList"/> - <!-- if secondaryLocationSeqId is also passed, then also the inventory items in the secondary location are considered, after the ones in the main location --> - <if-not-empty field="parameters.locationSeqId"> - <if-not-empty field="parameters.secondaryLocationSeqId"> - <set from-field="parameters.secondaryLocationSeqId" field="lookupFieldMap.locationSeqId"/> - <find-by-and entity-name="InventoryItem" map="lookupFieldMap" list="secondaryInventoryItemList" order-by-list="orderByList"/> - <list-to-list list="secondaryInventoryItemList" to-list="inventoryItemList"/> - </if-not-empty> - </if-not-empty> - - <set from-field="estimatedQuantity" field="parameters.quantityNotIssued"/> - - <set field="parameters.useReservedItems" value="N"/> - <iterate list="inventoryItemList" entry="inventoryItem"> - <!-- this is a little trick to get the InventoryItem value object without doing a query, possible since all fields on InventoryItem are also on InventoryItemAndLocation with the same names --> - <call-simple-method method-name="issueProductionRunTaskComponentInline"/> - </iterate> - - <if> - <condition> - <and> - <if-compare field="parameters.failIfItemsAreNotAvailable" operator="not-equals" value="Y" type="String"/> - <if-compare field="parameters.quantityNotIssued" operator="greater" value="0" type="BigDecimal"/> - </and> - </condition> - <then> - <set field="parameters.useReservedItems" value="Y"/> - <iterate list="inventoryItemList" entry="inventoryItem"> - <if-compare field="parameters.quantityNotIssued" operator="greater" value="0" type="BigDecimal"> - <refresh-value value-field="inventoryItem"/> - <!-- this is a little trick to get the InventoryItem value object without doing a query, possible since all fields on InventoryItem are also on InventoryItemAndLocation with the same names --> - <call-simple-method method-name="issueProductionRunTaskComponentInline"/> - </if-compare> - </iterate> - </then> - </if> - - <!-- if quantityNotIssued is not 0, then pull it from the last non-serialized inventory item found, in the quantityNotIssued field --> - <if-compare field="parameters.quantityNotIssued" operator="not-equals" value="0" type="BigDecimal"> - <if> - <condition> - <or> - <if-compare field="parameters.failIfItemsAreNotAvailable" operator="equals" value="Y" type="String"/> - <if-empty field="parameters.failIfItemsAreNotOnHand"/> - </or> - </condition> - <then> - <add-error> - <fail-property resource="ManufacturingUiLabels" property="ManufacturingMaterialsNotAvailable"/> - </add-error> - </then> - </if> - <check-errors/> - <if-not-empty field="lastNonSerInventoryItem"> - <!-- create ItemIssuance record --> - <set from-field="parameters.workEffortId" field="issuanceCreateMap.workEffortId"/> - <set from-field="lastNonSerInventoryItem.inventoryItemId" field="issuanceCreateMap.inventoryItemId"/> - <set from-field="parameters.quantityNotIssued" field="issuanceCreateMap.quantity"/> - <call-service service-name="assignInventoryToWorkEffort" in-map-name="issuanceCreateMap"> - </call-service> - - <!-- subtract from quantityNotIssued from the availableToPromise and quantityOnHand of existing inventory item --> - <!-- instead of updating InventoryItem, add an InventoryItemDetail --> - <set from-field="lastNonSerInventoryItem.inventoryItemId" field="createDetailMap.inventoryItemId"/> - <set from-field="parameters.workEffortId" field="createDetailMap.workEffortId"/> - <calculate field="createDetailMap.availableToPromiseDiff"> - <calcop operator="negative" field="parameters.quantityNotIssued"/> - </calculate> - <calculate field="createDetailMap.quantityOnHandDiff"> - <calcop operator="negative" field="parameters.quantityNotIssued"/> - </calculate> - <set field="createDetailMap.reasonEnumId" from-field="parameters.reasonEnumId"/> - <set field="createDetailMap.description" from-field="parameters.description"/> - <call-service service-name="createInventoryItemDetail" in-map-name="createDetailMap"/> - <clear-field field="createDetailMap"/> - <set field="balanceInventoryItemsInMap.inventoryItemId" from-field="lastNonSerInventoryItem.inventoryItemId"/> - <call-service service-name="balanceInventoryItems" in-map-name="balanceInventoryItemsInMap"/> - <else> - <!-- no non-ser inv item, create a non-ser InventoryItem with availableToPromise = -quantityNotIssued --> - <clear-field field="createInvItemInMap"/> - <clear-field field="createInvItemOutMap"/> - <set field="createInvItemInMap.productId" from-field="productId"/> - <set field="createInvItemInMap.facilityId" from-field="workEffort.facilityId"/> - <set field="createInvItemInMap.inventoryItemTypeId" value="NON_SERIAL_INV_ITEM"/> - <call-service service-name="createInventoryItem" in-map-name="createInvItemInMap"> - <result-to-field result-name="inventoryItemId" field="createInvItemOutMap.inventoryItemId"/> - </call-service> - - <!-- create ItemIssuance record --> - <set field="issuanceCreateMap.workEffortId" from-field="parameters.workEffortId"/> - <set field="issuanceCreateMap.inventoryItemId" from-field="createInvItemOutMap.inventoryItemId"/> - <set field="issuanceCreateMap.quantity" from-field="parameters.quantityNotIssued"/> - <call-service service-name="assignInventoryToWorkEffort" in-map-name="issuanceCreateMap"> - </call-service> - - <!-- also create a detail record with the quantities --> - <set field="createDetailMap.inventoryItemId" from-field="createInvItemOutMap.inventoryItemId"/> - <set field="createDetailMap.workEffortId" from-field="parameters.workEffortId"/> - <calculate field="createDetailMap.availableToPromiseDiff"> - <calcop operator="negative" field="parameters.quantityNotIssued"/> - </calculate> - <calculate field="createDetailMap.quantityOnHandDiff"> - <calcop operator="negative" field="parameters.quantityNotIssued"/> - </calculate> - <set field="createDetailMap.reasonEnumId" from-field="parameters.reasonEnumId"/> - <set field="createDetailMap.description" from-field="parameters.description"/> - <call-service service-name="createInventoryItemDetail" in-map-name="createDetailMap"/> - <clear-field field="createDetailMap"/> - </else> - </if-not-empty> - <calculate field="parameters.quantityNotIssued" ><number value="0"/></calculate> - </if-compare> - <if-not-empty field="workEffortGoodStandard"> - <entity-and entity-name="WorkEffortAndInventoryAssign" list="issuances"> - <field-map field-name="workEffortId" from-field="workEffortGoodStandard.workEffortId"/> - <field-map field-name="productId" from-field="workEffortGoodStandard.productId"/> - </entity-and> - <iterate list="issuances" entry="issuance"> - <calculate field="totalIssuance"> - <calcop operator="add"> - <calcop operator="get" field="issuance.quantity"/> - <calcop operator="get" field="totalIssuance"/> - </calcop> - </calculate> - </iterate> - <if-compare-field field="workEffortGoodStandard.estimatedQuantity" to-field="totalIssuance" operator="less-equals" type="BigDecimal"> - <set value="WEGS_COMPLETED" field="workEffortGoodStandard.statusId"/> - <store-value value-field="workEffortGoodStandard"/> - </if-compare-field> - </if-not-empty> - </if-not-empty> - </simple-method> - <simple-method method-name="issueProductionRunTaskComponentInline" short-description="Does a issuance for one InventoryItem, meant to be called in-line"> - <!-- only do something with this inventoryItem if there is more inventory to issue --> - <if-compare field="parameters.quantityNotIssued" operator="greater" value="0" type="BigDecimal"> - <if-compare value="SERIALIZED_INV_ITEM" operator="equals" field="inventoryItem.inventoryItemTypeId"> - <if-compare value="INV_AVAILABLE" operator="equals" field="inventoryItem.statusId"> - <!-- change status on inventoryItem --> - <set value="INV_DELIVERED" field="inventoryItem.statusId"/> - <store-value value-field="inventoryItem"/> - - <!-- create ItemIssuance record --> - <set from-field="parameters.workEffortId" field="issuanceCreateMap.workEffortId"/> - <set from-field="inventoryItem.inventoryItemId" field="issuanceCreateMap.inventoryItemId"/> - <calculate field="issuanceCreateMap.quantity" ><number value="1"/></calculate> - <call-service service-name="assignInventoryToWorkEffort" in-map-name="issuanceCreateMap"/> - <clear-field field="issuanceCreateMap"/> - - <calculate field="parameters.quantityNotIssued"> - <calcop operator="subtract" field="parameters.quantityNotIssued"><number value="1.0"/></calcop> - </calculate> - </if-compare> - </if-compare> - <if> - <condition> - <and> - <or> - <if-empty field="inventoryItem.statusId"/> - <if-compare field="inventoryItem.statusId" operator="equals" value="INV_AVAILABLE"/> - </or> - <if-compare field="inventoryItem.inventoryItemTypeId" operator="equals" value="NON_SERIAL_INV_ITEM"/> - </and> - </condition> - <then> - <if-compare field="parameters.useReservedItems" operator="equals" value="Y"> - <set field="inventoryItemQuantity" from-field="inventoryItem.quantityOnHandTotal"/> - <else> - <set field="inventoryItemQuantity" from-field="inventoryItem.availableToPromiseTotal"/> - </else> - </if-compare> - - <if-not-empty field="inventoryItemQuantity"> - <!-- reduce atp on inventoryItem if availableToPromise greater than 0, if not the code at the end of this method will handle it --> - <if-compare field="inventoryItemQuantity" operator="greater" value="0" type="BigDecimal"> - <if-compare-field field="parameters.quantityNotIssued" to-field="inventoryItemQuantity" operator="greater" type="BigDecimal"> - <set from-field="inventoryItemQuantity" field="parameters.deductAmount"/> - <else> - <set from-field="parameters.quantityNotIssued" field="parameters.deductAmount"/> - </else> - </if-compare-field> - - <!-- create WorkEffortInventoryAssign record --> - <set from-field="parameters.workEffortId" field="issuanceCreateMap.workEffortId"/> - <set from-field="inventoryItem.inventoryItemId" field="issuanceCreateMap.inventoryItemId"/> - <set from-field="parameters.deductAmount" field="issuanceCreateMap.quantity"/> - <call-service service-name="assignInventoryToWorkEffort" in-map-name="issuanceCreateMap"> - </call-service> - - <!-- instead of updating InventoryItem, add an InventoryItemDetail --> - <set from-field="inventoryItem.inventoryItemId" field="createDetailMap.inventoryItemId"/> - <set from-field="parameters.workEffortId" field="createDetailMap.workEffortId"/> - <!-- update availableToPromiseDiff AND quantityOnHandDiff since this is an issuance --> - <calculate field="createDetailMap.availableToPromiseDiff"> - <calcop operator="negative" field="parameters.deductAmount"/> - </calculate> - <calculate field="createDetailMap.quantityOnHandDiff"> - <calcop operator="negative" field="parameters.deductAmount"/> - </calculate> - <set field="createDetailMap.reasonEnumId" from-field="parameters.reasonEnumId"/> - <set field="createDetailMap.description" from-field="parameters.description"/> - <call-service service-name="createInventoryItemDetail" in-map-name="createDetailMap"/> - <clear-field field="createDetailMap"/> - - <calculate field="parameters.quantityNotIssued" > - <calcop operator="subtract" field="parameters.quantityNotIssued"> - <calcop operator="get" field="parameters.deductAmount"/> - </calcop> - </calculate> - <set field="balanceInventoryItemsInMap.inventoryItemId" from-field="inventoryItem.inventoryItemId"/> - <call-service service-name="balanceInventoryItems" in-map-name="balanceInventoryItemsInMap"/> - - <clear-field field="issuanceCreateMap"/> - </if-compare> - </if-not-empty> - - <!-- keep track of the last non-serialized inventory item for use if inventory is not sufficient for amount already issued --> - <!-- use env variable named lastNonSerInventoryItem --> - <set from-field="inventoryItem" field="lastNonSerInventoryItem"/> - </then> - </if> - </if-compare> - </simple-method> - - <simple-method method-name="issueInventoryItemToWorkEffort" short-description="Issue one InventoryItem to a WorkEffort"> - <set field="inventoryItem" from-field="parameters.inventoryItem"/> - <field-to-result field="inventoryItem.productId" result-name="finishedProductId"/> - <if-compare value="SERIALIZED_INV_ITEM" operator="equals" field="inventoryItem.inventoryItemTypeId"> - <if-compare value="INV_AVAILABLE" operator="equals" field="inventoryItem.statusId"> - <!-- change status on inventoryItem --> - <set field="inventoryItem.statusId" value="INV_DELIVERED"/> - <call-service service-name="updateInventoryItem" in-map-name="updateContext"/> - - <!-- create ItemIssuance record --> - <set field="issuanceCreateMap.workEffortId" from-field="parameters.workEffortId"/> - <set field="issuanceCreateMap.inventoryItemId" from-field="inventoryItem.inventoryItemId"/> - <calculate field="issuanceCreateMap.quantity" ><number value="1"/></calculate> - <call-service service-name="assignInventoryToWorkEffort" in-map-name="issuanceCreateMap"/> - <field-to-result field="issuanceCreateMap.quantity" result-name="quantityIssued"/> - </if-compare> - </if-compare> - <if> - <condition> - <and> - <if-compare field="inventoryItem.inventoryItemTypeId" operator="equals" value="NON_SERIAL_INV_ITEM"/> - <not><if-empty field="inventoryItem.availableToPromiseTotal"/></not> - <if-compare field="inventoryItem.availableToPromiseTotal" operator="greater" value="0" type="BigDecimal"/> - </and> - </condition> - <then> - <if> - <condition> - <or> - <if-empty field="parameters.quantity"/> - <if-compare-field field="parameters.quantity" to-field="inventoryItem.availableToPromiseTotal" operator="greater" type="BigDecimal"/> - </or> - </condition> - <then> - <set from-field="inventoryItem.availableToPromiseTotal" field="deductAmount"/> - </then> - <else> - <set from-field="parameters.quantity" field="deductAmount"/> - </else> - </if> - <!-- create WorkEffortInventoryAssign record --> - <set from-field="parameters.workEffortId" field="issuanceCreateMap.workEffortId"/> - <set from-field="inventoryItem.inventoryItemId" field="issuanceCreateMap.inventoryItemId"/> - <set from-field="deductAmount" field="issuanceCreateMap.quantity"/> - <call-service service-name="assignInventoryToWorkEffort" in-map-name="issuanceCreateMap"> - </call-service> - - <!-- instead of updating InventoryItem, add an InventoryItemDetail --> - <set from-field="inventoryItem.inventoryItemId" field="createDetailMap.inventoryItemId"/> - <set from-field="parameters.workEffortId" field="createDetailMap.workEffortId"/> - <!-- update availableToPromiseDiff AND quantityOnHandDiff since this is an issuance --> - <calculate field="createDetailMap.availableToPromiseDiff"> - <calcop operator="negative" field="deductAmount"/> - </calculate> - <calculate field="createDetailMap.quantityOnHandDiff"> - <calcop operator="negative" field="deductAmount"/> - </calculate> - <call-service service-name="createInventoryItemDetail" in-map-name="createDetailMap"/> - <field-to-result field="deductAmount" result-name="quantityIssued"/> - </then> - <else> - <calculate field="deductAmount"><number value="0"/></calculate> - <field-to-result field="deductAmount" result-name="quantityIssued"/> - </else> - </if> - </simple-method> - -</simple-methods> - diff --git a/applications/manufacturing/servicedef/services_production_run.xml b/applications/manufacturing/servicedef/services_production_run.xml index 3526091..b4d8c3b 100644 --- a/applications/manufacturing/servicedef/services_production_run.xml +++ b/applications/manufacturing/servicedef/services_production_run.xml @@ -38,8 +38,8 @@ under the License. <attribute name="productionRunId" type="String" mode="OUT" optional="false"/> <attribute name="estimatedCompletionDate" type="java.sql.Timestamp" mode="OUT" optional="true"/> </service> - <service name="createProductionRunPartyAssign" engine="simple" - location="component://manufacturing/minilang/jobshopmgt/ProductionRunServices.xml" invoke="createProductionRunPartyAssign" auth="false"> + <service name="createProductionRunPartyAssign" engine="groovy" + location="component://manufacturing/groovyScripts/jobshopmgt/ProductionRunServices.groovy" invoke="createProductionRunPartyAssign" auth="false"> <description> Associate a party to the production run </description> @@ -50,8 +50,8 @@ under the License. <attribute name="fromDate" type="java.sql.Timestamp" mode="INOUT" optional="true"/> <attribute name="thruDate" type="Timestamp" mode="IN" optional="true"/> </service> - <service name="createProductionRunAssoc" engine="simple" - location="component://manufacturing/minilang/jobshopmgt/ProductionRunServices.xml" invoke="createProductionRunAssoc" auth="false"> + <service name="createProductionRunAssoc" engine="groovy" + location="component://manufacturing/groovyScripts/jobshopmgt/ProductionRunServices.groovy" invoke="createProductionRunAssoc" auth="false"> <description> Associate the production run to another production run </description> @@ -193,8 +193,8 @@ under the License. <attribute name="productionRunId" type="String" mode="IN" optional="false"/> <attribute name="productId" type="String" mode="IN" optional="false"/> </service> - <service name="issueProductionRunTask" engine="simple" - location="component://manufacturing/minilang/jobshopmgt/ProductionRunServices.xml" invoke="issueProductionRunTask" auth="false"> + <service name="issueProductionRunTask" engine="groovy" + location="component://manufacturing/groovyScripts/jobshopmgt/ProductionRunServices.groovy" invoke="issueProductionRunTask" auth="false"> <description> Issues the Inventory for a Production Run Task. Note that this skips the normal inventory reservation process. @@ -204,8 +204,8 @@ under the License. <attribute name="failIfItemsAreNotAvailable" type="String" mode="IN" optional="true"/> <attribute name="failIfItemsAreNotOnHand" type="String" mode="IN" optional="true"/> </service> - <service name="issueProductionRunTaskComponent" engine="simple" - location="component://manufacturing/minilang/jobshopmgt/ProductionRunServices.xml" invoke="issueProductionRunTaskComponent" auth="false"> + <service name="issueProductionRunTaskComponent" engine="groovy" + location="component://manufacturing/groovyScripts/jobshopmgt/ProductionRunServices.groovy" invoke="issueProductionRunTaskComponent" auth="false"> <description> Issues the Inventory for a Production Run Task Component. For more info see the issueProductionRunTask service. If fromDate is passed, then the WorkEffortGoodStandard record with pk composed of (workEffortId|productId|fromDate) @@ -231,8 +231,8 @@ under the License. <attribute name="reasonEnumId" type="String" mode="IN" optional="true"/> <attribute name="description" type="String" mode="IN" optional="true"/> </service> - <service name="issueInventoryItemToWorkEffort" engine="simple" - location="component://manufacturing/minilang/jobshopmgt/ProductionRunServices.xml" invoke="issueInventoryItemToWorkEffort" auth="false"> + <service name="issueInventoryItemToWorkEffort" engine="groovy" + location="component://manufacturing/groovyScripts/jobshopmgt/ProductionRunServices.groovy" invoke="issueInventoryItemToWorkEffort" auth="false"> <description> Issue one InventoryItem (or part of it) to a WorkEffort. Note that this skips the normal inventory reservation process. |
Free forum by Nabble | Edit this page |