From bbc772abe7ad6b892e86da6b74d4c72345f21506 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 16 Aug 2025 23:35:27 +0530 Subject: [PATCH] fix: additional cost not consider in valuation rate for Stock Entry transfer --- erpnext/controllers/stock_controller.py | 1 + .../doctype/stock_entry/test_stock_entry.py | 64 +++++++++++++++++++ erpnext/stock/serial_batch_bundle.py | 18 +++++- 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 80b10b9be3a..d114fad7dfe 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -1963,6 +1963,7 @@ def make_bundle_for_material_transfer(**kwargs): row.warehouse = kwargs.warehouse + bundle_doc.set_incoming_rate() bundle_doc.calculate_qty_and_amount() bundle_doc.flags.ignore_permissions = True bundle_doc.flags.ignore_validate = True diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index ef92c5ea2a2..d0143941660 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -2083,6 +2083,70 @@ class TestStockEntry(IntegrationTestCase): self.assertEqual(jv.accounts[0].account, "Stock In Hand - _TPC") self.assertEqual(jv.accounts[1].account, "Stock Adjustment - _TPC") + def test_batch_item_additional_cost_for_material_transfer_entry(self): + item_code = "_Test Batch Item Additional Cost MTE" + make_item( + item_code, + { + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_naming_series": "BT-MTE.#####", + }, + ) + + se = make_stock_entry( + item_code=item_code, + target="_Test Warehouse - _TC", + qty=2, + basic_rate=100, + use_serial_batch_fields=1, + ) + + batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle) + + se = make_stock_entry( + item_code=item_code, + source="_Test Warehouse - _TC", + target="_Test Warehouse 1 - _TC", + batch_no=batch_no, + use_serial_batch_fields=1, + qty=2, + purpose="Material Transfer", + do_not_save=True, + ) + + se.append( + "additional_costs", + { + "cost_center": "Main - _TC", + "amount": 50, + "expense_account": "Stock Adjustment - _TC", + "description": "Test Additional Cost", + }, + ) + se.save() + self.assertEqual(se.additional_costs[0].amount, 50) + self.assertEqual(se.items[0].basic_rate, 100) + self.assertEqual(se.items[0].valuation_rate, 125) + + se.submit() + self.assertEqual(se.items[0].basic_rate, 100) + self.assertEqual(se.items[0].valuation_rate, 125) + + incoming_rate = frappe.db.get_value( + "Stock Ledger Entry", + { + "item_code": item_code, + "warehouse": "_Test Warehouse 1 - _TC", + "voucher_type": "Stock Entry", + "voucher_no": se.name, + }, + "incoming_rate", + ) + + self.assertEqual(incoming_rate, 125.0) + def make_serialized_item(self, **args): args = frappe._dict(args) diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py index e896f0bc8fd..d34b449c819 100644 --- a/erpnext/stock/serial_batch_bundle.py +++ b/erpnext/stock/serial_batch_bundle.py @@ -186,7 +186,23 @@ class SerialBatchBundle: } if self.sle.actual_qty < 0 and self.is_material_transfer(): - values_to_update["valuation_rate"] = flt(sn_doc.avg_rate) + basic_rate = flt(sn_doc.avg_rate) + ste_detail = frappe.db.get_value( + "Stock Entry Detail", + self.sle.voucher_detail_no, + ["additional_cost", "landed_cost_voucher_amount", "transfer_qty"], + as_dict=True, + ) + + additional_cost = 0.0 + + if ste_detail: + additional_cost = ( + flt(ste_detail.additional_cost) + flt(ste_detail.landed_cost_voucher_amount) + ) / flt(ste_detail.transfer_qty) + + values_to_update["basic_rate"] = basic_rate + values_to_update["valuation_rate"] = basic_rate + additional_cost if not frappe.get_single_value( "Stock Settings", "do_not_update_serial_batch_on_creation_of_auto_bundle"