From eb969a586661834ef118dd97ff21ccc9d62828b9 Mon Sep 17 00:00:00 2001 From: Sudharsanan11 Date: Fri, 31 Jul 2026 14:41:26 +0530 Subject: [PATCH 1/2] fix: respect quantity precision in material transfer validation --- erpnext/stock/doctype/stock_entry/stock_entry.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index a203ff71db4..ad22e5c3c08 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -1320,9 +1320,11 @@ class StockEntry(StockController, SubcontractingInwardController): first_row_by_item.setdefault(key, item) for key, transfer_qty in transfer_by_item.items(): - pending_qty = max(0.0, pending_by_item[key]) + item = first_row_by_item[key] + precision = item.precision("qty") + transfer_qty = flt(transfer_qty, precision) + pending_qty = max(0.0, flt(pending_by_item[key], precision)) if transfer_qty > pending_qty: - item = first_row_by_item[key] frappe.throw( _( "Row #{0}: Cannot transfer {1} {2} of Item {3}. " From 59bb56aa8d77cb1747fffd1225dfbb799f2b683f Mon Sep 17 00:00:00 2001 From: Sudharsanan11 Date: Fri, 31 Jul 2026 14:41:34 +0530 Subject: [PATCH 2/2] test: cover material transfer quantity precision --- .../doctype/stock_entry/test_stock_entry.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 6c341b62f27..d91ec89d7dd 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -929,6 +929,38 @@ class TestStockEntry(ERPNextTestSuite): fg_cost = next(filter(lambda x: x.item_code == "_Test FG Item 2", stock_entry.get("items"))).amount self.assertEqual(fg_cost, flt(rm_cost + bom_operation_cost + work_order.additional_operating_cost, 2)) + @ERPNextTestSuite.change_settings("System Settings", {"float_precision": 3}) + @ERPNextTestSuite.change_settings("Manufacturing Settings", {"backflush_raw_materials_based_on": "BOM"}) + def test_material_transfer_for_manufacture_qty_precision(self): + work_order = frappe.new_doc("Work Order") + work_order.append( + "required_items", + { + "item_code": "_Test Item", + "required_qty": 33.876, + "transferred_qty": 33.875, + }, + ) + + stock_entry = frappe.new_doc("Stock Entry") + stock_entry.work_order = "Test Work Order" + stock_entry.append( + "items", + { + "item_code": "_Test Item", + "s_warehouse": "_Test Warehouse - _TC", + "qty": 0.001, + "uom": "Nos", + }, + ) + + stock_entry.pro_doc = work_order + stock_entry._validate_no_excess_transfer() + + stock_entry.items[0].qty = 0.002 + with self.assertRaises(frappe.ValidationError): + stock_entry._validate_no_excess_transfer() + @ERPNextTestSuite.change_settings("Manufacturing Settings", {"material_consumption": 1}) def test_work_order_manufacture_with_material_consumption(self): from erpnext.manufacturing.doctype.work_order.work_order import (