blob: 46eb92cfde872eb44042fd31e04e798c621e6cd7 [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="createShipmentReceipt" short-description="Create a ShipmentReceipt">
<make-value value-field="newEntity" entity-name="ShipmentReceipt"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<sequenced-id sequence-name="ShipmentReceipt" field="receiptId"/>
<to-string field="receiptId"/>
<set field="newEntity.receiptId" from-field="receiptId"/>
<field-to-result field="receiptId" result-name="receiptId"/>
<if-empty field="newEntity.datetimeReceived">
<now-timestamp field="nowTimestamp"/>
<set field="newEntity.datetimeReceived" from-field="nowTimestamp"/>
</if-empty>
<set field="newEntity.receivedByUserLoginId" from-field="userLogin.userLoginId"/>
<create-value value-field="newEntity"/>
<if-not-empty field="parameters.inventoryItemDetailSeqId">
<entity-one entity-name="InventoryItemDetail" value-field="invDet">
<field-map field-name="inventoryItemDetailSeqId" from-field="parameters.inventoryItemDetailSeqId"/>
<field-map field-name="inventoryItemId" from-field="parameters.inventoryItemId"/>
</entity-one>
<set field="invDet.receiptId" from-field="receiptId"/>
<store-value value-field="invDet"/>
</if-not-empty>
<set field="affectAccounting" type="Boolean" value="true"/>
<entity-one entity-name="Product" value-field="product"/>
<if>
<condition>
<or>
<if-compare field="product.productTypeId" operator="equals" value="SERVICE_PRODUCT"/>
<if-compare field="product.productTypeId" operator="equals" value="ASSET_USAGE_OUT_IN"/>
<if-compare field="product.productTypeId" operator="equals" value="AGGREGATEDSERV_CONF"/>
</or>
</condition>
<then>
<set field="affectAccounting" type="Boolean" value="false"/>
</then>
</if>
<field-to-result field="affectAccounting" result-name="affectAccounting"/>
</simple-method>
<simple-method method-name="createShipmentReceiptRole" short-description="Create a ShipmentReceipt Role">
<make-value value-field="newEntity" entity-name="ShipmentReceiptRole"/>
<set-pk-fields map="parameters" value-field="newEntity"/>
<set-nonpk-fields map="parameters" value-field="newEntity"/>
<create-value value-field="newEntity"/>
</simple-method>
<simple-method method-name="removeShipmentReceiptRole" short-description="Remove a ShipmentReceipt Role">
<make-value value-field="lookupPKMap" entity-name="ShipmentReceiptRole"/>
<set-pk-fields map="parameters" value-field="lookupPKMap"/>
<find-by-primary-key entity-name="ShipmentReceiptRole" map="lookupPKMap" value-field="lookedUpValue"/>
<remove-value value-field="lookedUpValue"/>
</simple-method>
<simple-method method-name="receiveInventoryProduct" short-description="Receive Inventory in new Inventory Item(s)">
<!-- NOTES
- for serialized items with a serial number passed in: the quantityAccepted _should_ always be 1
- if the type is SERIALIZED_INV_ITEM but there is not serial number (which is weird...) we'll create a bunch of individual InventoryItems
- DEJ20070822: something to consider for the future: maybe instead of this funny looping maybe for serialized items we should only allow a quantity of 1, ie return an error if it is not 1
-->
<set field="loops" value="1" type="Double"/>
<if-compare value="SERIALIZED_INV_ITEM" operator="equals" field="parameters.inventoryItemTypeId">
<!-- if we are serialized and either a serialNumber or inventoyItemId is passed in and the quantityAccepted is greater than 1 then complain -->
<if>
<condition>
<and>
<or>
<not><if-empty field="parameters.serialNumber"/></not>
<not><if-empty field="parameters.currentInventoryItemId"/></not>
</or>
<if-compare field="parameters.quantityAccepted" operator="greater" value="1" type="BigDecimal"/>
</and>
</condition>
<then>
<add-error>
<fail-property resource="ProductUiLabels" property="FacilityReceiveInventoryProduct"/>
</add-error>
</then>
</if>
<set field="loops" from-field="parameters.quantityAccepted"/>
<set field="parameters.quantityAccepted" value="1" type="BigDecimal"/>
</if-compare>
<set field="parameters.quantityOnHandDiff" from-field="parameters.quantityAccepted"/>
<set field="parameters.availableToPromiseDiff" from-field="parameters.quantityAccepted"/>
<!-- before getting going, see if there are any validation issues so far -->
<check-errors/>
<!-- Status for Non serialized and Serialized inventory are different, lets make sure correct status is stored in database -->
<if-compare field="parameters.inventoryItemTypeId" operator="equals" value="NON_SERIAL_INV_ITEM">
<if-compare field="parameters.statusId" operator="equals" value="INV_DEFECTIVE"><!-- This status may come from the Receive Return Screen -->
<set field="parameters.statusId" value="INV_NS_DEFECTIVE"/>
<else>
<if-compare field="parameters.statusId" operator="equals" value="INV_ON_HOLD">
<set field="parameters.statusId" value="INV_NS_ON_HOLD"/>
<else>
<if-compare field="parameters.statusId" operator="equals" value="INV_RETURNED">
<set field="parameters.statusId" value="INV_NS_RETURNED"/>
</if-compare>
</else>
</if-compare>
</else>
</if-compare>
<!-- Any other status should be just set to null, if it is not a valid status for Non Serialized inventory -->
<if>
<condition>
<and>
<not><if-compare field="parameters.statusId" operator="equals" value="INV_NS_DEFECTIVE"/></not>
<not><if-compare field="parameters.statusId" operator="equals" value="INV_NS_ON_HOLD"/></not>
<not><if-compare field="parameters.statusId" operator="equals" value="INV_NS_RETURNED"/></not>
</and>
</condition>
<then>
<set field="parameters.statusId" from-field="nullField"/>
</then>
</if>
</if-compare>
<loop count="${loops}" field="currentLoop">
<log level="info" message="receiveInventoryProduct Looping and creating inventory info - ${currentLoop}"/>
<!-- if there is an inventoryItemId, update it (this will happen when receiving serialized inventory already in the system, like for returns); if not create one -->
<clear-field field="serviceInMap"/>
<clear-field field="currentInventoryItemId"/>
<!-- Set supplier partyId, if inventory received by purchase order -->
<if-not-empty field="parameters.orderId">
<entity-and entity-name="OrderRole" list="orderRoles">
<field-map field-name="orderId" from-field="parameters.orderId"/>
<field-map field-name="roleTypeId" value="SUPPLIER_AGENT"/>
</entity-and>
<if-not-empty field="orderRoles">
<first-from-list list="orderRoles" entry="orderRole"/>
<set field="parameters.partyId" from-field="orderRole.partyId"/>
</if-not-empty>
</if-not-empty>
<if-empty field="parameters.currentInventoryItemId">
<set-service-fields service-name="createInventoryItem" map="parameters" to-map="serviceInMap"/>
<call-service service-name="createInventoryItem" in-map-name="serviceInMap">
<result-to-field result-name="inventoryItemId" field="currentInventoryItemId"/>
</call-service>
<else>
<if-not-empty field="parameters.currentInventoryItemId">
<set field="parameters.inventoryItemId" from-field="parameters.currentInventoryItemId"/>
</if-not-empty>
<set-service-fields service-name="updateInventoryItem" map="parameters" to-map="serviceInMap"/>
<call-service service-name="updateInventoryItem" in-map-name="serviceInMap"/>
<set field="currentInventoryItemId" from-field="parameters.currentInventoryItemId"/>
</else>
</if-empty>
<!-- do this only for non-serialized inventory -->
<if-compare value="SERIALIZED_INV_ITEM" operator="not-equals" field="parameters.inventoryItemTypeId">
<clear-field field="serviceInMap"/>
<set-service-fields service-name="createInventoryItemDetail" map="parameters" to-map="serviceInMap"/>
<set field="serviceInMap.inventoryItemId" from-field="currentInventoryItemId"/>
<call-service service-name="createInventoryItemDetail" in-map-name="serviceInMap">
<result-to-field result-name="inventoryItemDetailSeqId" field="parameters.inventoryItemDetailSeqId"/>
</call-service>
</if-compare>
<clear-field field="serviceInMap"/>
<set-service-fields service-name="createShipmentReceipt" map="parameters" to-map="serviceInMap"/>
<set field="serviceInMap.inventoryItemId" from-field="currentInventoryItemId"/>
<call-service service-name="createShipmentReceipt" in-map-name="serviceInMap"/>
<!-- update serialized items to AVAILABLE (only if this is not a return), which then triggers other SECA chains -->
<if>
<condition>
<and>
<if-compare value="SERIALIZED_INV_ITEM" operator="equals" field="parameters.inventoryItemTypeId"/>
<if-empty field="parameters.returnId"/>
</and>
</condition>
<then>
<!-- Retrieve the new inventoryItem -->
<entity-one entity-name="InventoryItem" value-field="inventoryItem">
<field-map field-name="inventoryItemId" from-field="currentInventoryItemId"/>
</entity-one>
<!-- Don't reset the status if it's already set to INV_PROMISED or INV_ON_HOLD -->
<if>
<condition>
<and>
<if-compare value="INV_PROMISED" operator="not-equals" field="inventoryItem.statusId"/>
<if-compare value="INV_ON_HOLD" operator="not-equals" field="inventoryItem.statusId"/>
</and>
</condition>
<then>
<clear-field field="serviceInMap"/>
<set field="serviceInMap.inventoryItemId" from-field="currentInventoryItemId"/>
<set field="serviceInMap.statusId" value="INV_AVAILABLE"/> <!-- XXX set to returned instead -->
<call-service service-name="updateInventoryItem" in-map-name="serviceInMap"/>
</then>
</if>
</then>
</if>
<clear-field field="serviceInMap"/>
<set-service-fields service-name="balanceInventoryItems" map="parameters" to-map="serviceInMap"/>
<set field="serviceInMap.inventoryItemId" from-field="currentInventoryItemId"/>
<call-service service-name="balanceInventoryItems" in-map-name="serviceInMap"/>
<set field="successMessageList[]" value="Received ${parameters.quantityAccepted} of ${parameters.productId} in inventory item ${currentInventoryItemId}"/>
</loop>
<!-- return the last inventory item received -->
<field-to-result field="currentInventoryItemId" result-name="inventoryItemId"/>
</simple-method>
<simple-method method-name="quickReceiveReturn" short-description="Quick Receive Entire Return">
<entity-one entity-name="ReturnHeader" value-field="returnHeader">
<field-map field-name="returnId" from-field="parameters.returnId"/>
</entity-one>
<if-compare field="returnHeader.needsInventoryReceive" operator="equals" value="Y">
<!-- before receiving inventory, check to see if there is inventory information in this database -->
<entity-count entity-name="InventoryItem" count-field="iiCount">
<condition-expr field-name="facilityId" operator="equals" from-field="returnHeader.destinationFacilityId"/>
</entity-count>
<if-compare field="iiCount" operator="greater" value="0" type="Integer">
<!-- create a return shipment for this return -->
<set field="shipmentCtx.returnId" from-field="parameters.returnId"/>
<call-service service-name="createShipmentForReturn" in-map-name="shipmentCtx">
<result-to-field result-name="shipmentId"/>
</call-service>
<log level="info" message="Created new shipment ${shipmentId}"/>
<entity-condition entity-name="ReturnItem" list="returnItems">
<condition-expr field-name="returnId" operator="equals" from-field="returnHeader.returnId"/>
</entity-condition>
<!-- if no inventory item type specified, get default from facility -->
<if-empty field="parameters.inventoryItemTypeId">
<get-related-one value-field="returnHeader" relation-name="Facility" to-value-field="facility"/>
<set field="parameters.inventoryItemTypeId" from-field="facility.defaultInventoryItemTypeId" default-value="NON_SERIAL_INV_ITEM"/>
</if-empty>
<now-timestamp field="nowTimestamp"/>
<entity-count entity-name="ReturnItem" count-field="returnItemCount">
<condition-expr field-name="returnId" operator="equals" from-field="returnHeader.returnId"/>
</entity-count>
<set field="nonProductItems" type="Long" value="0"/>
<iterate list="returnItems" entry="returnItem">
<!-- record this return item on the return shipment as well. not sure if this is actually necessary... -->
<clear-field field="shipItemCtx"/>
<set from-field="shipmentId" field="shipItemCtx.shipmentId"/>
<set from-field="returnItem.productId" field="shipItemCtx.productId"/>
<set from-field="returnItem.returnQuantity" field="shipItemCtx.quantity"/>
<log level="info" message="calling create shipment item with ${shipItemCtx}"/>
<call-service service-name="createShipmentItem" in-map-name="shipItemCtx">
<result-to-field result-name="shipmentItemSeqId"/>
</call-service>
</iterate>
<iterate list="returnItems" entry="returnItem">
<clear-field field="receiveCtx"/>
<if-empty field="returnItem.expectedItemStatus">
<set value="INV_RETURNED" field="returnItem.expectedItemStatus" type="String"/>
</if-empty>
<get-related-one value-field="returnItem" relation-name="OrderItem" to-value-field="orderItem"/>
<if-not-empty field="orderItem.productId">
<set field="costCtx.returnItemSeqId" from-field="returnItem.returnItemSeqId"/>
<set field="costCtx.returnId" from-field="returnItem.returnId"/>
<call-service service-name="getReturnItemInitialCost" in-map-name="costCtx">
<result-to-field result-name="initialItemCost" field="receiveCtx.unitCost"/>
</call-service>
<!--check if the items already have SERIALIZED inventory. If so, it still puts them back as SERIALIZED with status "Accepted."-->
<entity-count entity-name="InventoryItem" count-field="serializedItemCount">
<condition-list combine="and">
<condition-expr field-name="productId" operator="equals" from-field="returnItem.productId"/>
<condition-expr field-name="facilityId" operator="equals" from-field="returnHeader.destinationFacilityId"/>
<condition-expr field-name="inventoryItemTypeId" operator="equals" value="SERIALIZED_INV_ITEM"/>
</condition-list>
</entity-count>
<set field="setNonSerial" value="false"/>
<if-compare field="parameters.inventoryItemTypeId" value="NON_SERIAL_INV_ITEM" operator="equals">
<if-compare field="serializedItemCount" value="0" operator="equals">
<set field="parameters.inventoryItemTypeId" value="NON_SERIAL_INV_ITEM"/>
<set field="setNonSerial" value="true"/>
</if-compare>
</if-compare>
<if-compare field="setNonSerial" value="false" operator="equals">
<set field="parameters.inventoryItemTypeId" value="SERIALIZED_INV_ITEM"/>
<set field="returnItem.returnQuantity" value="1" type="BigDecimal"/>
</if-compare>
<set from-field="parameters.inventoryItemTypeId" field="receiveCtx.inventoryItemTypeId"/>
<set from-field="returnItem.expectedItemStatus" field="receiveCtx.statusId"/>
<set from-field="returnItem.productId" field="receiveCtx.productId"/>
<set from-field="returnItem.returnItemSeqId" field="receiveCtx.returnItemSeqId"/>
<set from-field="returnItem.returnId" field="receiveCtx.returnId"/>
<set from-field="returnItem.returnQuantity" field="receiveCtx.quantityAccepted"/>
<set from-field="returnHeader.destinationFacilityId" field="receiveCtx.facilityId"/>
<!-- important: associate ShipmentReceipt with return shipment created -->
<set field="receiveCtx.shipmentId" from-field="shipmentId"/>
<set field="receiveCtx.comments" value="Returned Item RA# ${returnItem.returnId}"/>
<set field="receiveCtx.datetimeReceived" from-field="nowTimestamp"/>
<set field="receiveCtx.quantityRejected" value="0" type="BigDecimal"/>
<call-service service-name="receiveInventoryProduct" in-map-name="receiveCtx"/>
<else>
<calculate field="nonProductItems" type="Long">
<calcop operator="add">
<number value="1"/>
</calcop>
</calculate>
</else>
</if-not-empty>
</iterate>
<!-- now that the receive is done; set the need flag to N -->
<refresh-value value-field="returnHeader"/>
<set field="returnHeader.needsInventoryReceive" value="N"/>
<store-value value-field="returnHeader"/>
<!-- always check/update the ReturnHeader status, even though it might have been from the receiving above, just make sure -->
<if-compare field="returnHeader.statusId" operator="not-equals" value="RETURN_RECEIVED">
<set field="retStCtx.returnId" from-field="returnHeader.returnId"/>
<set field="retStCtx.statusId" value="RETURN_RECEIVED"/>
<call-service service-name="updateReturnHeader" in-map-name="retStCtx"/>
</if-compare>
<else>
<log level="info" message="Not receiving inventory for returnId ${returnHeader.returnId}, no inventory information available."/>
</else>
</if-compare>
</if-compare>
</simple-method>
<simple-method method-name="issueOrderItemToShipmentAndReceiveAgainstPO" short-description="Issues order item quantity specified to the shipment, then receives inventory for that item and quantity">
<set value="Issue OrderItem to Shipment and Receive against PO" field="operationName"/>
<call-simple-method method-name="checkCanChangeShipmentStatusPacked" xml-resource="component://product/minilang/shipment/shipment/ShipmentServices.xml"/>
<!-- get orderItem -->
<entity-one entity-name="OrderItem" value-field="orderItem" auto-field-map="true"/>
<!-- get orderItemShipGroupAssoc -->
<entity-one entity-name="OrderItemShipGroupAssoc" value-field="orderItemShipGroupAssoc" auto-field-map="true"/>
<!-- get shipment -->
<entity-one entity-name="Shipment" value-field="shipment" auto-field-map="true"/>
<!-- try to find an existing shipmentItem and attach to it, if none found create a new shipmentItem -->
<!-- if there is NO productId on the orderItem, ALWAYS create a new shipmentItem -->
<if-not-empty field="orderItem.productId">
<entity-condition entity-name="ShipmentItem" list="shipmentItems">
<condition-list combine="and">
<condition-expr field-name="productId" from-field="orderItem.productId"/>
<condition-expr field-name="shipmentId" from-field="shipment.shipmentId"/>
<condition-expr field-name="shipmentItemSeqId" from-field="parameters.shipmentItemSeqId" ignore-if-empty="true"/>
</condition-list>
<order-by field-name="shipmentItemSeqId"/>
</entity-condition>
<first-from-list list="shipmentItems" entry="shipmentItem"/>
</if-not-empty>
<if-empty field="shipmentItem">
<set from-field="orderItem.productId" field="shipmentItemCreate.productId"/>
<set from-field="parameters.shipmentId" field="shipmentItemCreate.shipmentId"/>
<set from-field="parameters.quantity" field="shipmentItemCreate.quantity"/>
<call-service service-name="createShipmentItem" in-map-name="shipmentItemCreate">
<result-to-field result-name="shipmentItemSeqId" field="shipmentItemLookupPk.shipmentItemSeqId"/>
</call-service>
<set from-field="parameters.shipmentId" field="shipmentItemLookupPk.shipmentId"/>
<find-by-primary-key entity-name="ShipmentItem" map="shipmentItemLookupPk" value-field="shipmentItem"/>
<!-- Create OrderShipment for this ShipmentItem -->
<set from-field="parameters.quantity" field="orderShipmentCreate.quantity"/>
<set from-field="shipmentItem.shipmentId" field="orderShipmentCreate.shipmentId"/>
<set from-field="shipmentItem.shipmentItemSeqId" field="orderShipmentCreate.shipmentItemSeqId"/>
<set from-field="orderItem.orderId" field="orderShipmentCreate.orderId"/>
<set from-field="orderItem.orderItemSeqId" field="orderShipmentCreate.orderItemSeqId"/>
<if-not-empty field="orderItemShipGroupAssoc">
<!-- If we have a ShipGroup Assoc for this Item to focus on, set that; this is mostly the case for purchase orders and such -->
<set from-field="orderItemShipGroupAssoc.shipGroupSeqId" field="orderShipmentCreate.shipGroupSeqId"/>
</if-not-empty>
<call-service service-name="createOrderShipment" in-map-name="orderShipmentCreate"/>
<else>
<call-simple-method method-name="getTotalIssuedQuantityForOrderItem" xml-resource="component://product/minilang/shipment/issuance/IssuanceServices.xml"/>
<call-simple-method method-name="getReceivedQuantityForOrderItem"/>
<set field="receivedQuantity" value="${receivedQuantity$bigDecimal + parameters.quantity$bigDecimal}" type="BigDecimal"/>
<entity-and entity-name="OrderShipment" list="orderShipments">
<field-map field-name="orderId" from-field="orderItem.orderId"/>
<field-map field-name="orderItemSeqId" from-field="orderItem.orderItemSeqId"/>
<field-map field-name="shipmentId" from-field="shipmentItem.shipmentId"/>
<field-map field-name="shipmentItemSeqId" from-field="shipmentItem.shipmentItemSeqId"/>
<field-map field-name="shipGroupSeqId" from-field="orderItemShipGroupAssoc.shipGroupSeqId"/>
</entity-and>
<first-from-list list="orderShipments" entry="orderShipment"/>
<if-compare-field field="totalIssuedQuantity" operator="less" to-field="receivedQuantity" type="BigDecimal">
<set field="quantityToAdd" value="${receivedQuantity$bigDecimal - totalIssuedQuantity$bigDecimal}" type="BigDecimal"/>
<set field="shipmentItem.quantity" value="${shipmentItem.quantity$bigDecimal + quantityToAdd$bigDecimal}" type="BigDecimal"/>
<store-value value-field="shipmentItem"/>
<set field="shipmentItemSeqId" from-field="shipmentItem.shipmentItemSeqId"/>
<set field="orderShipment.quantity" value="${orderShipment.quantity$bigDecimal + quantityToAdd$bigDecimal}" type="BigDecimal"/>
<store-value value-field="orderShipment"/>
</if-compare-field>
</else>
</if-empty>
<!--
TODO: if we want to record the role of the facility operation we have to re-implement this using ShipmentReceiptRole
<call-simple-method method-name="associateIssueRoles" xml-resource="component://product/minilang/shipment/issuance/IssuanceServices.xml"/>
-->
<set-service-fields service-name="receiveInventoryProduct" map="parameters" to-map="receiveInventoryProductCtx"/>
<set field="receiveInventoryProductCtx.shipmentItemSeqId" from-field="shipmentItemSeqId"/>
<call-service service-name="receiveInventoryProduct" in-map-name="receiveInventoryProductCtx">
<result-to-result result-name="inventoryItemId"/>
</call-service>
</simple-method>
<simple-method method-name="getReceivedQuantityForOrderItem" short-description="Computes the till now received quantity from all ShipmentReceipts">
<set field="receivedQuantity" type="BigDecimal" value="0"/>
<entity-and entity-name="ShipmentReceipt" list="shipmentReceipts">
<field-map field-name="orderId" from-field="orderItem.orderId"/>
<field-map field-name="orderItemSeqId" from-field="orderItem.orderItemSeqId"/>
</entity-and>
<iterate list="shipmentReceipts" entry="shipmentReceipt">
<set field="receivedQuantity" value="${receivedQuantity$bigDecimal + shipmentReceipt.quantityAccepted$bigDecimal}" type="BigDecimal"/>
</iterate>
</simple-method>
<simple-method method-name="updateIssuanceShipmentAndPoOnReceiveInventory" short-description="Update issuance, shipment and order items if quantity received is higher than quantity on purchase order">
<entity-one entity-name="OrderItem" value-field="orderItem"/>
<if-not-empty field="parameters.orderCurrencyUnitPrice">
<if-compare-field field="parameters.orderCurrencyUnitPrice" operator="not-equals" to-field="orderItem.unitPrice" type="BigDecimal">
<set field="orderItem.unitPrice" from-field="parameters.orderCurrencyUnitPrice" type="BigDecimal"/>
<store-value value-field="orderItem"/>
</if-compare-field>
<else>
<if-compare-field field="parameters.unitCost" operator="not-equals" to-field="orderItem.unitPrice" type="BigDecimal">
<set field="orderItem.unitPrice" from-field="parameters.unitCost" type="BigDecimal"/>
<store-value value-field="orderItem"/>
</if-compare-field>
</else>
</if-not-empty>
<call-simple-method method-name="getReceivedQuantityForOrderItem"/>
<if-compare-field field="orderItem.quantity" operator="less" to-field="receivedQuantity" type="BigDecimal">
<entity-and entity-name="OrderItemShipGroupAssoc" list="orderItemShipGroupAssocs">
<field-map field-name="orderId" from-field="orderItem.orderId"/>
<field-map field-name="orderItemSeqId" from-field="orderItem.orderItemSeqId"/>
</entity-and>
<calculate field="quantityVariance" type="BigDecimal" decimal-scale="2" rounding-mode="HalfUp">
<calcop operator="subtract">
<calcop operator="get" field="receivedQuantity"/>
<calcop operator="get" field="orderItem.quantity"/>
</calcop>
</calculate>
<first-from-list list="orderItemShipGroupAssocs" entry="orderItemShipGroupAssoc"/>
<calculate field="oisgaQuantity" type="BigDecimal" decimal-scale="2" rounding-mode="HalfUp">
<calcop operator="add">
<calcop operator="get" field="orderItemShipGroupAssoc.quantity"/>
<calcop operator="get" field="quantityVariance"/>
</calcop>
</calculate>
<set field="orderItemShipGroupAssoc.quantity" from-field="oisgaQuantity"/>
<set field="orderItem.quantity" from-field="receivedQuantity"/>
<store-value value-field="orderItemShipGroupAssoc"/>
<store-value value-field="orderItem"/>
</if-compare-field>
<if-not-empty field="parameters.shipmentId">
<if-not-empty field="orderItem.productId">
<call-simple-method method-name="getTotalIssuedQuantityForOrderItem" xml-resource="component://product/minilang/shipment/issuance/IssuanceServices.xml"/>
<if-compare-field field="totalIssuedQuantity" operator="less" to-field="receivedQuantity" type="BigDecimal">
<set field="quantityToAdd" value="${receivedQuantity$bigDecimal - totalIssuedQuantity$bigDecimal}" type="BigDecimal"/>
<entity-condition entity-name="ShipmentItem" list="shipmentItems">
<condition-list combine="and">
<condition-expr field-name="productId" from-field="orderItem.productId"/>
<condition-expr field-name="shipmentId" from-field="parameters.shipmentId"/>
<condition-expr field-name="shipmentItemSeqId" from-field="parameters.shipmentItemSeqId" ignore-if-empty="true"/>
</condition-list>
<order-by field-name="shipmentItemSeqId"/>
</entity-condition>
<first-from-list list="shipmentItems" entry="shipmentItem"/>
<set field="shipmentItem.quantity" value="${shipmentItem.quantity$bigDecimal + quantityToAdd$bigDecimal}" type="BigDecimal"/>
<store-value value-field="shipmentItem"/>
<entity-and entity-name="OrderShipment" list="orderShipments">
<field-map field-name="orderId" from-field="parameters.orderId"/>
<field-map field-name="orderItemSeqId" from-field="parameters.orderItemSeqId"/>
<field-map field-name="shipmentId" from-field="parameters.shipmentId"/>
<field-map field-name="shipmentItemSeqId" from-field="shipmentItem.shipmentItemSeqId"/>
</entity-and>
<first-from-list list="orderShipments" entry="orderShipment"/>
<set field="orderShipment.quantity" value="${orderShipment.quantity$bigDecimal + quantityToAdd$bigDecimal}" type="BigDecimal"/>
<store-value value-field="orderShipment"/>
<!--
TODO: if we want to record the role of the facility operation we have to re-implement this using ShipmentReceiptRole
<set field="itemIssuanceId" from-field="itemIssuance.itemIssuanceId"/>
<call-simple-method method-name="associateIssueRoles" xml-resource="component://product/minilang/shipment/issuance/IssuanceServices.xml"/>
-->
</if-compare-field>
</if-not-empty>
</if-not-empty>
</simple-method>
<simple-method method-name="cancelReceivedItems" short-description="Cancel Received Items against a purchase order if received something incorrectly">
<!-- TODO: When items are received against a Purchase Order, service listed below changes certain things in the system. Changes done by these
services also need to be reverted and missing logic can be added later.
1. addProductsBackToCategory
2. setUnitPriceAsLastPrice
3. createAcctgTransForShipmentReceipt
4. updateProductIfAvailableFromShipment
-->
<!-- update the accepted and received quantity to zero in ShipmentReceipt entity -->
<entity-one entity-name="ShipmentReceipt" value-field="shipmentReceipt"/>
<set field="shipmentReceipt.quantityAccepted" value="0" type="BigDecimal"/>
<set field="shipmentReceipt.quantityRejected" value="0" type="BigDecimal"/>
<store-value value-field="shipmentReceipt"/>
<!-- create record for InventoryItemDetail entity -->
<get-related-one value-field="shipmentReceipt" relation-name="InventoryItem" to-value-field="inventoryItem"/>
<set field="inventoryItemDetailMap.inventoryItemId" from-field="inventoryItem.inventoryItemId"/>
<calculate field="inventoryItemDetailMap.quantityOnHandDiff">
<calcop operator="multiply" field="inventoryItem.quantityOnHandTotal">
<number value="-1"/>
</calcop>
</calculate>
<calculate field="inventoryItemDetailMap.availableToPromiseDiff">
<calcop operator="multiply" field="inventoryItem.availableToPromiseTotal">
<number value="-1"/>
</calcop>
</calculate>
<call-service service-name="createInventoryItemDetail" in-map-name="inventoryItemDetailMap"/>
<!-- Balance the inventory item -->
<set field="balanceInventoryItemMap.inventoryItemId" from-field="inventoryItem.inventoryItemId"/>
<set field="balanceInventoryItemMap.priorityOrderId" from-field="shipmentReceipt.orderId"/>
<set field="balanceInventoryItemMap.priorityOrderItemSeqId" from-field="shipmentReceipt.orderItemSeqId"/>
<call-service service-name="balanceInventoryItems" in-map-name="balanceInventoryItemMap"/>
<!-- update the shipment status, if shipment was received -->
<get-related-one value-field="shipmentReceipt" relation-name="Shipment" to-value-field="shipment"/>
<if-compare field="shipment.statusId" operator="equals" value="PURCH_SHIP_RECEIVED">
<set field="shipmentStatusMap.shipmentId" from-field="shipment.shipmentId"/>
<set field="shipmentStatusMap.statusId" value="PURCH_SHIP_SHIPPED"/>
<call-service service-name="updateShipment" in-map-name="shipmentStatusMap"/>
</if-compare>
<!-- change order item and order status -->
<get-related-one value-field="shipmentReceipt" relation-name="OrderItem" to-value-field="orderItem"/>
<if-compare field="orderItem.statusId" operator="equals" value="ITEM_COMPLETED">
<!-- update the order item status -->
<set field="orderItem.statusId" value="ITEM_APPROVED"/>
<set-service-fields service-name="changeOrderItemStatus" map="orderItem" to-map="orderItemCtx"/>
<set field="orderItemCtx.fromStatusId" value="ITEM_COMPLETED"/>
<call-service service-name="changeOrderItemStatus" in-map-name="orderItemCtx"/>
<get-related-one value-field="orderItem" relation-name="OrderHeader" to-value-field="orderHeader"/>
<!-- cancel the invoice -->
<entity-and entity-name="OrderItemBilling" list="orderItemBillings">
<field-map field-name="orderId" from-field="orderItem.orderId"/>
</entity-and>
<if-not-empty field="orderItemBillings">
<first-from-list list="orderItemBillings" entry="orderItemBilling"/>
<set field="invoiceStatusMap.invoiceId" from-field="orderItemBilling.invoiceId"/>
<set field="invoiceStatusMap.statusId" value="INVOICE_CANCELLED"/>
<call-service service-name="setInvoiceStatus" in-map-name="invoiceStatusMap"/>
</if-not-empty>
</if-compare>
</simple-method>
</simple-methods>