I have encountered a significant localization bug during the purchase
order receiving process in Apache OFBiz. When using non-US regional
settings (specifically Polish locale, where the decimal separator is a
comma `,` instead of a dot `.`), the unit price of an item gets
multiplied incorrectly (e.g., 7.410 becomes 741.00) after completing the
receipt.
Steps to reproduce:
1. Set the system/user profile locale to Polish (pl_PL).
2. Create a new Purchase Order: select an organization, vendor, currency
(PLN), and a product catalog.
3. Add a test product to the order with a quantity of 1 and a unit price
of 7.410.
4. Click "Finalize order" -> "Continue" -> select a warehouse location
-> click "Continue" and finalize with "Create Order".
5. Approve the order. The order details screen correctly shows the unit
price as 7,41 PLN and Total Due as 7,41 PLN.
6. Click "Quick Receive Purchase Order".
7. Choose the shipment to receive and click "Receive Selected Shipment".
8. On the receiving form, verify the fields: Qty Accepted: 1, Per Unit
Price: 7,41 PLN. Click "Receive Selected Product(s)".
9. In the "Receipt(s) For Purchase Order" screen, the "Per Unit Price"
is displayed as 7.410. Click the PO identifier link to return to the
order view.
10. Review the order items: the "Unit / List" column now incorrectly
displays 741.00 PLN (multiplied by 100). The Items SubTotal and Total
Due are also bloated to 741.00 PLN.
Root Cause:
In the `updateIssuanceShipmentAndPoOnReceiveInventory` service
definition, the attributes `unitCost` and `orderCurrencyUnitPrice` are
defined as `String`. When the Groovy service parses these string values
into numerical objects, it encounters a formatting mismatch due to the
active regional settings (Locale), shifting the decimal threshold and
corrupting the monetary values.
Proposed Solution:
Change the data type of `unitCost` and `orderCurrencyUnitPrice`
attributes from `String` to `BigDecimal` directly in the service
definition. This forces the OFBiz framework to handle the type
conversion natively and safely before passing it to the Groovy
implementation layer.
File: applications/product/servicedef/services_shipment.xml
Modified Fragment:
<service name="updateIssuanceShipmentAndPoOnReceiveInventory"
engine="groovy"
location="component://product/src/main/groovy/org/apache/ofbiz/product/shipment/ShipmentReceiptServices.groovy"
invoke="updateIssuanceShipmentAndPoOnReceiveInventory">
<description>Update issuance, shipment and order items if
quantity received is higher than quantity on purchase order</description>
...
<attribute name="unitCost" type="BigDecimal" mode="IN"
optional="true"/>
<attribute name="orderCurrencyUnitPrice" type="BigDecimal"
mode="IN" optional="true"/>
</service>
This modification resolves the issue completely and ensures robust
handling across different Locales.
Best regards,
Tomek