This is an automated email from the ASF dual-hosted git repository.
jleroux pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push:
new af6424127b Fixed: incomplete invoice generation when receiving several
items from the 'Receive Inventory Against Purchase Order' (OFBIZ-13358) (#959)
af6424127b is described below
commit af6424127b90d45be296e55e13cd2030e74cf619
Author: Anahita Goljahani <[email protected]>
AuthorDate: Mon Feb 9 09:51:28 2026 +0100
Fixed: incomplete invoice generation when receiving several items from the
'Receive Inventory Against Purchase Order' (OFBIZ-13358) (#959)
As described in the jira ticket
[OFBIZ-13358](https://issues.apache.org/jira/browse/OFBIZ-13358),
currently, when a purchase order contains more than one item and
inventory is received from the ‘Receive Inventory Against Purchase
Order’ screen, the invoice generated by the system reports only the
first item processed, while the remaining items are ignored.
This PR splits the original request-map
'issueOrderItemToShipmentAndReceiveAgainstPO' into two request-maps: the
first creates the shipment items, and the second receives them. Two of
the existing services, 'issueOrderItemToShipment' and
'receiveInventoryProduct' have been used instead of the specialized
service 'issueOrderItemToShipmentAndReceiveAgainstPO', which was causing
the issue with the invoice.
---
.../product/servicedef/services_shipment.xml | 11 ---
.../shipment/ShipmentReceiptServices.groovy | 85 ----------------------
.../product/webapp/facility/WEB-INF/controller.xml | 8 +-
3 files changed, 7 insertions(+), 97 deletions(-)
diff --git a/applications/product/servicedef/services_shipment.xml
b/applications/product/servicedef/services_shipment.xml
index b8af50d902..dce7ef2f75 100644
--- a/applications/product/servicedef/services_shipment.xml
+++ b/applications/product/servicedef/services_shipment.xml
@@ -900,17 +900,6 @@ under the License.
<override name="facilityId" optional="false"/>
</service>
- <service name="issueOrderItemToShipmentAndReceiveAgainstPO"
engine="groovy" transaction-timeout="600"
-
location="component://product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentReceiptServices.groovy"
invoke="issueOrderItemToShipmentAndReceiveAgainstPO" auth="true">
- <description>Issues order item quantity specified to the shipment,
then receives inventory for that item and quantity</description>
- <required-permissions join-type="AND">
- <permission-service
service-name="checkCanChangeShipmentStatusPacked" main-action="CREATE"/>
- <permission-service service-name="facilityGenericPermission"
main-action="UPDATE"/>
- </required-permissions>
- <implements service="issueOrderItemToShipment"/>
- <implements service="receiveInventoryProduct"/>
- </service>
-
<service name="quickReceiveReturn" engine="groovy"
location="component://product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentReceiptServices.groovy"
invoke="quickReceiveReturn" auth="true">
<permission-service service-name="facilityGenericPermission"
main-action="CREATE"/>
diff --git
a/applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentReceiptServices.groovy
b/applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentReceiptServices.groovy
index 7ad5de20eb..9c8d39f72c 100644
---
a/applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentReceiptServices.groovy
+++
b/applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentReceiptServices.groovy
@@ -274,91 +274,6 @@ Map quickReceiveReturn() {
return result
}
-/**
- * Issues order item quantity specified to the shipment, then receives
inventory for that item and quantity
- */
-Map issueOrderItemToShipmentAndReceiveAgainstPO() {
- Map result = success()
- String shipmentItemSeqId
- GenericValue shipmentItem
- // get orderItem
- GenericValue orderItem = from('OrderItem').where(parameters).queryOne()
- // get orderItemShipGroupAssoc
- GenericValue orderItemShipGroupAssoc =
from('OrderItemShipGroupAssoc').where(parameters).queryOne()
- // get shipment
- GenericValue shipment = from('Shipment').where(parameters).queryOne()
-
- // 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 (orderItem?.productId) {
- EntityCondition condition = EntityCondition.makeCondition([
- EntityCondition.makeCondition(productId: orderItem.productId),
- EntityCondition.makeCondition(shipmentId: shipment.shipmentId)
- ])
- if (parameters.shipmentItemSeqId) {
- condition = EntityCondition.makeCondition([
- EntityCondition.makeCondition(shipmentItemSeqId:
parameters.shipmentItemSeqId),
- condition
- ])
- }
- shipmentItem = from('ShipmentItem')
- .where(condition)
- .orderBy('shipmentItemSeqId')
- .queryFirst()
- }
- if (shipmentItem) {
- Map inputMap = parameters
- shipmentItemSeqId = shipmentItem.shipmentItemSeqId
- inputMap.orderItem = orderItem
- Map serviceResult = run service: 'getTotalIssuedQuantityForOrderItem',
with: inputMap
- BigDecimal totalIssuedQuantity = serviceResult.totalIssuedQuantity
- BigDecimal receivedQuantity =
getReceivedQuantityForOrderItem(orderItem)
- receivedQuantity += parameters.quantity
- GenericValue orderShipment = from('OrderShipment')
- .where(orderId: orderItem.orderId,
- orderItemSeqId: orderItem.orderItemSeqId,
- shipmentId: shipmentItem.shipmentId,
- shipmentItemSeqId: shipmentItem.shipmentItemSeqId,
- shipGroupSeqId: orderItemShipGroupAssoc.shipGroupSeqId)
- .queryFirst()
- if (totalIssuedQuantity < receivedQuantity) {
- BigDecimal quantityToAdd = receivedQuantity - totalIssuedQuantity
- shipmentItem.quantity += quantityToAdd
- shipmentItem.store()
- orderShipment.quantity = orderShipment.quantity + quantityToAdd
- orderShipment.store()
- }
- } else {
- Map shipmentItemCreate = [productId: orderItem.productId, shipmentId:
parameters.shipmentId, quantity: parameters.quantity]
- Map serviceResult = run service: 'createShipmentItem', with:
shipmentItemCreate
- Map shipmentItemLookupPk = [shipmentItemSeqId:
serviceResult.shipmentItemSeqId, shipmentId: parameters.shipmentId]
- shipmentItem =
from('ShipmentItem').where(shipmentItemLookupPk).queryOne()
- shipmentItemSeqId = shipmentItem.shipmentItemSeqId
-
- // Create OrderShipment for this ShipmentItem
- Map orderShipmentCreate = [quantity: parameters.quantity,
- shipmentId: shipmentItem.shipmentId,
- shipmentItemSeqId:
shipmentItem.shipmentItemSeqId,
- orderId: orderItem.orderId,
- orderItemSeqId: orderItem.orderItemSeqId]
- if (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
- orderShipmentCreate.shipGroupSeqId =
orderItemShipGroupAssoc.shipGroupSeqId
- }
- run service: 'createOrderShipment', with: orderShipmentCreate
- }
- // 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"/>
-
- Map receiveInventoryProductCtx = parameters
- receiveInventoryProductCtx.shipmentItemSeqId = shipmentItemSeqId
- Map serviceResult = run service: 'receiveInventoryProduct', with:
receiveInventoryProductCtx
- result.inventoryItemId = serviceResult.inventoryItemId
- result.successMessageList = serviceResult.successMessageList
-
- return result
-}
-
/**
* Computes the till now received quantity from all ShipmentReceipts
*/
diff --git a/applications/product/webapp/facility/WEB-INF/controller.xml
b/applications/product/webapp/facility/WEB-INF/controller.xml
index 2a96e7328f..b54fa20465 100644
--- a/applications/product/webapp/facility/WEB-INF/controller.xml
+++ b/applications/product/webapp/facility/WEB-INF/controller.xml
@@ -1197,7 +1197,13 @@ under the License.
</request-map>
<request-map uri="issueOrderItemToShipmentAndReceiveAgainstPO">
<security https="true" auth="true"/>
- <event type="service-multi" path=""
invoke="issueOrderItemToShipmentAndReceiveAgainstPO"/>
+ <event type="service-multi" path="" invoke="issueOrderItemToShipment"/>
+ <response name="success" type="request"
value="receiveInventoryProductsFromShipment"/>
+ <response name="error" type="view"
value="ReceiveInventoryAgainstPurchaseOrder"/>
+ </request-map>
+ <request-map uri="receiveInventoryProductsFromShipment">
+ <security https="true" auth="true"/>
+ <event type="service-multi" path="" invoke="receiveInventoryProduct"/>
<response name="success" type="view"
value="ReceiveInventoryAgainstPurchaseOrder"/>
<response name="error" type="view"
value="ReceiveInventoryAgainstPurchaseOrder"/>
</request-map>