From e4398d3761668b78a1c8ed1ed4f7ca8cee22ca49 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 (cherry picked from commit bbc772abe7ad6b892e86da6b74d4c72345f21506) # Conflicts: # erpnext/stock/doctype/stock_entry/test_stock_entry.py --- erpnext/controllers/stock_controller.py | 1 + .../doctype/stock_entry/test_stock_entry.py | 134 ++++++++++++++++++ erpnext/stock/serial_batch_bundle.py | 18 ++- 3 files changed, 152 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 2369c39f508..8c2b4db3fc9 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -1854,6 +1854,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 68e57a3d971..042ec6abdf1 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -2021,7 +2021,141 @@ class TestStockEntry(FrappeTestCase): self.assertEqual(se.items[0].basic_rate, 300) +<<<<<<< HEAD def make_serialized_item(**args): +======= + company = "_Test Periodic Accounting Company" + + frappe.get_doc( + { + "doctype": "Company", + "company_name": company, + "abbr": "_TPC", + "default_currency": "INR", + "enable_perpetual_inventory": 0, + } + ).insert(ignore_permissions=True) + + warehouse = frappe.db.get_value("Warehouse", {"company": company, "is_group": 0}, "name") + + make_stock_entry( + item_code=item_code, + qty=10, + to_warehouse=warehouse, + basic_rate=100, + posting_date=add_days(nowdate(), -2), + ) + + jv = frappe.new_doc("Journal Entry") + jv.voucher_type = "Periodic Accounting Entry" + jv.posting_date = add_days(nowdate(), -1) + jv.posting_time = nowtime() + jv.company = company + jv.for_all_stock_asset_accounts = 1 + jv.periodic_entry_difference_account = "Stock Adjustment - _TPC" + jv.get_balance_for_periodic_accounting() + jv.save() + jv.submit() + + self.assertEqual(len(jv.accounts), 2) + self.assertEqual(jv.accounts[0].debit_in_account_currency, 1000) + self.assertEqual(jv.accounts[1].credit_in_account_currency, 1000) + self.assertEqual(jv.accounts[0].account, "Stock In Hand - _TPC") + self.assertEqual(jv.accounts[1].account, "Stock Adjustment - _TPC") + + make_stock_entry( + item_code=item_code, + qty=5, + from_warehouse=warehouse, + company=company, + posting_date=nowdate(), + posting_time=nowtime(), + ) + + jv = frappe.new_doc("Journal Entry") + jv.voucher_type = "Periodic Accounting Entry" + jv.posting_date = nowdate() + jv.posting_time = nowtime() + jv.company = company + jv.for_all_stock_asset_accounts = 1 + jv.periodic_entry_difference_account = "Stock Adjustment - _TPC" + jv.get_balance_for_periodic_accounting() + jv.save() + jv.submit() + + self.assertEqual(len(jv.accounts), 2) + self.assertEqual(jv.accounts[0].credit_in_account_currency, 500) + self.assertEqual(jv.accounts[1].debit_in_account_currency, 500) + 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): +>>>>>>> bbc772abe7 (fix: additional cost not consider in valuation rate for Stock Entry transfer) args = frappe._dict(args) se = frappe.copy_doc(test_records[0]) diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py index 203340a9ff5..172ee4edcf2 100644 --- a/erpnext/stock/serial_batch_bundle.py +++ b/erpnext/stock/serial_batch_bundle.py @@ -185,7 +185,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.db.get_single_value( "Stock Settings", "do_not_update_serial_batch_on_creation_of_auto_bundle"