mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-12 06:01:46 +00:00
fix: disallow BOM finished good item in secondary items table (#55710)
The FG item produced by a BOM should not also appear as a secondary item (Co-Product/By-Product/Scrap/Additional Finished Good). When an Additional Finished Good shared the main FG's item code, the resulting Stock Entry ended up with two rows of the same item carrying different valuation rates. Validate against it instead, exempting legacy rows so migrated BOMs can still be re-saved. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -366,6 +366,13 @@ class BOM(WebsiteGenerator):
|
||||
|
||||
def validate_secondary_items(self):
|
||||
for item in self.secondary_items:
|
||||
if not item.is_legacy and item.item_code == self.item:
|
||||
frappe.throw(
|
||||
_(
|
||||
"Row #{0}: Finished Good Item {1} cannot be added in the Secondary Items table."
|
||||
).format(item.idx, get_link_to_form("Item", item.item_code))
|
||||
)
|
||||
|
||||
if not item.qty:
|
||||
frappe.throw(
|
||||
_("Row #{0}: Quantity should be greater than 0 for {1} Item {2}").format(
|
||||
|
||||
@@ -444,6 +444,30 @@ class TestBOM(ERPNextTestSuite):
|
||||
# Items with whole UOMs can't be PL Items
|
||||
self.assertRaises(frappe.ValidationError, bom_doc.submit)
|
||||
|
||||
@timeout
|
||||
def test_fg_item_not_allowed_in_secondary_items(self):
|
||||
fg_item = make_item(properties={"is_stock_item": 1, "valuation_rate": 100}).name
|
||||
rm_item = make_item(properties={"is_stock_item": 1, "valuation_rate": 100}).name
|
||||
|
||||
bom_doc = frappe.new_doc("BOM")
|
||||
bom_doc.item = fg_item
|
||||
bom_doc.quantity = 1
|
||||
bom_doc.company = "_Test Company"
|
||||
bom_doc.currency = "INR"
|
||||
bom_doc.append("items", {"item_code": rm_item, "qty": 1, "rate": 100.0})
|
||||
bom_doc.append(
|
||||
"secondary_items",
|
||||
{
|
||||
"item_code": fg_item,
|
||||
"secondary_item_type": "Additional Finished Good",
|
||||
"qty": 1,
|
||||
"cost_allocation_per": 10,
|
||||
},
|
||||
)
|
||||
|
||||
# FG item of the BOM cannot also be a secondary item
|
||||
self.assertRaises(frappe.ValidationError, bom_doc.save)
|
||||
|
||||
@timeout
|
||||
def test_bom_item_query(self):
|
||||
query = partial(
|
||||
|
||||
Reference in New Issue
Block a user