Merge pull request #30834 from ankush/transfer_precision
fix: precision loss when transferring
This commit is contained in:
commit
06c036f49f
@ -672,7 +672,8 @@ class StockEntry(StockController):
|
|||||||
batch_no=d.batch_no,
|
batch_no=d.batch_no,
|
||||||
)
|
)
|
||||||
|
|
||||||
d.basic_rate = flt(d.basic_rate, d.precision("basic_rate"))
|
# do not round off basic rate to avoid precision loss
|
||||||
|
d.basic_rate = flt(d.basic_rate)
|
||||||
if d.is_process_loss:
|
if d.is_process_loss:
|
||||||
d.basic_rate = flt(0.0)
|
d.basic_rate = flt(0.0)
|
||||||
d.basic_amount = flt(flt(d.transfer_qty) * flt(d.basic_rate), d.precision("basic_amount"))
|
d.basic_amount = flt(flt(d.transfer_qty) * flt(d.basic_rate), d.precision("basic_amount"))
|
||||||
@ -720,7 +721,7 @@ class StockEntry(StockController):
|
|||||||
total_fg_qty = sum([flt(d.transfer_qty) for d in self.items if d.is_finished_item])
|
total_fg_qty = sum([flt(d.transfer_qty) for d in self.items if d.is_finished_item])
|
||||||
return flt(outgoing_items_cost / total_fg_qty)
|
return flt(outgoing_items_cost / total_fg_qty)
|
||||||
|
|
||||||
def get_basic_rate_for_manufactured_item(self, finished_item_qty, outgoing_items_cost=0):
|
def get_basic_rate_for_manufactured_item(self, finished_item_qty, outgoing_items_cost=0) -> float:
|
||||||
scrap_items_cost = sum([flt(d.basic_amount) for d in self.get("items") if d.is_scrap_item])
|
scrap_items_cost = sum([flt(d.basic_amount) for d in self.get("items") if d.is_scrap_item])
|
||||||
|
|
||||||
# Get raw materials cost from BOM if multiple material consumption entries
|
# Get raw materials cost from BOM if multiple material consumption entries
|
||||||
@ -760,10 +761,8 @@ class StockEntry(StockController):
|
|||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if d.transfer_qty:
|
if d.transfer_qty:
|
||||||
d.amount = flt(flt(d.basic_amount) + flt(d.additional_cost), d.precision("amount"))
|
d.amount = flt(flt(d.basic_amount) + flt(d.additional_cost), d.precision("amount"))
|
||||||
d.valuation_rate = flt(
|
# Do not round off valuation rate to avoid precision loss
|
||||||
flt(d.basic_rate) + (flt(d.additional_cost) / flt(d.transfer_qty)),
|
d.valuation_rate = flt(d.basic_rate) + (flt(d.additional_cost) / flt(d.transfer_qty))
|
||||||
d.precision("valuation_rate"),
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_total_incoming_outgoing_value(self):
|
def set_total_incoming_outgoing_value(self):
|
||||||
self.total_incoming_value = self.total_outgoing_value = 0.0
|
self.total_incoming_value = self.total_outgoing_value = 0.0
|
||||||
|
@ -8,9 +8,8 @@ import frappe
|
|||||||
from frappe.core.page.permission_manager.permission_manager import reset
|
from frappe.core.page.permission_manager.permission_manager import reset
|
||||||
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
||||||
from frappe.query_builder.functions import CombineDatetime
|
from frappe.query_builder.functions import CombineDatetime
|
||||||
from frappe.tests.utils import FrappeTestCase
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
from frappe.utils import add_days, today
|
from frappe.utils import add_days, add_to_date, flt, today
|
||||||
from frappe.utils.data import add_to_date
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.gl_entry.gl_entry import rename_gle_sle_docs
|
from erpnext.accounts.doctype.gl_entry.gl_entry import rename_gle_sle_docs
|
||||||
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
||||||
@ -1219,6 +1218,41 @@ class TestStockLedgerEntry(FrappeTestCase):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.fail("Double processing of qty for clashing timestamp.")
|
self.fail("Double processing of qty for clashing timestamp.")
|
||||||
|
|
||||||
|
@change_settings("System Settings", {"float_precision": 3, "currency_precision": 2})
|
||||||
|
def test_transfer_invariants(self):
|
||||||
|
"""Extact stock value should be transferred."""
|
||||||
|
|
||||||
|
item = make_item(
|
||||||
|
properties={
|
||||||
|
"valuation_method": "Moving Average",
|
||||||
|
"stock_uom": "Kg",
|
||||||
|
}
|
||||||
|
).name
|
||||||
|
source_warehouse = "Stores - TCP1"
|
||||||
|
target_warehouse = "Finished Goods - TCP1"
|
||||||
|
|
||||||
|
make_purchase_receipt(
|
||||||
|
item=item,
|
||||||
|
warehouse=source_warehouse,
|
||||||
|
qty=20,
|
||||||
|
conversion_factor=1000,
|
||||||
|
uom="Tonne",
|
||||||
|
rate=156_526.0,
|
||||||
|
company="_Test Company with perpetual inventory",
|
||||||
|
)
|
||||||
|
transfer = make_stock_entry(
|
||||||
|
item=item, from_warehouse=source_warehouse, to_warehouse=target_warehouse, qty=1_728.0
|
||||||
|
)
|
||||||
|
|
||||||
|
filters = {"voucher_no": transfer.name, "voucher_type": transfer.doctype, "is_cancelled": 0}
|
||||||
|
sles = frappe.get_all(
|
||||||
|
"Stock Ledger Entry",
|
||||||
|
fields=["*"],
|
||||||
|
filters=filters,
|
||||||
|
order_by="timestamp(posting_date, posting_time), creation",
|
||||||
|
)
|
||||||
|
self.assertEqual(abs(sles[0].stock_value_difference), sles[1].stock_value_difference)
|
||||||
|
|
||||||
|
|
||||||
def create_repack_entry(**args):
|
def create_repack_entry(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user