mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-15 07:28:39 +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)
# Conflicts:
# erpnext/controllers/taxes_and_totals.py
This commit is contained in:
@@ -358,7 +358,7 @@ class BuyingController(SubcontractingController):
|
|||||||
)
|
)
|
||||||
valuation_amount_adjustment -= item.item_tax_amount
|
valuation_amount_adjustment -= item.item_tax_amount
|
||||||
|
|
||||||
self.round_floats_in(item)
|
self.round_floats_in(item, do_not_round_fields=["conversion_factor"])
|
||||||
if flt(item.conversion_factor) == 0.0:
|
if flt(item.conversion_factor) == 0.0:
|
||||||
item.conversion_factor = (
|
item.conversion_factor = (
|
||||||
get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
|
get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
|
||||||
|
|||||||
@@ -184,8 +184,20 @@ class calculate_taxes_and_totals:
|
|||||||
if self.doc.get("is_consolidated"):
|
if self.doc.get("is_consolidated"):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
if not self.discount_amount_applied:
|
if not self.discount_amount_applied:
|
||||||
do_not_round_fields = ["valuation_rate", "incoming_rate", "sales_incoming_rate"]
|
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)
|
||||||
|
>>>>>>> 269cc6ee3b (fix: preserve UOM conversion factor precision in transactions)
|
||||||
|
|
||||||
for item in self.doc.items:
|
for item in self.doc.items:
|
||||||
self.doc.round_floats_in(item, do_not_round_fields=do_not_round_fields)
|
self.doc.round_floats_in(item, do_not_round_fields=do_not_round_fields)
|
||||||
|
|||||||
@@ -126,11 +126,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() {
|
calculate_item_values() {
|
||||||
var me = this;
|
var me = this;
|
||||||
if (!this.discount_amount_applied) {
|
if (!this.discount_amount_applied) {
|
||||||
|
const fields_to_round = this.get_item_fields_to_round();
|
||||||
for (const item of this.frm.doc.items || []) {
|
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.net_rate = item.rate;
|
||||||
item.qty = item.qty === undefined ? (me.frm.doc.is_return ? -1 : 1) : item.qty;
|
item.qty = item.qty === undefined ? (me.frm.doc.is_return ? -1 : 1) : item.qty;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user