| <?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="findOrdersToPickMove" short-description="Find Orders Ready to Pick or that need Stock Moves"> |
| <!-- filter on: |
| + OrderHeader.orderType = SALES_ORDER |
| + OrderHeader.statusId = ORDER_APPROVED |
| + OrderHeader.isRushOrder = if Y then add to rush list, still leave in other lists |
| + OrderItem.statusId = ITEM_APPROVED |
| + total number of orders to pick: limit to X |
| + ShipmentMethodType.sequenceNum = order display of methods by |
| x OrderItemShipGroup.carrierPartyId = group by along with ship method? |
| + OrderItemShipGroup.shipAfterDate is null or <= now |
| + OrderItemShipGroup.maySplit = decide to include based on whether all items available or not |
| x OrderItemShipGrpInvRes.reservedDatetime = sort by, or by order date? |
| + OrderItemShipGrpInvRes.quantityNotAvailable = if not null and not 0, and maySplit is N, exclude whole order |
| + PicklistItem = check to see if any exist, if so then already on a picklist |
| + InventoryItem.facilityId = passed facilityId |
| + FacilityLocation.locationTypeEnumId = FLT_PICKLOC, can be picked now |
| + FacilityLocation.locationTypeEnumId = FLT_BULK, stock move needed, remove whole order from list to be picked, add to list needing stock move |
| + User have options to select factors to group |
| + group by : Shipping method, Warehouse area, Number of order items (one to two, three or more) |
| --> |
| <!-- data to create - in Map in List pickMoveInfoList |
| + shipmentMethodType |
| + orderReadyToPickInfoList |
| + orderNeedsStockMoveInfoList |
| + groupName, which is based on user selected options to group |
| With each list containing a Map with: |
| + orderHeader |
| + orderItemShipGroup |
| + orderItemAndShipGroupAssocList |
| + orderItemShipGrpInvResList |
| + orderItemShipGrpInvResInfoList |
| Each entry in the orderItemShipGrpInvResInfoList is a Map with: |
| + orderItemShipGrpInvRes |
| + inventoryItem |
| + facilityLocation (may be null) |
| Also a Map called rushOrderInfo containing lists just as defined above, but containing only data for Orders where OrderHeader.isRushOrder = Y |
| + orderReadyToPickInfoList |
| + orderNeedsStockMoveInfoList |
| --> |
| |
| <set field="groupByShippingMethod" from-field="parameters.groupByShippingMethod"/> |
| <set field="groupByNoOfOrderItems" from-field="parameters.groupByNoOfOrderItems"/> |
| <set field="groupByWarehouseArea" from-field="parameters.groupByWarehouseArea"/> |
| <now-timestamp field="nowTimestamp"/> |
| <if-not-empty field="parameters.orderId"> |
| <entity-one entity-name="OrderHeader" value-field="orderHeader"/> |
| <field-to-list field="orderHeader" list="orderHeaderList"/> |
| <else> |
| <if-empty field="parameters.orderHeaderList"> |
| <log level="info" message="No order header list found in parameters; finding orders to pick."/> |
| <entity-condition entity-name="OrderHeader" list="orderHeaderList"> |
| <condition-list combine="and"> |
| <condition-expr field-name="orderTypeId" value="SALES_ORDER"/> |
| <condition-expr field-name="statusId" value="ORDER_APPROVED"/> |
| <condition-expr field-name="isRushOrder" from-field="parameters.isRushOrder" ignore-if-empty="true"/> |
| </condition-list> |
| <order-by field-name="+orderDate"/><!-- oldest first --> |
| </entity-condition> |
| <else> |
| <set from-field="parameters.orderHeaderList" field="orderHeaderList"/> |
| <log level="info" message="Found orderHeaderList in parameters; using: ${orderHeaderList}"/> |
| </else> |
| </if-empty> |
| </else> |
| </if-not-empty> |
| <set field="maxNumberOfOrders" type="Long" from-field="parameters.maxNumberOfOrders" set-if-empty="true"/> |
| <set field="numberSoFar" type="Long" value="0"/> |
| <iterate list="orderHeaderList" entry="orderHeader"> |
| <log level="info" message="Checking order #${orderHeader.orderId} to add to picklist"/> |
| <!-- get all ship groups, and iterate over them for each order --> |
| <entity-and entity-name="OrderItemShipGroup" list="orderItemShipGroupList"> |
| <field-map field-name="orderId" from-field="orderHeader.orderId"/> |
| <order-by field-name="shipGroupSeqId"/> |
| </entity-and> |
| <!-- get no. of order items for each order --> |
| <entity-count entity-name="OrderItem" count-field="orderItemCount"> |
| <condition-expr field-name="orderId" from-field="orderHeader.orderId"/> |
| </entity-count> |
| |
| <set field="groupName"/> |
| <set field="groupName1"/> <!-- Group by Shipping Method --> |
| <set field="groupName2"/> <!-- Group by Warehouse Area --> |
| <set field="groupName3"/> <!-- Group by Number of Order Items --> |
| |
| <!-- If user does not select any grouping method, then skip the grouping part. This is the default behavior of the picking screen --> |
| <if> |
| <condition> |
| <and> |
| <if-empty field="groupByShippingMethod"/> |
| <if-empty field="groupByWarehouseArea"/> |
| <if-empty field="groupByNoOfOrderItems"/> |
| </and> |
| </condition> |
| <then> |
| <set field="groupName" from-field="orderHeader.orderId"/> |
| </then> |
| <else> |
| <entity-condition entity-name="OrderHeaderAndItemFacilityLocation" list="OrderHeaderAndItemFacilityLocationList" distinct="true"> |
| <condition-list combine="and"> |
| <condition-expr field-name="orderId" from-field="orderHeader.orderId"/> |
| <condition-list combine="or"> |
| <condition-expr field-name="locationTypeEnumId" operator="equals" value="FLT_PICKLOC"/> |
| <condition-expr field-name="locationTypeEnumId" operator="equals" from-field="nullField"/> |
| </condition-list> |
| </condition-list> |
| <select-field field-name="shipmentMethodTypeId"/> |
| <select-field field-name="areaId"/> |
| <use-iterator/> |
| </entity-condition> |
| <iterate list="OrderHeaderAndItemFacilityLocationList" entry="orderHeaderAndItemFacilityLocation"> |
| <!-- set groupName for order according to the options selected by the user --> |
| |
| <if-compare field="groupByShippingMethod" operator="equals" value="Y"> |
| <set field="groupName1" from-field="orderHeaderAndItemFacilityLocation.shipmentMethodTypeId"/> |
| </if-compare> |
| |
| <if-compare field="groupByWarehouseArea" operator="equals" value="Y"> |
| <!-- If warehouse area is not setup, then just mark the group name as not-applicable (N/A) |
| This way if the user has selected group by warehouse area alone or with other options then system can still group the orders with a dummy group i.e. N/A |
| and user will still be able to see the group details by clicking on the group name which was not possible if warehouse area is not setup. |
| --> |
| <set field="groupName2" from-field="orderHeaderAndItemFacilityLocation.areaId" default-value="N/A"/> |
| <set field="locationGroupName" from-field="orderHeaderAndItemFacilityLocation.areaId"/> |
| </if-compare> |
| |
| <if> |
| <condition> |
| <and> |
| <if-compare field="groupByNoOfOrderItems" operator="equals" value="Y"/> |
| <if-compare field="orderItemCount" operator="less" value="3" type="BigDecimal"/> |
| </and> |
| </condition> |
| <then> |
| <property-to-field property="FacilityNumberOfItemsLessThanThree" field="noOfOrderItems" resource="ProductUiLabels"/> |
| <set field="groupName3" value="Items_Less_Than_3"/> |
| </then> |
| <else-if> |
| <condition> |
| <and> |
| <if-compare field="groupByNoOfOrderItems" operator="equals" value="Y"/> |
| <if-compare field="orderItemCount" operator="greater-equals" value="3" type="BigDecimal"/> |
| </and> |
| </condition> |
| <then> |
| <property-to-field property="FacilityNumberOfItemsThreeOrMore" field="noOfOrderItems" resource="ProductUiLabels"/> |
| <set field="groupName3" value="Items_Three_Or_More"/> |
| </then> |
| </else-if> |
| </if> |
| |
| <set field="groupName" value="${groupName1}${groupName2}${groupName3}"/> |
| |
| <if> |
| <condition> |
| <and> |
| <if-compare field="groupByWarehouseArea" operator="equals" value="Y"/> |
| <not><if-empty field="locationGroupName"></if-empty></not> |
| <not><if-compare-field field="locations" operator="contains" to-field="locationGroupName"/></not> |
| </and> |
| </condition> |
| <then> |
| <field-to-list field="locationGroupName" list="locations"/> |
| </then> |
| </if> |
| </iterate> |
| <!-- count no. of locations in location list --> |
| <set field="locationCount" value="0"/> |
| <if-not-empty field="locations"> |
| <set field="locationCount" value="${util:size(locations)}" type="Long"/> |
| </if-not-empty> |
| |
| <!-- If order items are picked from different locations of a facility, then create a new group called multiple locations. This order will now belong to this new group --> |
| <if-compare field="locationCount" operator="greater" value="1" type="Long"> |
| <set field="groupName2" value="MULTI_LOCATIONS"/> |
| <!-- update the composite group name with new location group name --> |
| <set field="groupName" value="${groupName1}${groupName2}${groupName3}"/> |
| <property-to-field property="FacilityMultipleLocations" field="groupName2" resource="ProductUiLabels"/> |
| </if-compare> |
| <clear-field field="locations"/> |
| <clear-field field="locationCount"/> |
| </else> |
| </if> |
| |
| <iterate list="orderItemShipGroupList" entry="orderItemShipGroup"> |
| <!-- get the order items and the order item inventory res entries --> |
| <if> |
| <condition> |
| <or> |
| <!-- only pick if now is after the shipAfterDate or the shipAfterDate is empty --> |
| <if-empty field="orderItemShipGroup.shipAfterDate"/> |
| <if-compare-field field="nowTimestamp" to-field="orderItemShipGroup.shipAfterDate" operator="greater-equals"/> |
| </or> |
| </condition> |
| <then> |
| <!-- get only for current OrderItemShipGroup --> |
| <entity-and entity-name="OrderItemShipGrpInvRes" list="orderItemShipGrpInvResList"> |
| <field-map field-name="orderId" from-field="orderItemShipGroup.orderId"/> |
| <field-map field-name="shipGroupSeqId" from-field="orderItemShipGroup.shipGroupSeqId"/> |
| </entity-and> |
| <entity-and entity-name="OrderItemAndShipGroupAssoc" list="orderItemAndShipGroupAssocList"> |
| <field-map field-name="orderId" from-field="orderItemShipGroup.orderId"/> |
| <field-map field-name="shipGroupSeqId" from-field="orderItemShipGroup.shipGroupSeqId"/> |
| <order-by field-name="+orderItemSeqId"/> |
| </entity-and> |
| |
| <!-- only add to picklist if inventory is not available (quantityNotAvailable on OISGIR greater than 0) when maySplit is N (wait until all available to ship) --> |
| <set value="Y" field="pickThisOrder"/> |
| <set value="N" field="needsStockMove"/> |
| <set value="Y" field="allPickStarted"/> |
| <set value="N" field="hasStockToPick"/> |
| <iterate list="orderItemShipGrpInvResList" entry="orderItemShipGrpInvRes"> |
| <get-related-one value-field="orderItemShipGrpInvRes" relation-name="OrderItem" to-value-field="orderItem"/> |
| <if-compare field="orderItem.statusId" value="ITEM_APPROVED" operator="not-equals"> |
| <set value="N" field="pickThisOrder"/> |
| </if-compare> |
| |
| <if-compare field="pickThisOrder" operator="equals" value="Y"> |
| <get-related-one value-field="orderItemShipGrpInvRes" relation-name="InventoryItem" to-value-field="inventoryItem"/> |
| <!-- Look for other picklists which might include this order item ship group inventory reservation. If it is on another picklist, then |
| we should not include it again. We screen out picklists which are either cancelled or already picked or packed, so that we can re-pick items if |
| (1) the previous picklist was cancelled, or |
| (2) the previous picklist was picked or packed, and there is still an OrderItemShipGrpInvRes, which means that some of the order item must not |
| have shipped yet. (OrderItemShipGrpInvRes is removed when an order item has been fully shipped. |
| We are using entity-condition instead of get-related because we want to exclude some picklists by status. |
| ** Calculate the total pick list items for this order and then subtracting it from the order item quantity |
| which is reserved while placing order results in remaining quantity of that order item which still has to be pick. --> |
| <entity-condition entity-name="PicklistAndBinAndItem" list="picklistItemList"> |
| <condition-list combine="and"> |
| <condition-expr field-name="orderId" from-field="orderItemShipGrpInvRes.orderId"/> |
| <condition-expr field-name="shipGroupSeqId" from-field="orderItemShipGrpInvRes.shipGroupSeqId"/> |
| <condition-expr field-name="orderItemSeqId" from-field="orderItemShipGrpInvRes.orderItemSeqId"/> |
| <condition-expr field-name="inventoryItemId" from-field="orderItemShipGrpInvRes.inventoryItemId"/> |
| <condition-expr field-name="statusId" operator="not-equals" value="PICKLIST_CANCELLED"/> |
| <condition-expr field-name="itemStatusId" operator="not-equals" value="PICKITEM_CANCELLED"/> |
| </condition-list> |
| </entity-condition> |
| <log level="info" message="Pick list ITEMS - ${picklistItemList}"/> |
| |
| <set field="pickedItemQuantity" value="0" type="BigDecimal"/> |
| <iterate list="picklistItemList" entry="picklistItem"> |
| <calculate field="pickedItemQuantity"> |
| <calcop operator="add" field="pickedItemQuantity"> |
| <calcop operator="get" field="picklistItem.quantity"/> |
| </calcop> |
| </calculate> |
| </iterate> |
| <calculate field="remainingQuantityToBePicked" type="BigDecimal"> |
| <calcop operator="subtract"> |
| <calcop operator="get" field="orderItemShipGrpInvRes.quantity"/> |
| <calcop operator="get" field="pickedItemQuantity"/> |
| </calcop> |
| </calculate> |
| |
| <!-- if the remaining quantity is greater than ZERO i.e. few quantity of the item is still not picked, then the |
| order will get included in the list and only that item will get included which is having some quantity to |
| pick not other items which were already picked --> |
| <if-compare field="remainingQuantityToBePicked" operator="greater" value="0" type="BigDecimal"> |
| <set field="orderItemShipGrpInvRes.quantity" from-field="remainingQuantityToBePicked"/> |
| <log level="info" message="The pick list item list is empty!"/> |
| <!-- note that this is separate because we can't really use it as a break condition, must check all of them before any useful information is to be had --> |
| <set value="N" field="allPickStarted"/> |
| |
| <if> |
| <condition> |
| <or> |
| <!-- check all OISGIRs and if quantityNotAvailable is not empty and > 0 for any, don't pick order --> |
| <and> |
| <if-compare field="orderItemShipGroup.maySplit" operator="equals" value="N"/> |
| <not><if-empty field="orderItemShipGrpInvRes.quantityNotAvailable"/></not> |
| <if-compare field="orderItemShipGrpInvRes.quantityNotAvailable" operator="greater" value="0" type="BigDecimal"/> |
| </and> |
| <!-- make sure the inventoryItem is in the specified facility --> |
| <if-compare-field field="parameters.facilityId" to-field="inventoryItem.facilityId" operator="not-equals"/> |
| </or> |
| </condition> |
| <then> |
| <set value="N" field="pickThisOrder"/> |
| </then> |
| <else> |
| <log level="info" message="Found item to pick: ${orderItemShipGrpInvRes}"/> |
| <!-- see if there is stock to pick. Items without stock (back ordered items) are not added to picklists. --> |
| <if> |
| <condition> |
| <or> |
| <if-empty field="orderItemShipGrpInvRes.quantityNotAvailable"/> |
| <if-compare field="orderItemShipGrpInvRes.quantityNotAvailable" operator="equals" value="0" type="BigDecimal"/> |
| <and> |
| <if-compare-field field="orderItemShipGrpInvRes.quantity" to-field="orderItemShipGrpInvRes.quantityNotAvailable" operator="greater" type="BigDecimal"/> |
| <if-compare field="orderItemShipGroup.maySplit" operator="equals" value="Y"/> |
| </and> |
| </or> |
| </condition> |
| <then> |
| <log level="info" message="Item has stock; flagging order (${orderItemShipGrpInvRes.orderId}) as OK"/> |
| <set value="Y" field="hasStockToPick"/> |
| </then> |
| <else> |
| <log level="info" message="Item ${orderitemShipGrpInvRes} does not have stock and will not be flagged as hasStockToPick"/> |
| </else> |
| </if> |
| |
| <!-- check InventoryItem->FacilityLocation (if exists), if it is of type FLT_BULK set needs stock move to true --> |
| <get-related-one value-field="inventoryItem" relation-name="FacilityLocation" to-value-field="facilityLocation"/> |
| <if-not-empty field="facilityLocation"> |
| <if-compare field="facilityLocation.locationTypeEnumId" operator="equals" value="FLT_BULK"> |
| <set value="Y" field="needsStockMove"/> |
| </if-compare> |
| </if-not-empty> |
| |
| <!-- make the orderItemShipGrpInvResInfo and add it to the orderItemShipGrpInvResInfoList --> |
| <set from-field="orderItemShipGrpInvRes" field="orderItemShipGrpInvResInfo.orderItemShipGrpInvRes"/> |
| <set from-field="inventoryItem" field="orderItemShipGrpInvResInfo.inventoryItem"/> |
| <set from-field="facilityLocation" field="orderItemShipGrpInvResInfo.facilityLocation"/> |
| <field-to-list field="orderItemShipGrpInvResInfo" list="orderItemShipGrpInvResInfoList"/> |
| <clear-field field="orderItemShipGrpInvResInfo"/> |
| <field-to-list field="orderItemShipGrpInvRes" list="finalOrderItemShipGrpInvResList"/> |
| </else> |
| </if> |
| </if-compare> |
| </if-compare> |
| </iterate> |
| |
| <!-- another check to see if we should pick this order --> |
| <if-compare field="hasStockToPick" operator="equals" value="N"> |
| <set value="N" field="pickThisOrder"/> |
| </if-compare> |
| |
| <if> |
| <condition> |
| <and> |
| <not><if-empty field="parameters.maxNumberOfOrders"/></not> |
| <if-compare-field field="numberSoFar" type="Long" to-field="maxNumberOfOrders" operator="greater-equals"/> |
| </and> |
| </condition> |
| <then> |
| <log level="info" message="We have passed the max number of orders!"/> |
| <set value="N" field="pickThisOrder"/> |
| </then> |
| <else> |
| <log level="info" message="We have not passed the max number of orders yet..."/> |
| </else> |
| </if> |
| |
| <if> |
| <condition> |
| <and> |
| <if-compare field="pickThisOrder" operator="equals" value="Y"/> |
| <if-compare field="allPickStarted" operator="equals" value="N"/> |
| </and> |
| </condition> |
| <then> |
| <!-- make the info map for this orderHeader --> |
| <set from-field="orderHeader" field="orderHeaderInfo.orderHeader"/> |
| <set from-field="orderItemShipGroup" field="orderHeaderInfo.orderItemShipGroup"/> |
| <set from-field="orderItemAndShipGroupAssocList" field="orderHeaderInfo.orderItemAndShipGroupAssocList"/> |
| <set from-field="finalOrderItemShipGrpInvResList" field="orderHeaderInfo.orderItemShipGrpInvResList"/> |
| <set from-field="orderItemShipGrpInvResInfoList" field="orderHeaderInfo.orderItemShipGrpInvResInfoList"/> |
| |
| <!-- pick now, or needs stock move first? --> |
| <!-- put in pick or move lists for the groupName prepared according to selected options by user --> |
| <if-empty field="pickMoveInfoMap[groupName][groupName]"> |
| <get-related-one value-field="orderItemShipGroup" relation-name="ShipmentMethodType" to-value-field="pickMoveInfoMap[groupName][groupName].shipmentMethodType"/> |
| </if-empty> |
| <if-compare field="needsStockMove" operator="equals" value="Y"> |
| <field-to-list field="orderHeaderInfo" list="pickMoveInfoMap[groupName].orderNeedsStockMoveInfoList"/> |
| <if-compare field="orderHeader.isRushOrder" operator="equals" value="Y"> |
| <field-to-list field="orderHeaderInfo" list="rushOrderInfo.orderNeedsStockMoveInfoList"/> |
| </if-compare> |
| <else> |
| <field-to-list field="orderHeaderInfo" list="pickMoveInfoMap[groupName].orderReadyToPickInfoList"/> |
| <if-compare field="orderHeader.isRushOrder" operator="equals" value="Y"> |
| <field-to-list field="orderHeaderInfo" list="rushOrderInfo.orderReadyToPickInfoList"/> |
| </if-compare> |
| </else> |
| </if-compare> |
| <clear-field field="orderHeaderInfo"/> |
| |
| <calculate field="numberSoFar" type="Long"> |
| <calcop operator="add" field="numberSoFar"><number value="1"/></calcop> |
| </calculate> |
| <log level="info" message="Added order #${orderHeader.orderId} to pick list [${numberSoFar} of ${parameters.maxNumberOfOrders}] - ${pickThisOrder} / ${allPickStarted}"/> |
| <set field="pickMoveInfoMap[groupName].groupName" from-field="groupName"/> |
| <set field="pickMoveInfoMap[groupName].groupName1" from-field="groupName1"/> |
| <set field="pickMoveInfoMap[groupName].groupName2" from-field="groupName2"/> |
| <set field="pickMoveInfoMap[groupName].groupName3" from-field="noOfOrderItems"/> |
| </then> |
| <else> |
| <log level="info" message="Order #${orderHeader.orderId} was not added to pick list [${numberSoFar} of ${parameters.maxNumberOfOrders}] - ${pickThisOrder} / ${allPickStarted}"/> |
| </else> |
| </if> |
| |
| <clear-field field="orderItemAndShipGroupAssocList"/> |
| <clear-field field="orderItemShipGrpInvResInfoList"/> |
| <clear-field field="finalOrderItemShipGrpInvResList"/> |
| </then> |
| <else> |
| <log level="info" message="Order is not a member of the requested shipment method: ${parameters.shipmentMethodTypeId}"/> |
| </else> |
| </if> |
| </iterate> |
| |
| <!-- prepare a list of group names --> |
| <if> |
| <condition> |
| <not><if-compare-field field="groupNames" operator="contains" to-field="groupName"/></not> |
| </condition> |
| <then> |
| <field-to-list field="groupName" list="groupNames"/> |
| </then> |
| </if> |
| |
| <clear-field field="orderHeaderInfo"/> |
| <clear-field field="orderItemShipGroupList"/> |
| <clear-field field="orderItemShipGrpInvResList"/> |
| <if> |
| <condition> |
| <and> |
| <not><if-empty field="maxNumberOfOrders"/></not> |
| <if-compare-field field="numberSoFar" type="Long" to-field="maxNumberOfOrders" operator="greater-equals"/> |
| </and> |
| </condition> |
| <then> |
| <break/> |
| </then> |
| </if> |
| </iterate> |
| |
| <!-- find all groupName, for each one get the value from the pickMoveInfoMap and add it to the pickMoveInfoList --> |
| <iterate list="groupNames" entry="groupName"> |
| <if-not-empty field="pickMoveInfoMap[groupName]"> |
| <field-to-list field="pickMoveInfoMap[groupName]" list="pickMoveInfoList"/> |
| </if-not-empty> |
| </iterate> |
| <clear-field field="groupNames"/> |
| <field-to-result field="pickMoveInfoList"/> |
| <field-to-result field="rushOrderInfo"/> |
| |
| </simple-method> |
| |
| <simple-method method-name="assembleOrderHeaderInfoInline" short-description="assembleOrderHeaderInfoInline"> |
| <!-- This uses pickMoveInfoList from the findOrdersToPickMove --> |
| <!-- This creates orderHeaderInfoList, wrongQuantityReservedList, insufficientQohList and inventoryItems, inventoryItemOrderItems, inventoryItemQuantities --> |
| |
| <!-- if maxNumberOfOrders is passed, get at most that many orders and go over them --> |
| <!-- moved above in findOrdersToPickMove |
| <calculate field="numberSoFar" type="Long"><number value="0"/></calculate> |
| <iterate list="pickMoveInfoList" entry="pickMoveInfo"> |
| <if> |
| <condition> |
| <or> |
| <if-empty field="parameters.maxNumberOfOrders"/> |
| <if-compare-field field="numberSoFar" to-field="parameters.maxNumberOfOrders" operator="less"></if-compare-field> |
| </or> |
| </condition> |
| <then> |
| <field-to-list field="pickMoveInfo" list="limitedPickMoveInfoList"/> |
| </then> |
| </if> |
| |
| <calculate field="numberSoFar" type="Long"> |
| <calcop operator="add" field="numberSoFar"><number value="1"/></calcop> |
| </calculate> |
| </iterate> |
| --> |
| |
| <iterate list="pickMoveInfoList" entry="pickMoveInfo"> |
| <iterate list="pickMoveInfo.orderReadyToPickInfoList" entry="orderReadyToPickInfo"> |
| <iterate list="orderReadyToPickInfo.orderItemAndShipGroupAssocList" entry="orderItemAndShipGroupAssoc"> |
| <if-compare value="ITEM_APPROVED" operator="equals" field="orderItemAndShipGroupAssoc.statusId"> |
| <calculate field="reservedQuantity"><number value="0"/></calculate> |
| |
| <set from-field="orderItemAndShipGroupAssoc.orderItemSeqId" field="itemFilterMap.orderItemSeqId"/> |
| <filter-list-by-and map="itemFilterMap" list="orderReadyToPickInfo.orderItemShipGrpInvResList" to-list="perItemResList"/> |
| <iterate list="perItemResList" entry="orderItemShipGrpInvRes"> |
| <set from-field="orderItemShipGrpInvRes.inventoryItemId" field="inventoryItemId"/> |
| <!-- update reserved quantity per inventoryItem, keep track of orderItems this came from --> |
| <set from-field="inventoryItems[inventoryItemId]" field="inventoryItem"/> |
| <if-empty field="inventoryItem"> |
| <entity-one entity-name="InventoryItem" value-field="inventoryItem"></entity-one> |
| <set field="inventoryItems[inventoryItemId]" from-field="inventoryItem"/> |
| </if-empty> |
| |
| <if-compare-field field="inventoryItem.facilityId" to-field="parameters.facilityId" operator="equals"> |
| <set field="perItemResListValid[]" from-field="orderItemShipGrpInvRes"/> |
| |
| <set field="inventoryItemOrderItemList" from-field="inventoryItemOrderItems[inventoryItemId]"/> |
| <set field="inventoryItemOrderItemList[]" from-field="orderItemAndShipGroupAssoc"/> |
| <set field="inventoryItemOrderItems[orderItemShipGrpInvRes.inventoryItemId]" from-field="inventoryItemOrderItemList"/> |
| <clear-field field="inventoryItemOrderItemList"/> |
| <if-not-empty field="inventoryItemQuantities[inventoryItemId]"> |
| <calculate field="inventoryItemQuantities[inventoryItemId]"> |
| <calcop operator="add" field="inventoryItemQuantities[inventoryItemId]"> |
| <calcop operator="get" field="orderItemShipGrpInvRes.quantity"/> |
| </calcop> |
| </calculate> |
| <else> |
| <set from-field="orderItemShipGrpInvRes.quantity" field="inventoryItemQuantities[inventoryItemId]"/> |
| </else> |
| </if-not-empty> |
| </if-compare-field> |
| <clear-field field="inventoryItem"/> |
| <!-- update total quantity reserved, picked, etc per line item to check to see if all and not more is reserved --> |
| <calculate field="reservedQuantity"> |
| <calcop operator="add" field="reservedQuantity"> |
| <calcop operator="get" field="orderItemShipGrpInvRes.quantity"/> |
| </calcop> |
| </calculate> |
| </iterate> |
| |
| <if-not-empty field="perItemResListValid"> |
| <clear-field field="orderItemInfo"/> |
| <set field="orderItemInfo.orderItemAndShipGroupAssoc" from-field="orderItemAndShipGroupAssoc"/> |
| <set field="orderItemInfo.orderItemShipGrpInvResList" from-field="perItemResListValid"/> |
| <get-related-one value-field="orderItemAndShipGroupAssoc" relation-name="Product" to-value-field="orderItemInfo.product" use-cache="true"/> |
| <set field="orderItemInfoList[]" from-field="orderItemInfo"/> |
| </if-not-empty> |
| <clear-field field="perItemResListValid"/> |
| |
| <!-- warn if wrong inventory has been reserved+issued --> |
| <!-- must include issued items as well, otherwise can't really do an effective check... --> |
| <get-related value-field="orderItemAndShipGroupAssoc" relation-name="ItemIssuance" list="itemIssuances"/> |
| <calculate field="issuedQuantity"><number value="0"/></calculate> |
| <iterate list="itemIssuances" entry="itemIssuance"> |
| <calculate field="issuedQuantity"> |
| <calcop operator="get" field="issuedQuantity"/> |
| <calcop operator="get" field="itemIssuance.quantity"/> |
| </calculate> |
| </iterate> |
| <calculate field="reservedIssuedQuantity"> |
| <calcop operator="get" field="reservedQuantity"/> |
| <calcop operator="get" field="issuedQuantity"/> |
| </calculate> |
| <if-compare-field field="reservedIssuedQuantity" to-field="orderItemAndShipGroupAssoc.quantity" operator="not-equals" type="BigDecimal"> |
| <set field="wrongQuantityReserved.orderItemAndShipGroupAssoc" from-field="orderItemAndShipGroupAssoc"/> |
| <set field="wrongQuantityReserved.reservedQuantity" from-field="reservedQuantity"/> |
| <set field="wrongQuantityReserved.issuedQuantity" from-field="issuedQuantity"/> |
| <set field="wrongQuantityReserved.reservedIssuedQuantity" from-field="reservedIssuedQuantity"/> |
| <set field="wrongQuantityReservedList[]" from-field="wrongQuantityReserved"/> |
| <clear-field field="wrongQuantityReserved"/> |
| </if-compare-field> |
| </if-compare> |
| </iterate> |
| |
| <!-- keep the order info for easy handling of order pack info --> |
| <if-not-empty field="orderItemInfoList"> |
| <set field="orderHeaderInfo.orderHeader" from-field="orderReadyToPickInfo.orderHeader"/> |
| <set field="orderHeaderInfo.orderItemShipGroup" from-field="orderReadyToPickInfo.orderItemShipGroup"/> |
| <set field="orderHeaderInfo.orderItemInfoList" from-field="orderItemInfoList"/> |
| <set field="orderHeaderInfoList[]" from-field="orderHeaderInfo"/> |
| </if-not-empty> |
| |
| <clear-field field="orderHeaderInfo"/> |
| <clear-field field="orderItemInfoList"/> |
| </iterate> |
| </iterate> |
| |
| |
| <!-- warn if insufficient QOH for reserved amount --> |
| <iterate-map map="inventoryItemQuantities" key="inventoryItemId" value="quantityNeeded"> |
| <set from-field="inventoryItems[inventoryItemId]" field="inventoryItem"/> |
| <if> |
| <condition> |
| <and> |
| <if-compare value="1" operator="less-equals" field="quantityNeeded" type="BigDecimal"/> |
| <or> |
| <and> |
| <if-compare value="SERIALIZED_INV_ITEM" operator="equals" field="inventoryItem.inventoryItemTypeId"/> |
| <if-compare value="1" operator="less" field="quantityNeeded" type="BigDecimal"/> |
| </and> |
| <and> |
| <if-compare value="NON_SERIAL_INV_ITEM" operator="equals" field="inventoryItem.inventoryItemTypeId"/> |
| <or> |
| <if-empty field="inventoryItem.quantityOnHandTotal"/> |
| <if-compare-field field="quantityNeeded" to-field="inventoryItem.quantityOnHandTotal" operator="greater" type="BigDecimal"/> |
| </or> |
| </and> |
| </or> |
| </and> |
| </condition> |
| <then> |
| <clear-field field="insufficientQoh"/> |
| <set from-field="inventoryItem" field="insufficientQoh.inventoryItem"/> |
| <set from-field="quantityNeeded" field="insufficientQoh.quantityNeeded"/> |
| <set from-field="insufficientQoh" field="insufficientQohList[]"/> |
| </then> |
| </if> |
| </iterate-map> |
| </simple-method> |
| |
| <!-- ========================================================= --> |
| <!-- ======= Persisted Picklist Maintenance Services ========= --> |
| <!-- ========================================================= --> |
| <simple-method method-name="createPicklistFromOrders" short-description="Create Picklist From Orders"> |
| <now-timestamp field="nowTimestamp"/> |
| |
| <set-service-fields map="parameters" service-name="findOrdersToPickMove" to-map="findOrdersToPickMoveMap"/> |
| <call-service service-name="findOrdersToPickMove" in-map-name="findOrdersToPickMoveMap"> |
| <result-to-field result-name="pickMoveInfoList"/> |
| </call-service> |
| <!-- <log level="info" message="pickMoveInfoList=${pickMoveInfoList}"/> --> |
| |
| <!-- This creates orderHeaderInfoList, wrongQuantityReservedList, insufficientQohList and inventoryItems, inventoryItemOrderItems, inventoryItemQuantities --> |
| <call-simple-method method-name="assembleOrderHeaderInfoInline"/> |
| <!-- <log level="info" message="orderHeaderInfoList=${orderHeaderInfoList}"/> --> |
| |
| <!-- if the orderHeaderInfoList is not empty, create a Picklist, then populate it --> |
| <if-not-empty field="orderHeaderInfoList"> |
| <set from-field="parameters.facilityId" field="createPicklistMap.facilityId"/> |
| <set from-field="parameters.shipmentMethodTypeId" field="createPicklistMap.shipmentMethodTypeId"/> |
| <call-service service-name="createPicklist" in-map-name="createPicklistMap"> |
| <result-to-field result-name="picklistId"/> |
| </call-service> |
| <field-to-result field="picklistId"/> |
| <log level="info" message="Created Picklist with ID ${picklistId}"/> |
| |
| <!-- iterate over the orderHeaderInfoList and create a PicklistBin for each order and a PicklistItem for each item --> |
| <calculate field="binLocationNumber" type="Long"><number value="1"/></calculate> |
| <iterate list="orderHeaderInfoList" entry="orderHeaderInfo"> |
| <clear-field field="picklistBinId"/> |
| <clear-field field="createPicklistBinMap"/> |
| <set from-field="picklistId" field="createPicklistBinMap.picklistId"/> |
| <set from-field="binLocationNumber" field="createPicklistBinMap.binLocationNumber"/> |
| <set from-field="orderHeaderInfo.orderItemShipGroup.orderId" field="createPicklistBinMap.primaryOrderId"/> |
| <set from-field="orderHeaderInfo.orderItemShipGroup.shipGroupSeqId" field="createPicklistBinMap.primaryShipGroupSeqId"/> |
| <call-service service-name="createPicklistBin" in-map-name="createPicklistBinMap"> |
| <result-to-field result-name="picklistBinId"/> |
| </call-service> |
| |
| <calculate field="binLocationNumber" type="Long"><calcop operator="add" field="binLocationNumber"/><number value="1"/></calculate> |
| <set field="itemsInBin" type="Long" value="0"/> |
| |
| <iterate list="orderHeaderInfo.orderItemInfoList" entry="orderItemInfo"> |
| <iterate list="orderItemInfo.orderItemShipGrpInvResList" entry="orderItemShipGrpInvRes"> |
| <log level="info" message="Getting pick quantity : ${orderItemShipGrpInvRes.quantity} - ${orderItemShipGrpInvRes.quantityNotAvailable}"/> |
| <set field="quantityToPick" from-field="orderItemShipGrpInvRes.quantity"/> |
| <!--If a portion of the item is not available, then reduce the quantity to pick. For example, |
| if a customer orders 15 and only 10 are in stock and quantityNotAvailable is 5, then subtract |
| the 5 from 15 so quantityToPick is 10 --> |
| <if> |
| <condition> |
| <and> |
| <not><if-empty field="orderItemShipGrpInvRes.quantityNotAvailable"/></not> |
| <if-compare field="orderItemShipGrpInvRes.quantityNotAvailable" value="0" operator="greater"/> |
| </and> |
| </condition> |
| <then> |
| <set field="quantityToSubtract" from-field="orderItemShipGrpInvRes.quantityNotAvailable"/> |
| <log level="info" message="Subtracting ${quantityToSubtract} from ${quantityToPick}"/> |
| <calculate field="quantityToPick"> |
| <calcop operator="subtract" field="quantityToPick"> |
| <calcop operator="get" field="quantityToSubtract"/> |
| </calcop> |
| </calculate> |
| </then> |
| </if> |
| |
| <log level="info" message="Order #${orderItemShipGrpInvRes.orderId} / ${orderItemShipGrpInvRes.orderItemSeqId} - ${quantityToPick}"/> |
| <if-compare field="quantityToPick" value="0" operator="greater" type="BigDecimal"> |
| <clear-field field="createPicklistItemMap"/> |
| <set from-field="picklistBinId" field="createPicklistItemMap.picklistBinId"/> |
| <set field="createPicklistItemMap.itemStatusId" value="PICKITEM_PENDING"/> |
| <set-service-fields service-name="createPicklistItem" map="orderItemShipGrpInvRes" to-map="createPicklistItemMap"/> |
| <set field="createPicklistItemMap.quantity" from-field="quantityToPick"/> |
| <call-service service-name="createPicklistItem" in-map-name="createPicklistItemMap"/> |
| <calculate field="itemsInBin"> |
| <calcop operator="add"/> |
| <number value="1"/> |
| </calculate> |
| </if-compare> |
| <clear-field field="quantityToPick"/> |
| </iterate> |
| </iterate> |
| |
| <!-- if we put nothing into this bin, delete the bin --> |
| <if-compare field="itemsInBin" value="0" operator="equals"> |
| <entity-one entity-name="PicklistBin" value-field="binToRemove"> |
| <field-map field-name="picklistBinId" from-field="picklistBinId"/> |
| </entity-one> |
| <remove-value value-field="binToRemove"/> |
| </if-compare> |
| </iterate> |
| <else> |
| <log level="info" message="Not Creating Picklist with ID, nothing to process."/> |
| <!-- return error messages saying no orders ready to pick, not creating picklist --> |
| <add-error> |
| <fail-property resource="ProductUiLabels" property="FacilityNoOrdersReadyToPick"/> |
| </add-error> |
| <check-errors/> |
| </else> |
| </if-not-empty> |
| </simple-method> |
| |
| <!-- print pick sheet --> |
| <simple-method method-name="printPickSheets" short-description="Print pick sheets for orders"> |
| <if-empty field="parameters.maxNumberOfOrdersToPrint"> |
| <add-error error-list-name="error_list"> |
| <fail-property resource="ProductErrorUiLabels" property="ProductNumberOfOrdersMustNotBeEmptyToPrintPickSheet"/> |
| </add-error> |
| <else> |
| <if-compare field="parameters.maxNumberOfOrdersToPrint" operator="less-equals" value="0" type="Long"> |
| <add-error error-list-name="error_list"> |
| <fail-property resource="ProductErrorUiLabels" property="ProductNumberOfOrdersMustBeGreaterThenZeroToPrintPickSheet"/> |
| </add-error> |
| </if-compare> |
| </else> |
| </if-empty> |
| <check-errors/> |
| |
| <now-timestamp field="nowTimestamp"/> |
| <set-service-fields service-name="findOrdersToPickMove" map="parameters" to-map="findOrdersToPickMoveMap"/> |
| <call-service service-name="findOrdersToPickMove" in-map-name="findOrdersToPickMoveMap"> |
| <result-to-field result-name="pickMoveInfoList"/> |
| </call-service> |
| |
| <if-not-empty field="parameters.printGroupName"> |
| <set field="printGroupName" from-field="parameters.printGroupName"/> |
| <iterate list="pickMoveInfoList" entry="pickMoveInfo"> |
| <set field="groupName" from-field="pickMoveInfo.groupName"/> |
| <if-compare-field field="groupName" operator="equals" to-field="printGroupName"> |
| <list-to-list list="pickMoveInfo.orderReadyToPickInfoList" to-list="toPrintList"/> |
| </if-compare-field> |
| </iterate> |
| <else> |
| <iterate list="pickMoveInfoList" entry="pickMoveInfo"> |
| <list-to-list list="pickMoveInfo.orderReadyToPickInfoList" to-list="toPrintList"/> |
| </iterate> |
| </else> |
| </if-not-empty> |
| <set field="counter" value="0" type="Long"/> |
| <iterate list="toPrintList" entry="toPrint"> |
| <if-compare-field field="counter" operator="less" to-field="parameters.maxNumberOfOrdersToPrint" type="Long"> |
| <set field="orderHeaderMap.orderId" from-field="toPrint.orderHeader.orderId"/> |
| <set field="orderHeaderMap.pickSheetPrintedDate" from-field="nowTimestamp"/> |
| <call-service service-name="updateOrderHeader" in-map-name="orderHeaderMap"/> |
| <set field="counter" value="${counter + 1}" type="Long"/> |
| <clear-field field="orderHeaderMap"/> |
| </if-compare-field> |
| </iterate> |
| <field-to-result field="pickMoveInfoList"/> |
| </simple-method> |
| |
| <!-- Picklist --> |
| <simple-method method-name="createPicklist" short-description="Create Picklist"> |
| <make-value value-field="newEntity" entity-name="Picklist"/> |
| <set-nonpk-fields map="parameters" value-field="newEntity"/> |
| |
| <sequenced-id sequence-name="Picklist" field="newEntity.picklistId"/> |
| <field-to-result field="newEntity.picklistId" result-name="picklistId"/> |
| |
| <if-empty field="newEntity.statusId"> |
| <set value="PICKLIST_INPUT" field="newEntity.statusId"/> |
| </if-empty> |
| |
| <!-- auto-set the picklistDate, this is not user-changeable --> |
| <now-timestamp field="newEntity.picklistDate"/> |
| |
| <!-- set the created and lastModified info --> |
| <set from-field="userLogin.userLoginId" field="newEntity.createdByUserLogin"/> |
| <set from-field="userLogin.userLoginId" field="newEntity.lastModifiedByUserLogin"/> |
| |
| <create-value value-field="newEntity"/> |
| </simple-method> |
| <simple-method method-name="updatePicklist" short-description="Update Picklist"> |
| <make-value value-field="lookupPKMap" entity-name="Picklist"/> |
| <set-pk-fields map="parameters" value-field="lookupPKMap"/> |
| <find-by-primary-key map="lookupPKMap" value-field="lookedUpValue"/> |
| |
| <if-not-empty field="parameters.statusId"> |
| <if-compare-field field="parameters.statusId" to-field="lookedUpValue.statusId" operator="not-equals"> |
| <!-- make sure a StatusValidChange record exists, if not return error --> |
| <entity-one entity-name="StatusValidChange" value-field="checkStatusValidChange" auto-field-map="false"> |
| <field-map field-name="statusId" from-field="lookedUpValue.statusId"/> |
| <field-map field-name="statusIdTo" from-field="parameters.statusId"/> |
| </entity-one> |
| <if-empty field="checkStatusValidChange"> |
| <set value="ERROR: Changing the status from ${lookedUpValue.statusId} to ${parameters.statusId} is not allowed." field="error_list[]"/> |
| </if-empty> |
| <check-errors/> |
| |
| <make-value entity-name="PicklistStatusHistory" value-field="newStatusValue"/> |
| <set from-field="parameters.picklistId" field="newStatusValue.picklistId"/> |
| <set from-field="lookedUpValue.statusId" field="newStatusValue.statusId"/> |
| <set from-field="parameters.statusId" field="newStatusValue.statusIdTo"/> |
| <now-timestamp field="newStatusValue.changeDate"/> |
| <set from-field="userLogin.userLoginId" field="newStatusValue.changeUserLoginId"/> |
| <create-value value-field="newStatusValue"/> |
| </if-compare-field> |
| </if-not-empty> |
| |
| <!-- now finally check for errors --> |
| <check-errors/> |
| |
| <!-- finally before setting nonpk fields, set the oldStatusId --> |
| <field-to-result field="lookedUpValue.statusId" result-name="oldStatusId"/> |
| |
| <!-- now that all changes have been checked, set the nonpks --> |
| <set-nonpk-fields map="parameters" value-field="lookedUpValue"/> |
| <set from-field="userLogin.userLoginId" field="lookedUpValue.lastModifiedByUserLogin"/> |
| |
| <store-value value-field="lookedUpValue"/> |
| </simple-method> |
| <simple-method method-name="deletePicklist" short-description="Delete Picklist"> |
| <make-value value-field="lookupPKMap" entity-name="Picklist"/> |
| <set-pk-fields map="parameters" value-field="lookupPKMap"/> |
| <find-by-primary-key map="lookupPKMap" value-field="lookedUpValue"/> |
| <remove-value value-field="lookedUpValue"/> |
| </simple-method> |
| |
| <!-- PicklistBin --> |
| <simple-method method-name="createPicklistBin" short-description="Create PicklistBin"> |
| <make-value value-field="newEntity" entity-name="PicklistBin"/> |
| <set-nonpk-fields map="parameters" value-field="newEntity"/> |
| |
| <sequenced-id sequence-name="PicklistBin" field="newEntity.picklistBinId"/> |
| <field-to-result field="newEntity.picklistBinId" result-name="picklistBinId"/> |
| |
| <create-value value-field="newEntity"/> |
| </simple-method> |
| <simple-method method-name="deletePicklistBin" short-description="Delete PicklistBin"> |
| <make-value value-field="lookupPKMap" entity-name="PicklistBin"/> |
| <set-pk-fields map="parameters" value-field="lookupPKMap"/> |
| <find-by-primary-key map="lookupPKMap" value-field="lookedUpValue"/> |
| <remove-value value-field="lookedUpValue"/> |
| </simple-method> |
| |
| <!-- PicklistItem --> |
| <simple-method method-name="createPicklistItem" short-description="Create PicklistItem"> |
| <make-value value-field="newEntity" entity-name="PicklistItem"/> |
| <set-pk-fields map="parameters" value-field="newEntity"/> |
| <set-nonpk-fields map="parameters" value-field="newEntity"/> |
| |
| <if-empty field="newEntity.itemStatusId"> |
| <set value="PICKITEM_PENDING" field="newEntity.itemStatusId"/> |
| </if-empty> |
| |
| <create-value value-field="newEntity"/> |
| </simple-method> |
| <simple-method method-name="updatePicklistItem" short-description="Update PicklistItem"> |
| <make-value value-field="lookupPKMap" entity-name="PicklistItem"/> |
| <set-pk-fields map="parameters" value-field="lookupPKMap"/> |
| <find-by-primary-key map="lookupPKMap" value-field="lookedUpValue"/> |
| |
| <if-not-empty field="parameters.itemStatusId"> |
| <if-compare-field field="parameters.itemStatusId" to-field="lookedUpValue.itemStatusId" operator="not-equals"> |
| <!-- make sure a StatusValidChange record exists, if not return error --> |
| <entity-one entity-name="StatusValidChange" value-field="checkStatusValidChange" auto-field-map="false"> |
| <field-map field-name="statusId" from-field="lookedUpValue.itemStatusId"/> |
| <field-map field-name="statusIdTo" from-field="parameters.itemStatusId"/> |
| </entity-one> |
| <if-empty field="checkStatusValidChange"> |
| <set value="ERROR: Changing the status from ${lookedUpValue.itemStatusId} to ${parameters.itemStatusId} is not allowed." field="error_list[]"/> |
| </if-empty> |
| </if-compare-field> |
| </if-not-empty> |
| |
| <!-- now finally check for errors --> |
| <check-errors/> |
| |
| <!-- finally before setting nonpk fields, set the oldItemStatusId --> |
| <field-to-result field="lookedUpValue.itemStatusId" result-name="oldItemStatusId"/> |
| |
| <!-- now that all changes have been checked, set the nonpks --> |
| <set-nonpk-fields map="parameters" value-field="lookedUpValue"/> |
| |
| <!-- store the changes --> |
| <store-value value-field="lookedUpValue"/> |
| </simple-method> |
| <simple-method method-name="deletePicklistItem" short-description="Delete PicklistItem"> |
| <make-value value-field="lookupPKMap" entity-name="PicklistItem"/> |
| <set-pk-fields map="parameters" value-field="lookupPKMap"/> |
| <find-by-primary-key map="lookupPKMap" value-field="lookedUpValue"/> |
| <remove-value value-field="lookedUpValue"/> |
| </simple-method> |
| |
| <!-- Service which edit a PicklistItem when a preparator choose a specified lot for one line order |
| This service is called by the request : |
| - editPicklistItem |
| --> |
| <simple-method method-name="editPicklistItem" short-description="Edit a Picklist Item"> |
| |
| <make-value value-field="lookupPKMap" entity-name="PicklistItem"/> |
| <set-pk-fields map="parameters" value-field="lookupPKMap"/> |
| <find-by-primary-key map="lookupPKMap" value-field="picklistItem"/> |
| |
| <!-- Error if the specified quantity is greater than the picklistItem quantity --> |
| <if-compare-field operator="greater" to-field="picklistItem.quantity" field="parameters.quantity" type="Integer"> |
| <add-error> |
| <fail-property resource="ProductErrorUiLabels" property="PicklistManageTooMuchQuantity"/> |
| </add-error> |
| </if-compare-field> |
| |
| <!-- In order to check if there is a link between the lot and the productId, |
| we retrieve all the inventoryItems with this lotId ... --> |
| <entity-condition entity-name="InventoryItem" list="inventoryItemList"> |
| <condition-expr field-name="lotId" operator="equals" from-field="parameters.lotId"/> |
| </entity-condition> |
| |
| <set value="ko" field="linkProductAndLot"/> |
| |
| <!-- ... and check if one of the inventoryItems have this productId --> |
| <iterate list="inventoryItemList" entry="inventoryItem"> |
| <if-compare-field operator="equals" to-field="inventoryItem.productId" field="parameters.productId"> |
| <set value="ok" field="linkProductAndLot"/> |
| </if-compare-field> |
| </iterate> |
| |
| <if-compare field="linkProductAndLot" operator="equals" value="ko"> |
| <add-error> |
| <fail-property resource="ProductErrorUiLabels" property="PicklistManageNoLinkProductAndLot"/> |
| </add-error> |
| </if-compare> |
| |
| <check-errors /> |
| |
| <set field="inputMap.productId" from-field="parameters.productId"/> |
| <set field="inputMap.facilityId" from-field="parameters.facilityId"/> |
| <set field="inputMap.lotId" from-field="parameters.lotId"/> |
| |
| <!-- Check the stock of this lot --> |
| <call-service service-name="getInventoryAvailableByFacility" in-map-name="inputMap"> |
| <result-to-field result-name="quantityOnHandTotal" field="quantityOnHandTotal"/> |
| <result-to-field result-name="availableToPromiseTotal" field="availableToPromiseTotal"/> |
| </call-service> |
| |
| <if> |
| <condition> |
| <if-compare-field operator="greater" field="parameters.quantity" to-field="availableToPromiseTotal" type="Integer"/> |
| </condition> |
| <then> |
| <add-error> |
| <fail-property resource="ProductErrorUiLabels" property="PicklistManageStockLow"/> |
| </add-error> |
| </then> |
| </if> |
| |
| <check-errors /> |
| |
| <!-- Retreive the informations about the OrderItemShipGrpInvRes of the edited PicklistItem --> |
| <entity-one value-field="oisgir" entity-name="OrderItemShipGrpInvRes"> |
| <field-map field-name="orderId" from-field="parameters.orderId"/> |
| <field-map field-name="shipGroupSeqId" from-field="parameters.shipGroupSeqId"/> |
| <field-map field-name="orderItemSeqId" from-field="parameters.orderItemSeqId"/> |
| <field-map field-name="inventoryItemId" from-field="parameters.inventoryItemId"/> |
| </entity-one> |
| |
| <!-- We remove the edited PicklistItem ... --> |
| <remove-value value-field="picklistItem"/> |
| |
| <!-- ... and its OrderItemShipGrpInvRes --> |
| <set-service-fields service-name="cancelOrderItemShipGrpInvRes" map="parameters" to-map="cancelOrderItemShipGrpInvResMap"/> |
| <call-service service-name="cancelOrderItemShipGrpInvRes" in-map-name="cancelOrderItemShipGrpInvResMap"/> |
| |
| <clear-field field="inputMap"/> |
| |
| <!-- We create new(s) OrderItemShipGrpInvRes with the new InventoryItem (with the specified lot) --> |
| <set from-field="parameters.orderId" field="inputMap.orderId"/> |
| <set from-field="parameters.shipGroupSeqId" field="inputMap.shipGroupSeqId"/> |
| <set from-field="parameters.orderItemSeqId" field="inputMap.orderItemSeqId"/> |
| <set from-field="parameters.productId" field="inputMap.productId"/> |
| <set from-field="parameters.quantity" field="inputMap.quantity"/> |
| <set from-field="parameters.facilityId" field="inputMap.facilityId" /> |
| <set value="Y" field="inputMap.requireInventory"/> |
| <set from-field="oisgir.reserveOrderEnumId" field="inputMap.reserveOrderEnumId"/> |
| <set from-field="parameters.lotId" field="inputMap.lotId"/> |
| |
| <call-service service-name="reserveProductInventoryByFacility" in-map-name="inputMap" /> |
| |
| <!-- If the new OrderItemShipGrpInvRes don't contains all of the item, we recreate OrderItemShipGrpInvRes |
| with the previous parameters --> |
| <if-compare-field field="parameters.quantity" operator="less" to-field="picklistItem.quantity" type="Integer"> |
| <clear-field field="inputMap"/> |
| |
| <set from-field="parameters.orderId" field="inputMap.orderId"/> |
| <set from-field="parameters.shipGroupSeqId" field="inputMap.shipGroupSeqId"/> |
| <set from-field="parameters.orderItemSeqId" field="inputMap.orderItemSeqId"/> |
| <set from-field="parameters.productId" field="inputMap.productId"/> |
| <set from-field="parameters.facilityId" field="inputMap.facilityId" /> |
| |
| <if-not-empty field="parameters.oldLotId"> |
| <set from-field="parameters.oldLotId" field="inputMap.lotId" /> |
| </if-not-empty> |
| |
| <calculate field="quantity"> |
| <calcop operator="subtract" field="picklistItem.quantity"> |
| <calcop operator="get" field="parameters.quantity"/> |
| </calcop> |
| </calculate> |
| |
| <set from-field="quantity" field="inputMap.quantity"/> |
| <set value="Y" field="inputMap.requireInventory"/> |
| <set from-field="oisgir.reserveOrderEnumId" field="inputMap.reserveOrderEnumId"/> |
| |
| <call-service service-name="reserveProductInventoryByFacility" in-map-name="inputMap"/> |
| </if-compare-field> |
| |
| <entity-condition entity-name="OrderItemShipGrpInvRes" list="oisgirs"> |
| <condition-list> |
| <condition-expr from-field="parameters.orderId" field-name="orderId" operator="equals"/> |
| <condition-expr from-field="parameters.shipGroupSeqId" field-name="shipGroupSeqId" operator="equals"/> |
| <condition-expr from-field="parameters.orderItemSeqId" field-name="orderItemSeqId" operator="equals"/> |
| </condition-list> |
| </entity-condition> |
| |
| <set from-field="picklistItem.picklistBinId" field="picklistBinId"/> |
| |
| <entity-condition entity-name="PicklistItem" list="picklistItemList"> |
| <condition-list> |
| <condition-expr from-field="parameters.orderId" field-name="orderId" operator="equals"/> |
| <condition-expr from-field="parameters.shipGroupSeqId" field-name="shipGroupSeqId" operator="equals"/> |
| <condition-expr from-field="parameters.orderItemSeqId" field-name="orderItemSeqId" operator="equals"/> |
| <condition-expr from-field="picklistBinId" field-name="picklistBinId" operator="equals" /> |
| </condition-list> |
| </entity-condition> |
| |
| <clear-field field="inputMap"/> |
| |
| <!-- We create the PicklistItem who correspond at the new(s) OrderItemShipGrpInvRes --> |
| <iterate list="oisgirs" entry="oisgir"> |
| |
| <!-- actionOnPli can have 3 values : |
| - new : the picklistItem has never existed and is created by this service |
| - edit : the picklistItem exists but we need to modify its quantity |
| - none : the picklistItem exists and this service haven't to touch at this one. --> |
| <set field="actionOnPli" value="new" /> |
| |
| <if-not-empty field="oisgir.quantityNotAvailable"> |
| <calculate field="quantity"> |
| <calcop operator="subtract" field="oisgir.quantity"> |
| <calcop operator="get" field="oisgir.quantityNotAvailable"/> |
| </calcop> |
| </calculate> |
| <else> |
| <set field="quantity" from-field="oisgir.quantity"/> |
| </else> |
| </if-not-empty> |
| |
| <iterate entry="pli" list="picklistItemList"> |
| <if-compare-field field="pli.inventoryItemId" operator="equals" to-field="oisgir.inventoryItemId"> |
| <if-compare-field field="pli.quantity" operator="equals" to-field="quantity"> |
| <set field="actionOnPli" value="none" /> |
| <else> |
| <set field="actionOnPli" value="edit" /> |
| <set field="currentPli" value="pli"/> |
| </else> |
| </if-compare-field> |
| </if-compare-field> |
| </iterate> |
| |
| <if-compare operator="equals" value="new" field="actionOnPli"> |
| |
| <set from-field="oisgir.inventoryItemId" field="inputMap.inventoryItemId" /> |
| <set from-field="oisgir.orderId" field="inputMap.orderId" /> |
| <set from-field="oisgir.orderItemSeqId" field="inputMap.orderItemSeqId" /> |
| <set from-field="picklistBinId" field="inputMap.picklistBinId" /> |
| <set from-field="quantity" field="inputMap.quantity" /> |
| <set from-field="oisgir.shipGroupSeqId" field="inputMap.shipGroupSeqId" /> |
| |
| <call-service service-name="createPicklistItem" in-map-name="inputMap" /> |
| </if-compare> |
| |
| <if-compare operator="equals" value="edit" field="actionOnPli"> |
| <set from-field="oisgir.inventoryItemId" field="inputMap.inventoryItemId" /> |
| <set from-field="oisgir.orderId" field="inputMap.orderId" /> |
| <set from-field="oisgir.orderItemSeqId" field="inputMap.orderItemSeqId" /> |
| <set from-field="picklistBinId" field="inputMap.picklistBinId" /> |
| <set from-field="quantity" field="inputMap.quantity" /> |
| <set from-field="oisgir.shipGroupSeqId" field="inputMap.shipGroupSeqId" /> |
| |
| <call-service service-name="updatePicklistItem" in-map-name="inputMap" /> |
| </if-compare> |
| </iterate> |
| |
| </simple-method> |
| |
| <simple-method method-name="setPicklistItemToComplete" short-description="Set the status of a pick list item to completed"> |
| <set-service-fields service-name="updatePicklistItem" map="parameters" to-map="serviceCtx"/> |
| <set field="serviceCtx.itemStatusId" value="PICKITEM_COMPLETED"/> |
| <call-service service-name="updatePicklistItem" in-map-name="serviceCtx" include-user-login="true"/> |
| </simple-method> |
| |
| <!-- PicklistRole --> |
| <simple-method method-name="createPicklistRole" short-description="Create PicklistRole"> |
| <make-value value-field="newEntity" entity-name="PicklistRole"/> |
| <set-pk-fields map="parameters" value-field="newEntity"/> |
| <set-nonpk-fields map="parameters" value-field="newEntity"/> |
| |
| <if-empty field="newEntity.fromDate"> |
| <now-timestamp field="newEntity.fromDate"/> |
| </if-empty> |
| |
| <create-value value-field="newEntity"/> |
| </simple-method> |
| <simple-method method-name="deletePicklistRole" short-description="Delete PicklistRole"> |
| <make-value value-field="lookupPKMap" entity-name="PicklistRole"/> |
| <set-pk-fields map="parameters" value-field="lookupPKMap"/> |
| <find-by-primary-key map="lookupPKMap" value-field="lookedUpValue"/> |
| <remove-value value-field="lookedUpValue"/> |
| </simple-method> |
| |
| <!-- ========================================================= --> |
| <!-- =========== Picklist Report/Display Services ============ --> |
| <!-- ========================================================= --> |
| <simple-method method-name="getPicklistDisplayInfo" short-description="Get Picklist Display Info"> |
| <set field="viewSize" from-field="parameters.viewSize" type="Integer"/> |
| <set field="viewIndex" from-field="parameters.viewIndex" type="Integer"/> |
| <entity-condition entity-name="Picklist" list="picklistList"> |
| <condition-list combine="and"> |
| <condition-expr field-name="facilityId" operator="equals" from-field="parameters.facilityId"/> |
| <condition-expr field-name="statusId" operator="not-equals" value="PICKLIST_PICKED"/> |
| <condition-expr field-name="statusId" operator="not-equals" value="PICKLIST_CANCELLED"/> |
| </condition-list> |
| <order-by field-name="picklistDate"/> |
| <limit-view view-size="${viewSize}" view-index="${viewIndex+1}"/> |
| </entity-condition> |
| |
| <entity-count entity-name="Picklist" count-field="picklistCount"> |
| <condition-list combine="and"> |
| <condition-expr field-name="facilityId" operator="equals" from-field="parameters.facilityId"/> |
| <condition-expr field-name="statusId" operator="not-equals" value="PICKLIST_PICKED"/> |
| <condition-expr field-name="statusId" operator="not-equals" value="PICKLIST_CANCELLED"/> |
| </condition-list> |
| </entity-count> |
| <iterate list="picklistList" entry="picklist"> |
| <call-simple-method method-name="getPicklistSingleInfoInline"/> |
| <field-to-list field="picklistInfo" list="picklistInfoList"/> |
| </iterate> |
| |
| <set field="lowIndex" value="${(viewIndex * viewSize) + 1}" type="Integer"/> |
| <set field="highIndex" value="${(viewIndex + 1) * viewSize}" type="Integer"/> |
| <if-compare-field field="highIndex" operator="greater" to-field="picklistCount" type="Integer"> |
| <set field="highIndex" from-field="picklistCount" type="Integer"/> |
| </if-compare-field> |
| <if-compare-field field="viewSize" operator="greater" to-field="picklistCount" type="Integer"> |
| <set field="highIndex" from-field="picklistCount" type="Integer"/> |
| </if-compare-field> |
| |
| <field-to-result field="picklistInfoList"/> |
| <field-to-result field="viewIndex"/> |
| <field-to-result field="viewSize"/> |
| <field-to-result field="lowIndex"/> |
| <field-to-result field="highIndex"/> |
| <field-to-result field="picklistCount"/> |
| </simple-method> |
| |
| <simple-method method-name="getPickAndPackReportInfo" short-description="getPickAndPackReportInfo"> |
| <!-- |
| Creates: |
| 1. Standard picklistInfo Map from the getPicklistSingleInfoInline simple-method (see comment there for details) |
| 2. facilityLocationInfoList (facilityLocation, product, pickQuantity, picklistBinInfoList (picklistBin, quantity), picklistItemInfoList (picklistItem, picklistBin, orderItem, product, inventoryItemAndLocation, orderItemShipGrpInvRes, itemIssuanceList)) |
| 3. noLocationProductInfoList (product, pickQuantity, picklistBinInfoList (picklistBin, quantity), picklistItemInfoList (picklistItem, picklistBin, orderItem, product, inventoryItemAndLocation, orderItemShipGrpInvRes, itemIssuanceList)) |
| --> |
| <!-- Get the general information for the picklist, this will be used for the pack sheets --> |
| <entity-one entity-name="Picklist" value-field="picklist" auto-field-map="true"/> |
| <call-simple-method method-name="getPicklistSingleInfoInline"/> |
| <field-to-result field="picklistInfo"/> |
| |
| <!-- Assemble the information per facility location for the pick sheet --> |
| <iterate list="picklistInfo.picklistBinInfoList" entry="picklistBinInfo"> |
| <set from-field="picklistBinInfo.picklistBin" field="picklistBinByIdMap[picklistBinInfo.picklistBin.picklistBinId]"/> |
| |
| <iterate list="picklistBinInfo.picklistItemInfoList" entry="picklistItemInfo"> |
| <!-- |
| In this iteration through the items we want 2 things: |
| 1. A Map with all FacilityLocation records by locationSeqId, so that we have one unique of each |
| instance per inventoryItem, this will be put into a list and sorted by facility location fields |
| AND |
| A Map containing a List of PicklistItemInfo records keyed by the locationSeqId |
| 2. A Map with key productId, value product |
| AND |
| A Map with a List of PicklistItemInfo records keyed by the productId |
| --> |
| <if-not-empty field="picklistItemInfo.inventoryItemAndLocation.locationSeqId"> |
| <make-value value-field="facilityLocation" entity-name="FacilityLocation" map="picklistItemInfo.inventoryItemAndLocation"/> |
| <set from-field="facilityLocation" field="facilityLocationByLocationSeqIdMap[facilityLocation.locationSeqId]"/> |
| |
| <clear-field field="picklistItemInfoTempList"/> |
| <set field="picklistItemInfoTempList" from-field="picklistItemInfoListByLocationSeqIdMap[facilityLocation.locationSeqId]"/> |
| <set field="picklistItemInfoTempList[]" from-field="picklistItemInfo"/> |
| <set field="picklistItemInfoListByLocationSeqIdMap[facilityLocation.locationSeqId]" from-field="picklistItemInfoTempList"/> |
| <else> |
| <!-- handle case where an InventoryItem is not associated with a location --> |
| <if-not-empty field="picklistItemInfo.orderItem.productId"> |
| <clear-field field="productValueTemp"/> |
| <set field="productId" from-field="picklistItemInfo.inventoryItemAndLocation.productId"/> |
| <entity-one entity-name="Product" value-field="productValueTemp" use-cache="true"> |
| <field-map field-name="productId"/> |
| </entity-one> |
| <set field="productByProductIdMap[productId]" from-field="productValueTemp"/> |
| |
| <clear-field field="picklistItemInfoTempList"/> |
| <set field="picklistItemInfoTempList" from-field="picklistItemInfoListByProductIdMap[productId]"/> |
| <set field="picklistItemInfoTempList[]" from-field="picklistItemInfo"/> |
| <set field="picklistItemInfoListByProductIdMap[productId]" from-field="picklistItemInfoTempList"/> |
| <else> |
| <!-- Uh oh, no productId, how did this happen? --> |
| <log level="warning" message="No productId and no FacilityLocation, not showing in Picklist for PicklistItem: ${picklistItemInfo.picklistItem}"/> |
| </else> |
| </if-not-empty> |
| </else> |
| </if-not-empty> |
| </iterate> |
| </iterate> |
| |
| <!-- === handle the ones by FacilityLocation === --> |
| <!-- make a facilityLocationList from the facilityLocationByLocationSeqIdMap, which was used to guarantee uniqueness of FacilityLocations --> |
| <iterate-map map="facilityLocationByLocationSeqIdMap" key="locationSeqId" value="facilityLocationList[]"/> |
| |
| <!-- order/sort the facilityLocations --> |
| <set value="+areaId" field="facilityLocsOrdLst[]"/> |
| <set value="+aisleId" field="facilityLocsOrdLst[]"/> |
| <set value="+sectionId" field="facilityLocsOrdLst[]"/> |
| <set value="+levelId" field="facilityLocsOrdLst[]"/> |
| <set value="+positionId" field="facilityLocsOrdLst[]"/> |
| <order-value-list list="facilityLocationList" order-by-list="facilityLocsOrdLst"/> |
| |
| <!-- Now we have an ordered list of FacilityLocations, create a facilityLocationInfoList --> |
| <iterate list="facilityLocationList" entry="facilityLocation"> |
| <clear-field field="facilityLocationInfo"/> |
| <set from-field="facilityLocation" field="facilityLocationInfo.facilityLocation"/> |
| <set from-field="picklistItemInfoListByLocationSeqIdMap[facilityLocation.locationSeqId]" field="facilityLocationInfo.picklistItemInfoList"/> |
| |
| <!-- make the pickQuantity and quantityByPicklistBinIdMap --> |
| <iterate list="facilityLocationInfo.picklistItemInfoList" entry="picklistItemInfo"> |
| <calculate field="facilityLocationInfo.pickQuantity"> |
| <calcop operator="add" field="facilityLocationInfo.pickQuantity"> |
| <calcop operator="get" field="picklistItemInfo.picklistItem.quantity"/> |
| </calcop> |
| </calculate> |
| |
| <calculate field="facilityLocationInfo.quantityByPicklistBinIdMap[picklistItemInfo.picklistBin.picklistBinId]"> |
| <calcop operator="add" field="facilityLocationInfo.quantityByPicklistBinIdMap[picklistItemInfo.picklistBin.picklistBinId]"> |
| <calcop operator="get" field="picklistItemInfo.picklistItem.quantity"/> |
| </calcop> |
| </calculate> |
| |
| <!-- also put the product record in place --> |
| <if-empty field="facilityLocationInfo.product"> |
| <set from-field="picklistItemInfo.product" field="facilityLocationInfo.product"/> |
| <else> |
| <if-compare-field field="facilityLocationInfo.product.productId" to-field="picklistItemInfo.product.productId" operator="not-equals"> |
| <!-- Uh oh, have different products in the same location... what to do about this? --> |
| <log level="error" message="When creating picklist report found in the same location [${facilityLocation.locationSeqId}] two different products: ${facilityLocationInfo.product.productId} and ${picklistItemInfo.product.productId}"/> |
| <string-append string=" WARNING: products with different IDs are sharing the same bin location, you must check products and quantities required against orders : ${facilityLocationInfo.product.productId} and ${picklistItemInfo.product.productId}" field="facilityLocationInfo.message"/> |
| </if-compare-field> |
| </else> |
| </if-empty> |
| </iterate> |
| |
| <!-- create the picklistBinInfoList from the quantityByPicklistBinIdMap --> |
| <iterate-map key="picklistBinId" value="quantity" map="facilityLocationInfo.quantityByPicklistBinIdMap"> |
| <clear-field field="picklistBinInfo"/> |
| <set from-field="picklistBinByIdMap[picklistBinId]" field="picklistBinInfo.picklistBin"/> |
| <set from-field="quantity" field="picklistBinInfo.quantity"/> |
| <set from-field="picklistBinInfo" field="facilityLocationInfo.picklistBinInfoList[]"/> |
| </iterate-map> |
| <order-map-list list="facilityLocationInfo.picklistBinInfoList"><order-by field-name="picklistBin.binLocationNumber"/></order-map-list> |
| |
| <set from-field="facilityLocationInfo" field="facilityLocationInfoList[]"/> |
| </iterate> |
| |
| <!-- === handle the ones by Product === --> |
| <!-- make a productList from the productByProductIdMap, which was used to guarantee uniqueness of Products --> |
| <iterate-map map="productByProductIdMap" key="productId" value="productList[]"/> |
| |
| <!-- order/sort the products --> |
| <set value="+productId" field="productsOrdLst[]"/> |
| <order-value-list list="productList" order-by-list="productsOrdLst"/> |
| |
| <!-- Now we have an ordered list of Products, create a noLocationProductInfoList --> |
| <iterate list="productList" entry="product"> |
| <clear-field field="productInfo"/> |
| <set from-field="product" field="productInfo.product"/> |
| <set from-field="picklistItemInfoListByProductIdMap[product.productId]" field="productInfo.picklistItemInfoList"/> |
| |
| <!-- make the pickQuantity and quantityByPicklistBinIdMap --> |
| <iterate list="productInfo.picklistItemInfoList" entry="picklistItemInfo"> |
| <calculate field="productInfo.pickQuantity"> |
| <calcop operator="add" field="productInfo.pickQuantity"/> |
| <calcop operator="get" field="picklistItemInfo.picklistItem.quantity"/> |
| </calculate> |
| |
| <calculate field="productInfo.quantityByPicklistBinIdMap[picklistItemInfo.picklistBin.picklistBinId]"> |
| <calcop operator="add" field="productInfo.quantityByPicklistBinIdMap[picklistItemInfo.picklistBin.picklistBinId]"> |
| <calcop operator="get" field="picklistItemInfo.picklistItem.quantity"/> |
| </calcop> |
| </calculate> |
| </iterate> |
| |
| <!-- create the picklistBinInfoList from the quantityByPicklistBinIdMap --> |
| <iterate-map key="picklistBinId" value="quantity" map="productInfo.quantityByPicklistBinIdMap"> |
| <clear-field field="picklistBinInfo"/> |
| <set from-field="picklistBinByIdMap[picklistBinId]" field="picklistBinInfo.picklistBin"/> |
| <set from-field="quantity" field="picklistBinInfo.quantity"/> |
| <set from-field="picklistBinInfo" field="productInfo.picklistBinInfoList[]"/> |
| </iterate-map> |
| <order-map-list list="productInfo.picklistBinInfoList"><order-by field-name="picklistBin.binLocationNumber"/></order-map-list> |
| |
| <set from-field="productInfo" field="noLocationProductInfoList[]"/> |
| </iterate> |
| |
| <field-to-result field="facilityLocationInfoList"/> |
| <field-to-result field="noLocationProductInfoList"/> |
| </simple-method> |
| |
| <simple-method method-name="getPicklistSingleInfoInline" short-description="getPicklistSingleInfoInline"> |
| <!-- |
| Creates picklistInfo Map containing: |
| - picklist |
| - facility |
| - shipmentMethodType |
| - statusItem |
| - statusValidChangeToDetailList |
| - picklistRoleInfoList (picklistRole, partyNameView, roleType) |
| - picklistStatusHistoryInfoList (picklistStatusHistory, statusItem, statusItemTo) |
| - picklistBinInfoList |
| - picklistBin |
| - primaryOrderHeader |
| - primaryOrderItemShipGroup |
| - picklistItemInfoList (picklistItem, picklistBin, orderItem, product, inventoryItemAndLocation, orderItemShipGrpInvRes, itemIssuanceList) |
| --> |
| <!-- expects a picklist GenericValue to be in the context, and creates a picklistInfo Map --> |
| <clear-field field="picklistRoleInfoList"/> |
| <get-related value-field="picklist" relation-name="PicklistRole" list="picklistRoleList"/> |
| <iterate list="picklistRoleList" entry="picklistRole"> |
| <clear-field field="picklistRoleInfo"/> |
| <get-related-one value-field="picklistRole" relation-name="PartyNameView" to-value-field="picklistRoleInfo.partyNameView" use-cache="true"/> |
| <get-related-one value-field="picklistRole" relation-name="RoleType" to-value-field="picklistRoleInfo.roleType" use-cache="true"/> |
| <set from-field="picklistRole" field="picklistRoleInfo.picklistRole"/> |
| <field-to-list field="picklistRoleInfo" list="picklistRoleInfoList"/> |
| </iterate> |
| |
| <clear-field field="picklistStatusHistoryInfoList"/> |
| <get-related value-field="picklist" relation-name="PicklistStatusHistory" list="picklistStatusHistoryList"/> |
| <iterate list="picklistStatusHistoryList" entry="picklistStatusHistory"> |
| <clear-field field="picklistStatusHistoryInfo"/> |
| <get-related-one value-field="picklistStatusHistory" relation-name="StatusItem" to-value-field="picklistStatusHistoryInfo.statusItem" use-cache="true"/> |
| <get-related-one value-field="picklistStatusHistory" relation-name="ToStatusItem" to-value-field="picklistStatusHistoryInfo.statusItemTo" use-cache="true"/> |
| <set from-field="picklistStatusHistory" field="picklistStatusHistoryInfo.picklistStatusHistory"/> |
| <field-to-list field="picklistStatusHistoryInfo" list="picklistStatusHistoryInfoList"/> |
| </iterate> |
| |
| <clear-field field="picklistBinOrderList"/> |
| <clear-field field="picklistBinInfoList"/> |
| |
| <set value="+binLocationNumber" field="picklistBinOrderList[]"/> |
| <get-related value-field="picklist" relation-name="PicklistBin" list="picklistBinList" order-by-list="picklistBinOrderList"/> |
| <iterate list="picklistBinList" entry="picklistBin"> |
| <clear-field field="picklistBinInfo"/> |
| <get-related-one value-field="picklistBin" relation-name="PrimaryOrderHeader" to-value-field="picklistBinInfo.primaryOrderHeader"/> |
| <get-related-one value-field="picklistBin" relation-name="PrimaryOrderItemShipGroup" to-value-field="picklistBinInfo.primaryOrderItemShipGroup"/> |
| <get-related-one value-field="picklistBinInfo.primaryOrderHeader" relation-name="ProductStore" to-value-field="picklistBinInfo.productStore" /> |
| |
| <clear-field field="picklistItemInfoList"/> |
| <get-related value-field="picklistBin" relation-name="PicklistItem" list="picklistItemList" use-cache="true"/> |
| <iterate list="picklistItemList" entry="picklistItem"> |
| <clear-field field="picklistItemInfo"/> |
| <get-related-one value-field="picklistItem" relation-name="OrderItem" to-value-field="picklistItemInfo.orderItem"/> |
| <get-related-one value-field="picklistItemInfo.orderItem" relation-name="Product" to-value-field="picklistItemInfo.product"/> |
| <get-related-one value-field="picklistItem" relation-name="InventoryItemAndLocation" to-value-field="picklistItemInfo.inventoryItemAndLocation"/> |
| <get-related-one value-field="picklistItem" relation-name="OrderItemShipGrpInvRes" to-value-field="picklistItemInfo.orderItemShipGrpInvRes"/> |
| <get-related value-field="picklistItem" relation-name="ItemIssuance" list="picklistItemInfo.itemIssuanceList"/> |
| <set from-field="picklistItem" field="picklistItemInfo.picklistItem"/> |
| <set from-field="picklistBin" field="picklistItemInfo.picklistBin"/> |
| <field-to-list field="picklistItemInfo" list="picklistItemInfoList"/> |
| </iterate> |
| <set from-field="picklistItemInfoList" field="picklistBinInfo.picklistItemInfoList"/> |
| |
| <set from-field="picklistBin" field="picklistBinInfo.picklistBin"/> |
| <field-to-list field="picklistBinInfo" list="picklistBinInfoList"/> |
| </iterate> |
| |
| <clear-field field="picklistInfo"/> |
| <set from-field="picklist" field="picklistInfo.picklist"/> |
| <set from-field="picklistRoleInfoList" field="picklistInfo.picklistRoleInfoList"/> |
| <set from-field="picklistStatusHistoryInfoList" field="picklistInfo.picklistStatusHistoryInfoList"/> |
| <set from-field="picklistBinInfoList" field="picklistInfo.picklistBinInfoList"/> |
| <set value="sequenceId" field="orderBy" type="List"/> |
| <get-related-one value-field="picklist" relation-name="StatusItem" to-value-field="picklistInfo.statusItem" use-cache="true"/> |
| <get-related-one value-field="picklist" relation-name="Facility" to-value-field="picklistInfo.facility" use-cache="true"/> |
| <get-related-one value-field="picklist" relation-name="ShipmentMethodType" to-value-field="picklistInfo.shipmentMethodType" use-cache="true"/> |
| <get-related value-field="picklist" relation-name="StatusValidChangeToDetail" order-by-list="orderBy" list="picklistInfo.statusValidChangeToDetailList"/> |
| </simple-method> |
| |
| |
| <!-- ================================================== --> |
| <!-- ================================================== --> |
| <!-- DEJ20050317 These methods are no longer used, but are here temporarily for reference. --> |
| <!-- ================================================== --> |
| <!-- ================================================== --> |
| <simple-method method-name="getPicklistData" short-description="Get Picklist Data"> |
| <!-- |
| Parameters: |
| facilityId |
| shipmentMethodTypeId |
| maxNumberOfOrders |
| Returns: |
| facilityLocationInfoList: List of Maps with facilityLocation, productInfoList, being a List of Maps with product, quantity, inventoryItemList, orderItemList |
| inventoryItemInfoList: List of Maps with inventoryItem, facilityLocation, orderItems, product, statusItem, quantity |
| orderHeaderInfoList: List of Maps with orderHeader, orderItemShipGroup and orderItemInfoList which is List of Maps with orderItem, product and orderItemShipGrpInvResList |
| wrongQuantityReservedList: List of Maps with reservedQuantity and orderItem |
| insufficientQohList: List of Maps with inventoryItem and quantityNeeded |
| --> |
| |
| <check-permission permission="FACILITY" action="_VIEW"> |
| <fail-property resource="ProductUiLabels" property="ProductFacilityViewPermissionError"/> |
| </check-permission> |
| <check-permission permission="FACILITY" action="_UPDATE"> |
| <fail-property resource="ProductUiLabels" property="ProductFacilityUpdatePermissionError"/> |
| </check-permission> |
| <check-errors/> |
| |
| <now-timestamp field="nowTimestamp"/> |
| |
| <set-service-fields map="parameters" service-name="findOrdersToPickMove" to-map="findOrdersToPickMoveMap"/> |
| <call-service service-name="findOrdersToPickMove" in-map-name="findOrdersToPickMoveMap"> |
| <result-to-field result-name="pickMoveInfoList"/> |
| </call-service> |
| |
| <!-- This creates orderHeaderInfoList, wrongQuantityReservedList, insufficientQohList and inventoryItems, inventoryItemOrderItems, inventoryItemQuantities --> |
| <call-simple-method method-name="assembleOrderHeaderInfoInline"/> |
| |
| <!-- This creates facilityLocationInfoList and inventoryItemInfoList --> |
| <call-simple-method method-name="assembleFacilityLocationInfoInline"/> |
| |
| <field-to-result field="orderHeaderInfoList"/> |
| <field-to-result field="wrongQuantityReservedList"/> |
| <field-to-result field="insufficientQohList"/> |
| |
| <field-to-result field="facilityLocationInfoList"/> |
| <field-to-result field="inventoryItemInfoList"/> |
| </simple-method> |
| <simple-method method-name="assembleFacilityLocationInfoInline" short-description="assembleFacilityLocationInfoInline"> |
| <!-- This uses inventoryItems, inventoryItemOrderItems, inventoryItemQuantities --> |
| <!-- This creates facilityLocationInfoList and inventoryItemInfoList (and for internal use facilityLocationMap) --> |
| |
| <!-- go through all quantities and get inventoryItem and facilityLocation --> |
| <iterate-map key="inventoryItemId" value="quantityNeeded" map="inventoryItemQuantities"> |
| <set from-field="inventoryItems[inventoryItemId]" field="inventoryItem"/> |
| |
| <!-- create a list of locations, then sort it, will have to create a reverse Map to go from location to inventory item --> |
| <clear-field field="facilityLocation"/> |
| <get-related-one value-field="inventoryItem" relation-name="FacilityLocation" to-value-field="facilityLocation"/> |
| <if-not-empty field="facilityLocation"> |
| <set from-field="facilityLocation" field="facilityLocationMap[facilityLocation.locationSeqId]"/> |
| <!-- support multiple invnetoryItemIds per facilityLocation.locationSeqId --> |
| <clear-field field="inventoryItemIdList"/> |
| <set from-field="inventoryItemsByLocation[facilityLocation.locationSeqId]" field="inventoryItemIdList"/> |
| <set from-field="inventoryItemId" field="inventoryItemIdList[]"/> |
| <set from-field="inventoryItemIdList" field="inventoryItemsByLocation[facilityLocation.locationSeqId]"/> |
| <else> |
| <set from-field="inventoryItemId" field="noLocationInventoryItemIds[]"/> |
| </else> |
| </if-not-empty> |
| </iterate-map> |
| |
| <!-- make a facilityLocations List from the facilityLocationMap, which was used to guarantee uniqueness --> |
| <iterate-map map="facilityLocationMap" key="locationSeqId" value="facilityLocation"> |
| <set from-field="facilityLocation" field="facilityLocations[]"/> |
| </iterate-map> |
| |
| <!-- order the facilityLocations --> |
| <set value="+areaId" field="facilityLocsOrdLst[]"/> |
| <set value="+aisleId" field="facilityLocsOrdLst[]"/> |
| <set value="+sectionId" field="facilityLocsOrdLst[]"/> |
| <set value="+levelId" field="facilityLocsOrdLst[]"/> |
| <set value="+positionId" field="facilityLocsOrdLst[]"/> |
| <order-value-list list="facilityLocations" order-by-list="facilityLocsOrdLst"/> |
| |
| <!-- for each facility location add an entry to the inventoryItemInfoList --> |
| <iterate list="facilityLocations" entry="facilityLocation"> |
| <!-- facilityLocationInfoList: facilityLocation, productInfoList (product, quantity, inventoryItemList, orderItemList) --> |
| <clear-field field="facilityLocationInfo"/> |
| <set from-field="facilityLocation" field="facilityLocationInfo.facilityLocation"/> |
| |
| <!-- inventoryItemInfoList: facilityLocation, inventoryItem, orderItems, quantity, product, statusItems --> |
| <set from-field="inventoryItemsByLocation[facilityLocation.locationSeqId]" field="inventoryItemIdList"/> |
| <iterate list="inventoryItemIdList" entry="inventoryItemId"> |
| <clear-field field="inventoryItemInfo"/> |
| <set from-field="facilityLocation" field="inventoryItemInfo.facilityLocation"/> |
| <set from-field="inventoryItems[inventoryItemId]" field="inventoryItemInfo.inventoryItem"/> |
| <set from-field="inventoryItemOrderItems[inventoryItemId]" field="inventoryItemInfo.orderItems"/> |
| <set from-field="inventoryItemQuantities[inventoryItemId]" field="inventoryItemInfo.quantity"/> |
| <get-related-one value-field="inventoryItemInfo.inventoryItem" relation-name="Product" to-value-field="inventoryItemInfo.product"/> |
| <get-related-one value-field="inventoryItemInfo.inventoryItem" relation-name="StatusItem" to-value-field="inventoryItemInfo.statusItem"/> |
| |
| <field-to-list field="inventoryItemInfo" list="inventoryItemInfoList"/> |
| |
| <!-- before destroying inventoryItemInfo, add info to the productInfoMap --> |
| <set from-field="inventoryItemInfo.product" field="productInfoMap.${inventoryItemInfo.product.productId}.product"/> |
| <calculate field="productInfoMap.${inventoryItemInfo.product.productId}.quantity"> |
| <calcop operator="get" field="productInfoMap.${inventoryItemInfo.product.productId}.quantity"/> |
| <calcop operator="get" field="inventoryItemInfo.quantity"/> |
| </calculate> |
| <set from-field="inventoryItemInfo.inventoryItem" field="productInfoMap.${inventoryItemInfo.product.productId}.inventoryItemList[]"/> |
| <!-- put orderItems in Map by orderId:orderItemSeqId to make sure they are unique --> |
| <iterate list="inventoryItemInfo.orderItems" entry="orderItem"> |
| <set from-field="orderItem" field="orderItemMap.${orderItem.orderId}:${orderItem.orderItemSeqId}"/> |
| </iterate> |
| </iterate> |
| |
| <iterate-map key="orderItemCompositeId" value="orderItem" map="orderItemMap"> |
| <set from-field="orderItem" field="productInfoMap.${orderItem.productId}.orderItemList[]"/> |
| </iterate-map> |
| |
| <!-- move all values from productInfoMap to facilityLocationInfo.productInfoList --> |
| <iterate-map key="productId" value="productInfo" map="productInfoMap"> |
| <set from-field="productInfo" field="facilityLocationInfo.productInfoList[]"/> |
| </iterate-map> |
| |
| <set from-field="facilityLocationInfo" field="facilityLocationInfoList[]"/> |
| <clear-field field="orderItemMap"/> |
| <clear-field field="productInfoMap"/> |
| </iterate> |
| |
| <!-- add all noLocationInventoryItemIds to inventoryItemInfoList with all entries except facilityLocation --> |
| <iterate list="noLocationInventoryItemIds" entry="inventoryItemId"> |
| <set from-field="inventoryItems${inventoryItemId}" field="inventoryItemInfo.inventoryItem"/> |
| <set from-field="inventoryItemOrderItems[inventoryItemId]" field="inventoryItemInfo.orderItems"/> |
| <set from-field="inventoryItemQuantities[inventoryItemId]" field="inventoryItemInfo.quantity"/> |
| <get-related-one value-field="inventoryItemInfo.inventoryItem" relation-name="Product" to-value-field="inventoryItemInfo.product"/> |
| <get-related-one value-field="inventoryItemInfo.inventoryItem" relation-name="StatusItem" to-value-field="inventoryItemInfo.statusItem"/> |
| |
| <set from-field="inventoryItemInfo" field="inventoryItemInfoList[]"/> |
| <clear-field field="inventoryItemInfo"/> |
| </iterate> |
| </simple-method> |
| |
| <!-- special method to check update the picklist status from the item status --> |
| <simple-method method-name="checkPicklistBinItemStatuses" short-description="Checks the item status and updates the pick list status"> |
| <!-- find the picklist bin --> |
| <make-value value-field="binLookup" entity-name="PicklistBin"/> |
| <set-pk-fields map="parameters" value-field="binLookup"/> |
| <find-by-primary-key map="binLookup" value-field="picklistBin"/> |
| |
| <!-- find the pick list --> |
| <make-value value-field="plLookup" entity-name="Picklist"/> |
| <set-pk-fields map="picklistBin" value-field="plLookup"/> |
| <find-by-primary-key map="plLookup" value-field="picklist"/> |
| |
| <!-- find all related picklist items --> |
| <entity-and entity-name="PicklistItemAndBin" list="picklistItem"> |
| <field-map field-name="picklistId" from-field="picklist.picklistId"/> |
| </entity-and> |
| |
| <set field="allCompleteOrCancelled" type="Boolean" value="true"/> |
| <set field="allCancelled" type="Boolean" value="true"/> |
| |
| <!-- determine if all the items are completed and/or cancelled --> |
| <iterate list="picklistItem" entry="item"> |
| <log level="info" message="checking status for item: ${item}"/> |
| <if-compare field="item.itemStatusId" value="PICKITEM_CANCELLED" operator="not-equals"> |
| <log level="info" message="item is not cancelled; all cancelled set to false"/> |
| <set field="allCancelled" type="Boolean" value="false"/> |
| |
| <if-compare field="item.itemStatusId" value="PICKITEM_COMPLETED" operator="not-equals"> |
| <log level="info" message="item is not completed; all completed set to false"/> |
| <set field="allCompleteOrCancelled" type="Boolean" value="false"/> |
| </if-compare> |
| </if-compare> |
| </iterate> |
| |
| <!-- update the picklist status --> |
| <if-compare field="allCancelled" value="true" type="Boolean" operator="equals"> |
| <log level="info" message="Setting picklist #${picklist.picklistId} to cancelled"/> |
| <set field="picklist.statusId" value="PICKLIST_CANCELLED"/> |
| <store-value value-field="picklist"/> |
| <else> |
| <log level="info" message="Not all items were cancelled; now check if we can complete the picklist : ${allCompleteOrCancelled}"/> |
| <if-compare field="allCompleteOrCancelled" value="true" type="Boolean" operator="equals"> |
| <log level="info" message="Setting picklist #${picklist.picklistId} to completed"/> |
| <set field="picklist.statusId" value="PICKLIST_PICKED"/> |
| <store-value value-field="picklist"/> |
| </if-compare> |
| </else> |
| </if-compare> |
| </simple-method> |
| |
| <simple-method method-name="cancelPicklistAndItems" short-description="If Picklist is Cancelled then cancel all the PicklistItem"> |
| <entity-and entity-name="PicklistBin" list="picklistBinList"> |
| <field-map field-name="picklistId" from-field="parameters.picklistId"/> |
| </entity-and> |
| <if-not-empty field="picklistBinList"> |
| <iterate list="picklistBinList" entry="picklistBin"> |
| <entity-and entity-name="PicklistItem" list="itemList"> |
| <field-map field-name="picklistBinId" from-field="picklistBin.picklistBinId"/> |
| </entity-and> |
| <if-not-empty field="itemList"> |
| <iterate list="itemList" entry="item"> |
| <set field="item.itemStatusId" value="PICKITEM_CANCELLED"/> |
| <store-value value-field="item"/> |
| </iterate> |
| </if-not-empty> |
| </iterate> |
| </if-not-empty> |
| </simple-method> |
| </simple-methods> |