Skip to content

Commit d0d01d8

Browse files
goljaJacquesLeRoux
authored andcommitted
Fixed: PO receipts with zero accepted units are not handled correctly (OFBIZ-13376) (#1027)
As detailed in [OFBIZ-13376](https://issues.apache.org/jira/browse/OFBIZ-13376), currently, when a PO is received with zero accepted units (e.g., via the ‘ReceiveInventory’ screen), the system creates: - an inventory item with quantity set to zero - a receipt with zero accepted units, even when there are no rejected units. This behavior is not desirable. When receiving a PO, - if no item units are accepted, the system should not create an inventory item with zero quantity - if rejected units are also zero, the system should not create a receipt. The changes in this PR: - avoid creating a receipt and an inventory item when both accepted and rejected quantities are zero - create a receipt, but not an inventory item, when the accepted quantity is zero, but there are rejected units.
1 parent 7ba83c4 commit d0d01d8

9 files changed

Lines changed: 52 additions & 18 deletions

File tree

applications/accounting/minilang/ledger/GeneralLedgerServices.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,9 @@ under the License.
12241224
<call-simple-method method-name="getGlArithmeticSettingsInline"/>
12251225

12261226
<entity-one entity-name="ShipmentReceipt" value-field="shipmentReceipt"/>
1227+
<if-compare field="shipmentReceipt.quantityAccepted" operator="less-equals" value="0">
1228+
<return/>
1229+
</if-compare>
12271230
<get-related-one value-field="shipmentReceipt" relation-name="InventoryItem" to-value-field="inventoryItem"/>
12281231
<get-related-one value-field="shipmentReceipt" relation-name="Shipment" to-value-field="shipment"/>
12291232
<if-not-empty field="shipmentReceipt.returnId">

applications/datamodel/entitydef/shipment-entitymodel.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ under the License.
473473
<alias entity-alias="II" name="availableToPromiseTotal"/>
474474
<alias entity-alias="II" name="unitCost"/>
475475
<alias entity-alias="II" name="lotId"/>
476-
<view-link entity-alias="SR" rel-entity-alias="II">
476+
<view-link entity-alias="SR" rel-entity-alias="II" rel-optional="true">
477477
<key-map field-name="inventoryItemId"/>
478478
</view-link>
479479
</view-entity>

applications/order/template/order/OrderItems.ftl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,9 +660,11 @@ under the License.
660660
class="buttontext">${shipmentReceipt.shipmentId}</a>:${shipmentReceipt.shipmentItemSeqId!}
661661
</#if>
662662
&nbsp;<#if shipmentReceipt.datetimeReceived?has_content>${Static["org.apache.ofbiz.base.util.UtilFormatOut"].formatDateTime(shipmentReceipt.datetimeReceived, "", locale, timeZone)!}</#if>&nbsp;
663-
<span class="label">${uiLabelMap.CommonInventory}</span>&nbsp;
664-
<a href="<@ofbizUrl controlPath="/facility/control">EditInventoryItem?inventoryItemId=${shipmentReceipt.inventoryItemId}</@ofbizUrl>"
665-
class="buttontext">${shipmentReceipt.inventoryItemId}</a>
663+
<#if shipmentReceipt.inventoryItemId?has_content>
664+
<span class="label">${uiLabelMap.CommonInventory}</span>&nbsp;
665+
<a href="<@ofbizUrl controlPath="/facility/control">EditInventoryItem?inventoryItemId=${shipmentReceipt.inventoryItemId}</@ofbizUrl>"
666+
class="buttontext">${shipmentReceipt.inventoryItemId}</a>
667+
</#if>
666668
</td>
667669
<td align="center">
668670
${shipmentReceipt.quantityAccepted?string.number}&nbsp;/&nbsp;${shipmentReceipt.quantityRejected?default(0)?string.number}

applications/product/servicedef/secas.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ under the License.
134134

135135
<!-- Set the average cost of product -->
136136
<eca service="receiveInventoryProduct" event="commit">
137+
<condition field-name="inventoryItemId" operator="is-not-empty"/>
137138
<action service="updateProductAverageCostOnReceiveInventory" mode="sync"/>
138139
</eca>
139140

applications/product/servicedef/secas_shipment.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,11 @@ under the License.
158158
<action service="updateOrderStatusFromReceipt" mode="sync" run-as-user="system"/>
159159
</eca>
160160
<eca service="createShipmentReceipt" event="commit">
161-
<condition field-name="shipmentId" operator="is-not-empty"/>
161+
<condition field-name="inventoryItemId" operator="is-not-empty"/>
162162
<action service="checkDecomposeInventoryItem" mode="sync"/>
163+
</eca>
164+
<eca service="createShipmentReceipt" event="commit">
165+
<condition field-name="shipmentId" operator="is-not-empty"/>
163166
<action service="updatePurchaseShipmentFromReceipt" mode="sync"/>
164167
</eca>
165168

applications/product/servicedef/services_shipment.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ under the License.
864864
</type-validate>
865865
</attribute>
866866
<attribute name="affectAccounting" type="Boolean" mode="OUT" optional="true"/>
867+
<override name="inventoryItemId" optional="true"/>
867868
</service>
868869
<service name="updatePurchaseShipmentFromReceipt" engine="java"
869870
location="org.apache.ofbiz.shipment.shipment.ShipmentServices" invoke="updatePurchaseShipmentFromReceipt" auth="true">

applications/product/src/main/groovy/org/apache/ofbiz/product/facility/inventory/ReceiveInventory.groovy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ if (purchaseOrderItems) {
207207
receivedItems = null
208208
if (purchaseOrder) {
209209
receivedItems = from('ShipmentReceiptAndItem').where('orderId', purchaseOrderId, 'facilityId', facilityId).queryList()
210+
receivedItemsWithNoInventory = from('ShipmentReceiptAndItem').where('orderId', purchaseOrderId, 'inventoryItemId', null).queryList()
211+
receivedItems.addAll(receivedItemsWithNoInventory)
210212
context.receivedItems = receivedItems
211213
}
212214

applications/product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentReceiptServices.groovy

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ Map receiveInventoryProduct () {
7474
* - DEJ20070822: something to consider for the future:
7575
* maybe instead of this funny looping maybe for serialized items we should only allow a quantity of 1, ie return an error if it is not 1
7676
*/
77+
78+
// Return an error if both quantityAccepted and quantityRejected are zero or less than zero
79+
BigDecimal quantityRejected = parameters.quantityRejected ?: BigDecimal.ZERO
80+
if ((quantityRejected == BigDecimal.ZERO && parameters.quantityAccepted == BigDecimal.ZERO)
81+
|| (quantityRejected < BigDecimal.ZERO || parameters.quantityAccepted < BigDecimal.ZERO)) {
82+
return error(UtilProperties.getMessage('ProductUiLabels', 'ProductNoItemsToReceive', parameters.locale))
83+
}
84+
7785
Map result = success()
7886
List successMessageList = []
7987
String currentInventoryItemId
@@ -85,8 +93,10 @@ Map receiveInventoryProduct () {
8593
return error(UtilProperties.getMessage('ProductUiLabels', 'FacilityReceiveInventoryProduct', errorLog, parameters.locale))
8694
// before getting going, see if there are any validation issues so far
8795
}
88-
loops = parameters.quantityAccepted
89-
parameters.quantityAccepted = BigDecimal.ONE
96+
if (parameters.quantityAccepted > BigDecimal.ZERO) {
97+
loops = parameters.quantityAccepted
98+
parameters.quantityAccepted = BigDecimal.ONE
99+
}
90100
}
91101
parameters.quantityOnHandDiff = parameters.quantityAccepted
92102
parameters.availableToPromiseDiff = parameters.quantityAccepted
@@ -135,12 +145,14 @@ Map receiveInventoryProduct () {
135145
run service: 'updateInventoryItem', with: parameters
136146
currentInventoryItemId = parameters.currentInventoryItemId
137147
} else {
138-
Map serviceResult = run service: 'createInventoryItem', with: parameters
139-
currentInventoryItemId = serviceResult.inventoryItemId
148+
if (parameters.quantityAccepted > BigDecimal.ZERO) {
149+
Map serviceResult = run service: 'createInventoryItem', with: parameters
150+
currentInventoryItemId = serviceResult.inventoryItemId
151+
}
140152
}
141153

142154
// do this only for non-serialized inventory
143-
if (parameters.inventoryItemTypeId != 'SERIALIZED_INV_ITEM') {
155+
if (parameters.inventoryItemTypeId != 'SERIALIZED_INV_ITEM' && parameters.quantityAccepted > BigDecimal.ZERO) {
144156
serviceInMap = [:]
145157
serviceInMap = parameters
146158
serviceInMap.inventoryItemId = currentInventoryItemId
@@ -153,7 +165,7 @@ Map receiveInventoryProduct () {
153165
run service: 'createShipmentReceipt', with: serviceInMap
154166

155167
//update serialized items to AVAILABLE (only if this is not a return), which then triggers other SECA chains
156-
if (parameters.inventoryItemTypeId == 'SERIALIZED_INV_ITEM' && !parameters.returnId) {
168+
if (parameters.inventoryItemTypeId == 'SERIALIZED_INV_ITEM' && !parameters.returnId && parameters.quantityAccepted > BigDecimal.ZERO) {
157169
// Retrieve the new inventoryItem
158170
GenericValue inventoryItem = from('InventoryItem').where(inventoryItemId: currentInventoryItemId).queryOne()
159171

@@ -165,13 +177,18 @@ Map receiveInventoryProduct () {
165177
run service: 'updateInventoryItem', with: serviceInMap
166178
}
167179
}
168-
serviceInMap = [:]
169-
serviceInMap = parameters
170-
serviceInMap.inventoryItemId = currentInventoryItemId
171-
run service: 'balanceInventoryItems', with: serviceInMap
180+
if (parameters.quantityAccepted > BigDecimal.ZERO) {
181+
serviceInMap = [:]
182+
serviceInMap = parameters
183+
serviceInMap.inventoryItemId = currentInventoryItemId
184+
run service: 'balanceInventoryItems', with: serviceInMap
185+
186+
successMessageList << "Received ${parameters.quantityAccepted} of ${parameters.productId}"
187+
.concat(" in inventory item ${currentInventoryItemId}.") as String
188+
}
172189

173-
successMessageList << "Received ${parameters.quantityAccepted} of ${parameters.productId}"
174-
.concat(" in inventory item ${currentInventoryItemId}.") as String
190+
//the following ensures that, for serialized items, the rejected quantity is accounted for only once
191+
parameters.quantityRejected = BigDecimal.ZERO
175192
}
176193
// return the last inventory item received
177194
result.inventoryItemId = currentInventoryItemId

applications/product/template/shipment/ReceiveInventoryAgainstPurchaseOrder.ftl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@ under the License.
2424
for (var x = 0; x <= rowCount; x++) {
2525
var quantityAcceptedInput = document.getElementById('quantityAccepted_o_' + x);
2626
var quantityInput = document.getElementById('quantity_o_' + x);
27+
var rowSubmit = document.getElementById('_rowSubmit_o_' + x);
2728
if (quantityAcceptedInput != null && quantityInput != null) {
2829
quantityInput.value = quantityAcceptedInput.value;
30+
if (quantityAcceptedInput.value == 0) {
31+
rowSubmit.checked = false;
32+
rowSubmit.value = "N";
33+
}
2934
}
3035
}
3136
}
@@ -193,7 +198,7 @@ under the License.
193198
<a href="<@ofbizUrl>ReceiveInventoryAgainstPurchaseOrder?shipmentId=${shipmentId}&amp;purchaseOrderId=${orderId}&amp;productId=${product.productId}</@ofbizUrl>" class="buttontext">${uiLabelMap.CommonClear}</a>
194199
</td>
195200
<td align="right">
196-
<input type="checkbox" name="_rowSubmit_o_${rowCount}" value="Y" onclick="highlightRow(this,'orderItemData_tableRow_${rowCount}');" />
201+
<input type="checkbox" name="_rowSubmit_o_${rowCount}" id="_rowSubmit_o_${rowCount}" value="Y" onclick="highlightRow(this,'orderItemData_tableRow_${rowCount}');" />
197202
</td>
198203
<#assign rowCount = rowCount + 1>
199204
</#if>

0 commit comments

Comments
 (0)