fix: preserve inventory dimensions when raw materials are reset (backport #54440) (backport #54493) (#54513)

* fix: preserve inventory dimensions when raw materials are reset (backport #54440) (#54493)

fix: preserve inventory dimensions when raw materials are reset (#54440)

* fix: preserve inventory dimensions when raw materials are reset

* test: add test case

(cherry picked from commit 0e20e35842)

Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
(cherry picked from commit 456e99b352)

# Conflicts:
#	erpnext/patches.txt

* chore: resolve conflicts

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
This commit is contained in:
mergify[bot]
2026-04-24 12:33:34 +00:00
committed by GitHub
parent c99b9e1b64
commit 610735d1c5
7 changed files with 115 additions and 5 deletions

View File

@@ -435,6 +435,12 @@ frappe.ui.form.on("Subcontracting Receipt Item", {
set_missing_values(frm);
},
before_items_remove(frm, cdt, cdn) {
const filtered_rows = frm.doc.supplied_items.filter((item) => item.reference_name !== cdn);
frm.doc.supplied_items = filtered_rows;
frm.refresh_field("supplied_items");
},
items_delete(frm) {
set_missing_values(frm);
},

View File

@@ -15,6 +15,7 @@ from erpnext.buying.utils import check_on_hold_or_closed_status
from erpnext.controllers.subcontracting_controller import SubcontractingController
from erpnext.setup.doctype.brand.brand import get_brand_defaults
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
from erpnext.stock.doctype.item.item import get_item_defaults
from erpnext.stock.get_item_details import get_default_cost_center, get_default_expense_account
from erpnext.stock.stock_ledger import get_valuation_rate
@@ -119,6 +120,7 @@ class SubcontractingReceipt(SubcontractingController):
)
def before_validate(self):
self.save_inventory_dimensions()
super().before_validate()
self.validate_items_qty()
self.set_items_bom()
@@ -159,6 +161,7 @@ class SubcontractingReceipt(SubcontractingController):
self.set_supplied_items_expense_account()
self.set_supplied_items_cost_center()
self.set_supplied_items_inventory_dimensions()
def on_submit(self):
self.validate_closed_subcontracting_order()
@@ -312,6 +315,22 @@ class SubcontractingReceipt(SubcontractingController):
self.company,
)
def set_supplied_items_inventory_dimensions(self):
if hasattr(self, "inventory_dimensions") and (inventory_dimensions := get_inventory_dimensions()):
for item in self.supplied_items:
key = (
item.reference_name,
item.rm_item_code,
item.main_item_code,
item.batch_no,
item.serial_no,
)
for dimension in inventory_dimensions:
dimension_values = self.inventory_dimensions.get(dimension.source_fieldname, {})
if key in dimension_values:
item.set(dimension.source_fieldname, dimension_values[key])
def set_supplied_items_expense_account(self):
for item in self.supplied_items:
if not item.expense_account:
@@ -328,6 +347,19 @@ class SubcontractingReceipt(SubcontractingController):
get_brand_defaults(item.rm_item_code, self.company),
)
def save_inventory_dimensions(self):
if inventory_dimensions := get_inventory_dimensions():
if not getattr(self, "inventory_dimensions", None):
self.inventory_dimensions = {}
for dimension in inventory_dimensions:
self.inventory_dimensions[dimension.source_fieldname] = {
(d.reference_name, d.rm_item_code, d.main_item_code, d.batch_no, d.serial_no): d.get(
dimension.source_fieldname
)
for d in self.supplied_items
}
def reset_supplied_items(self):
if (
frappe.db.get_single_value("Buying Settings", "backflush_raw_materials_of_subcontract_based_on")

View File

@@ -2036,6 +2036,47 @@ class TestSubcontractingReceipt(ERPNextTestSuite):
scr.submit()
frappe.flags["args"].pop("items", None)
def test_inventory_dimensions(self):
"""
The subcontracting controller resets the supplied items table on each save causing the inventory dimensions to be lost.
This test ensures that the inventory dimensions are retained on each save.
"""
from erpnext.stock.doctype.inventory_dimension.test_inventory_dimension import (
create_inventory_dimension,
)
inventory_dimension = create_inventory_dimension(
apply_to_all_doctypes=1,
dimension_name="Inv Site",
reference_document="Inv Site",
document_type="Inv Site",
)
inventory_dimension.reqd = 1
inventory_dimension.save()
set_backflush_based_on("BOM")
sco = get_subcontracting_order()
rm_items = get_rm_items(sco.supplied_items)
itemwise_details = make_stock_in_entry(rm_items=rm_items)
make_stock_transfer_entry(
sco_no=sco.name,
rm_items=rm_items,
itemwise_details=copy.deepcopy(itemwise_details),
)
scr = make_subcontracting_receipt(sco.name)
scr.items[0].inv_site = "Site 1"
scr.save()
scr.supplied_items[0].inv_site = "Site 1"
scr.save()
self.assertEqual(scr.supplied_items[0].inv_site, "Site 1")
inventory_dimension.reqd = 0
inventory_dimension.save()
def make_return_subcontracting_receipt(**args):
args = frappe._dict(args)