mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-06 11:13:04 +00:00
fix: preserve UOM conversion factor precision in transactions
calculate_item_values rounds every Float field on an item row to the
site's Float Precision (3 by default), and conversion_factor was one of
them. The factor is a ratio, not a rate: UOM Conversion Factor.value is
stored at precision 9, and Material Request keeps the full value because
it has no currency field and so never runs the calculation.
Mapping a Material Request to a Purchase Order therefore truncated the
factor - 0.453592292 for Pound -> Kg became 0.454 - and stock_qty, which
is recomputed as qty * conversion_factor, drifted from the quantity that
was requested, leaving the Material Request unable to close.
Exclude conversion_factor from the rounded fields on the server and on
the client. Factors below the site precision would otherwise round to
zero outright.
(cherry picked from commit 269cc6ee3b)
This commit is contained in:
@@ -467,7 +467,7 @@ class BuyingController(SubcontractingController):
|
||||
self.precision("item_tax_amount", item),
|
||||
)
|
||||
|
||||
self.round_floats_in(item)
|
||||
self.round_floats_in(item, do_not_round_fields=["conversion_factor"])
|
||||
if flt(item.conversion_factor) == 0.0:
|
||||
item.conversion_factor = (
|
||||
get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
|
||||
|
||||
@@ -227,7 +227,12 @@ class calculate_taxes_and_totals:
|
||||
if self.doc.get("is_consolidated") or self.discount_amount_applied:
|
||||
return
|
||||
|
||||
do_not_round_fields = ["valuation_rate", "incoming_rate", "sales_incoming_rate"]
|
||||
do_not_round_fields = [
|
||||
"valuation_rate",
|
||||
"incoming_rate",
|
||||
"sales_incoming_rate",
|
||||
"conversion_factor",
|
||||
]
|
||||
for item in self.doc.items:
|
||||
self.doc.round_floats_in(item, do_not_round_fields=do_not_round_fields)
|
||||
self.calculate_item_rate(item)
|
||||
|
||||
@@ -138,11 +138,26 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
}
|
||||
}
|
||||
|
||||
get_item_fields_to_round() {
|
||||
const [item] = this.frm.doc.items || [];
|
||||
if (!item) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const do_not_round_fields = ["conversion_factor"];
|
||||
return frappe.meta
|
||||
.get_fieldnames(item.doctype, item.parent, {
|
||||
fieldtype: ["in", ["Currency", "Float"]],
|
||||
})
|
||||
.filter((fieldname) => !do_not_round_fields.includes(fieldname));
|
||||
}
|
||||
|
||||
calculate_item_values() {
|
||||
var me = this;
|
||||
if (!this.discount_amount_applied) {
|
||||
const fields_to_round = this.get_item_fields_to_round();
|
||||
for (const item of this.frm.doc.items || []) {
|
||||
frappe.model.round_floats_in(item);
|
||||
frappe.model.round_floats_in(item, fields_to_round);
|
||||
item.net_rate = item.rate;
|
||||
item.qty = item.qty === undefined ? (me.frm.doc.is_return ? -1 : 1) : item.qty;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user