blob: c7e2ca68d8bd364f1d44354520f600416167d791 [file] [log] [blame]
<?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="issueImmediatelyFulfilledOrder" short-description="Issues the Inventory for an Order that was Immediately Fulfilled" login-required="false">
<entity-one entity-name="OrderHeader" value-field="orderHeader"/>
<entity-one entity-name="ProductStore" value-field="productStore">
<field-map field-name="productStoreId" from-field="orderHeader.productStoreId"/>
</entity-one>
<if-not-empty field="orderHeader">
<if-compare field="orderHeader.needsInventoryIssuance" operator="equals" value="Y">
<get-related list="orderItemList" relation-name="OrderItem" value-field="orderHeader"/>
<!-- before issuing inventory, check to see if there is inventory information in this database -->
<!-- if inventory info is not available for all of the products, then don't do the issuance,
ie there has to be at least SOME inventory info in the database to facilitate inventory-less cases -->
<entity-count entity-name="InventoryItem" count-field="iiCount">
<condition-expr field-name="facilityId" operator="equals" from-field="orderHeader.originFacilityId"/>
</entity-count>
<!-- now go through each order item and call a service to issue the inventory -->
<if-compare field="iiCount" operator="greater" value="0" type="BigDecimal">
<iterate list="orderItemList" entry="orderItem">
<if-not-empty field="orderItem.productId">
<clear-field field="callSvcMap"/>
<set-service-fields service-name="issueImmediatelyFulfilledOrderItem" map="orderItem" to-map="callSvcMap"/>
<set field="callSvcMap.orderHeader" from-field="orderHeader"/>
<set field="callSvcMap.orderItem" from-field="orderItem"/>
<set field="callSvcMap.productStore" from-field="productStore"/>
<call-service service-name="issueImmediatelyFulfilledOrderItem" in-map-name="callSvcMap"/>
</if-not-empty>
</iterate>
<!-- now that the issuance is done, set the needsInventoryIssuance=N -->
<set field="orderHeader.needsInventoryIssuance" value="N"/>
<store-value value-field="orderHeader"/>
<log level="info" message="Issued inventory for orderId ${orderHeader.orderId}."/>
<else>
<log level="info" message="Not issuing inventory for orderId ${orderHeader.orderId}, no inventory information available."/>
</else>
</if-compare>
</if-compare>
</if-not-empty>
</simple-method>
<simple-method method-name="issueImmediatelyFulfilledOrderItem" short-description="Issues the Inventory for an Order Item that was Immediately Fulfilled" login-required="false">
<if-empty field="parameters.orderItem">
<entity-one entity-name="OrderItem" value-field="orderItem"/>
<else>
<set field="orderItem" from-field="parameters.orderItem"/>
</else>
</if-empty>
<!-- kind of like the inventory reservation routine (with a few variations...), 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="orderItem.productId">
<now-timestamp field="nowTimestamp"/>
<!-- NOTE: the inventory will be issued from the OrderHeader.originFacilityId -->
<if-empty field="parameters.orderHeader">
<entity-one entity-name="OrderHeader" value-field="orderHeader"/>
<else>
<set field="orderHeader" from-field="parameters.orderHeader"/>
</else>
</if-empty>
<!-- get the ProductStore to fund the reserveOrderEnumId -->
<if-empty field="parameters.productStore">
<entity-one entity-name="ProductStore" value-field="productStore">
<field-map field-name="productStoreId" from-field="orderHeader.productStoreId"/>
</entity-one>
<else>
<set field="productStore" from-field="parameters.productStore"/>
</else>
</if-empty>
<!-- 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="productStore.reserveOrderEnumId">
<set field="orderByString" value="+expireDate"/>
<else>
<if-compare value="INVRO_LIFO_EXP" operator="equals" field="productStore.reserveOrderEnumId">
<set field="orderByString" value="-expireDate"/>
<else>
<if-compare value="INVRO_LIFO_REC" operator="equals" field="productStore.reserveOrderEnumId">
<set field="orderByString" value="-datetimeReceived"/>
<else>
<!-- the default reserveOrderEnumId is INVRO_FIFO_REC, ie FIFO based on date received -->
<set field="orderByString" value="+datetimeReceived"/>
</else>
</if-compare>
</else>
</if-compare>
</else>
</if-compare>
<field-to-list field="orderByString" list="orderByList"/>
<set field="lookupFieldMap.productId" from-field="orderItem.productId"/>
<set field="lookupFieldMap.facilityId" from-field="orderHeader.originFacilityId"/>
<find-by-and entity-name="InventoryItem" map="lookupFieldMap" list="inventoryItemList" order-by-list="orderByList"/>
<set field="parameters.quantityNotIssued" from-field="orderItem.quantity"/>
<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="issueImmediateForInventoryItemInline"/>
</iterate>
<!-- 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-not-empty field="lastNonSerInventoryItem">
<!-- create ItemIssuance record -->
<set field="issuanceCreateMap.orderId" from-field="parameters.orderId"/>
<set field="issuanceCreateMap.orderItemSeqId" from-field="parameters.orderItemSeqId"/>
<set field="issuanceCreateMap.inventoryItemId" from-field="lastNonSerInventoryItem.inventoryItemId"/>
<set field="issuanceCreateMap.quantity" from-field="parameters.quantityNotIssued"/>
<call-service service-name="createItemIssuance" in-map-name="issuanceCreateMap">
<result-to-field result-name="itemIssuanceId"/>
</call-service>
<!-- subtract from quantityNotIssued from the availableToPromise and quantityOnHand of existing inventory item -->
<!-- instead of updating InventoryItem, add an InventoryItemDetail -->
<set field="createDetailMap.inventoryItemId" from-field="lastNonSerInventoryItem.inventoryItemId"/>
<set field="createDetailMap.orderId" from-field="parameters.orderId"/>
<set field="createDetailMap.orderItemSeqId" from-field="parameters.orderItemSeqId"/>
<set field="createDetailMap.itemIssuanceId" from-field="itemIssuanceId"/>
<calculate field="createDetailMap.availableToPromiseDiff" decimal-scale="6">
<calcop operator="negative" field="parameters.quantityNotIssued"/>
</calculate>
<calculate field="createDetailMap.quantityOnHandDiff" decimal-scale="6">
<calcop operator="negative" field="parameters.quantityNotIssued"/>
</calculate>
<call-service service-name="createInventoryItemDetail" in-map-name="createDetailMap"/>
<clear-field field="createDetailMap"/>
<clear-field field="itemIssuanceId"/>
<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="orderItem.productId"/>
<set field="createInvItemInMap.facilityId" from-field="orderHeader.originFacilityId"/>
<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.orderId" from-field="parameters.orderId"/>
<set field="issuanceCreateMap.orderItemSeqId" from-field="parameters.orderItemSeqId"/>
<set field="issuanceCreateMap.inventoryItemId" from-field="createInvItemOutMap.inventoryItemId"/>
<set field="issuanceCreateMap.quantity" from-field="parameters.quantityNotIssued"/>
<call-service service-name="createItemIssuance" in-map-name="issuanceCreateMap">
<result-to-field result-name="itemIssuanceId"/>
</call-service>
<!-- also create a detail record with the quantities -->
<set field="createDetailMap.inventoryItemId" from-field="createInvItemOutMap.inventoryItemId"/>
<set field="createDetailMap.orderId" from-field="parameters.orderId"/>
<set field="createDetailMap.orderItemSeqId" from-field="parameters.orderItemSeqId"/>
<set field="createDetailMap.itemIssuanceId" from-field="itemIssuanceId"/>
<calculate field="createDetailMap.availableToPromiseDiff" decimal-scale="6">
<calcop operator="negative" field="parameters.quantityNotIssued"/>
</calculate>
<calculate field="createDetailMap.quantityOnHandDiff" decimal-scale="6">
<calcop operator="negative" field="parameters.quantityNotIssued"/>
</calculate>
<call-service service-name="createInventoryItemDetail" in-map-name="createDetailMap"/>
<clear-field field="createDetailMap"/>
<clear-field field="itemIssuanceId"/>
</else>
</if-not-empty>
<calculate field="parameters.quantityNotIssued" ><number value="0"/></calculate>
</if-compare>
</if-not-empty>
</simple-method>
<simple-method method-name="issueImmediateForInventoryItemInline" 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 field="inventoryItem.statusId" value="INV_DELIVERED"/>
<set-service-fields service-name="updateInventoryItem" map="inventoryItem" to-map="inventoryItemMap"/>
<call-service service-name="updateInventoryItem" in-map-name="inventoryItemMap"/>
<!-- create ItemIssuance record -->
<set field="issuanceCreateMap.orderId" from-field="parameters.orderId"/>
<set field="issuanceCreateMap.orderItemSeqId" from-field="parameters.orderItemSeqId"/>
<set field="issuanceCreateMap.inventoryItemId" from-field="inventoryItem.inventoryItemId"/>
<calculate field="issuanceCreateMap.quantity" ><number value="1"/></calculate>
<call-service service-name="createItemIssuance" 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-compare field="inventoryItem.inventoryItemTypeId" operator="equals" value="NON_SERIAL_INV_ITEM">
<!-- reduce atp on inventoryItem if availableToPromise greater than 0, if not the code at the end of this method will handle it -->
<if>
<condition>
<and>
<or>
<if-empty field="inventoryItem.statusId"/>
<if-compare field="inventoryItem.statusId" operator="equals" value="INV_AVAILABLE"/>
</or>
<not><if-empty field="inventoryItem.availableToPromiseTotal"/></not>
<if-compare field="inventoryItem.availableToPromiseTotal" operator="greater" value="0" type="BigDecimal"/>
</and>
</condition>
<then>
<if-compare-field field="parameters.quantityNotIssued" to-field="inventoryItem.availableToPromiseTotal" operator="greater" type="BigDecimal">
<set field="parameters.deductAmount" from-field="inventoryItem.availableToPromiseTotal"/>
<else>
<set field="parameters.deductAmount" from-field="parameters.quantityNotIssued"/>
</else>
</if-compare-field>
<!-- create ItemIssuance record -->
<set field="issuanceCreateMap.orderId" from-field="parameters.orderId"/>
<set field="issuanceCreateMap.orderItemSeqId" from-field="parameters.orderItemSeqId"/>
<set field="issuanceCreateMap.inventoryItemId" from-field="inventoryItem.inventoryItemId"/>
<set field="issuanceCreateMap.quantity" from-field="parameters.deductAmount"/>
<call-service service-name="createItemIssuance" in-map-name="issuanceCreateMap">
<result-to-field result-name="itemIssuanceId"/>
</call-service>
<!-- instead of updating InventoryItem, add an InventoryItemDetail -->
<set field="createDetailMap.inventoryItemId" from-field="inventoryItem.inventoryItemId"/>
<set field="createDetailMap.orderId" from-field="parameters.orderId"/>
<set field="createDetailMap.orderItemSeqId" from-field="parameters.orderItemSeqId"/>
<set field="createDetailMap.itemIssuanceId" from-field="itemIssuanceId"/>
<!-- update availableToPromiseDiff AND quantityOnHandDiff since this is an issuance -->
<calculate field="createDetailMap.availableToPromiseDiff" decimal-scale="6">
<calcop operator="negative" field="parameters.deductAmount"/>
</calculate>
<calculate field="createDetailMap.quantityOnHandDiff" decimal-scale="6">
<calcop operator="negative" field="parameters.deductAmount"/>
</calculate>
<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>
<clear-field field="issuanceCreateMap"/>
<clear-field field="itemIssuanceId"/>
<!-- 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 field="lastNonSerInventoryItem" from-field="inventoryItem"/>
</then>
</if>
</if-compare>
</if-compare>
</simple-method>
</simple-methods>