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..cde5be4d6ee 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -2020,6 +2020,70 @@ class TestStockEntry(FrappeTestCase): self.assertEqual(se.items[0].basic_rate, 300) + 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(**args): args = frappe._dict(args) diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py index 203340a9ff5..21180accf83 100644 --- a/erpnext/stock/serial_batch_bundle.py +++ b/erpnext/stock/serial_batch_bundle.py @@ -185,7 +185,21 @@ 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", "transfer_qty"], + as_dict=True, + ) + + additional_cost = 0.0 + + if ste_detail: + additional_cost = flt(ste_detail.additional_cost) / 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"