From bec627c3eba9bef369b64faadebde23ae3776217 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sat, 12 Sep 2026 06:55:42 +0530 Subject: [PATCH] refactor(manufacturing): rename secondary item valuation type to "% of Component Cost" (#59021) --- erpnext/manufacturing/doctype/bom/bom.js | 2 +- .../manufacturing/doctype/bom/services/costing.py | 2 +- erpnext/manufacturing/doctype/bom/test_bom.py | 6 +++--- .../bom_secondary_item/bom_secondary_item.json | 6 +++--- .../bom_secondary_item/bom_secondary_item.py | 2 +- .../doctype/job_card/test_job_card.py | 6 +++--- .../production_plan/test_production_plan.py | 2 +- .../doctype/work_order/test_work_order.py | 4 ++-- erpnext/patches.txt | 1 + .../v16_0/rename_component_cost_valuation_type.py | 15 +++++++++++++++ erpnext/stock/doctype/stock_entry/stock_entry.js | 2 +- erpnext/stock/doctype/stock_entry/stock_entry.py | 6 +++--- .../stock/doctype/stock_entry/test_stock_entry.py | 12 ++++++------ .../stock_entry_detail/stock_entry_detail.json | 2 +- .../stock_entry_detail/stock_entry_detail.py | 2 +- .../test_subcontracting_receipt.py | 2 +- .../subcontracting_receipt_item.json | 2 +- .../subcontracting_receipt_item.py | 2 +- 18 files changed, 46 insertions(+), 30 deletions(-) create mode 100644 erpnext/patches/v16_0/rename_component_cost_valuation_type.py diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index 7d3f4f0c1dc..4e7a824c955 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -1040,7 +1040,7 @@ frappe.tour["BOM"] = [ frappe.ui.form.on("BOM Secondary Item", { valuation_type(frm, cdt, cdn) { const row = locals[cdt][cdn]; - if (row.valuation_type !== "% of FG Cost") { + if (row.valuation_type !== "% of Component Cost") { frappe.model.set_value(cdt, cdn, "cost_allocation_per", 0); } if (row.valuation_type === "Valuation Rate") { diff --git a/erpnext/manufacturing/doctype/bom/services/costing.py b/erpnext/manufacturing/doctype/bom/services/costing.py index b86cd9e5663..f23b763b41a 100644 --- a/erpnext/manufacturing/doctype/bom/services/costing.py +++ b/erpnext/manufacturing/doctype/bom/services/costing.py @@ -269,7 +269,7 @@ class BOMCostingService: def calculate_secondary_items_costs(self, save=False): """Valuation Rate and Manual rows carry their own cost, deducted from the raw - material cost; the % of FG Cost rows split the remainder by their percentage.""" + material cost; the % of Component Cost rows split the remainder by their percentage.""" total_sm_cost = 0 base_total_sm_cost = 0 precision = self.doc.precision("raw_material_cost") diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py index afdd89fc0ac..6a32c5a18a0 100644 --- a/erpnext/manufacturing/doctype/bom/test_bom.py +++ b/erpnext/manufacturing/doctype/bom/test_bom.py @@ -610,7 +610,7 @@ class TestBOM(ERPNextTestSuite): "secondary_item_type": "Additional Finished Good", "qty": 1, "cost_allocation_per": 10, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", }, ) @@ -645,7 +645,7 @@ class TestBOM(ERPNextTestSuite): "secondary_item_type": "Scrap", "qty": 1, "cost_allocation_per": 10, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", }, ) self.assertRaises(frappe.ValidationError, bom_doc.save) @@ -718,7 +718,7 @@ class TestBOM(ERPNextTestSuite): "secondary_item_type": "By-Product", "qty": 1, "cost_allocation_per": 10, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", }, ) bom_doc.save() diff --git a/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json b/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json index 9f740752a72..40daf1fcc78 100644 --- a/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json +++ b/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json @@ -138,7 +138,7 @@ }, { "default": "0", - "depends_on": "eval:doc.valuation_type == '% of FG Cost'", + "depends_on": "eval:doc.valuation_type == '% of Component Cost'", "fieldname": "cost_allocation_per", "fieldtype": "Percent", "label": "Cost Allocation %", @@ -178,11 +178,11 @@ }, { "default": "Valuation Rate", - "description": "Valuation Rate and Manual value this item on its own and deduct that cost from the raw material cost, like the pre-v16 scrap items. % of FG Cost allocates a percentage of the remaining raw material cost.", + "description": "Valuation Rate and Manual value this item on its own and deduct that cost from the raw material cost, like the pre-v16 scrap items. % of Component Cost allocates a percentage of the remaining raw material cost.", "fieldname": "valuation_type", "fieldtype": "Select", "label": "Valuation Type", - "options": "Valuation Rate\n% of FG Cost\nManual", + "options": "Valuation Rate\n% of Component Cost\nManual", "reqd": 1, "show_description_on_click": 1 }, diff --git a/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.py b/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.py index ec2f72247ac..a5fc82dfbd5 100644 --- a/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.py +++ b/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.py @@ -32,7 +32,7 @@ class BOMSecondaryItem(Document): stock_qty: DF.Float stock_uom: DF.Link | None uom: DF.Link - valuation_type: DF.Literal["Valuation Rate", "% of FG Cost", "Manual"] + valuation_type: DF.Literal["Valuation Rate", "% of Component Cost", "Manual"] # end: auto-generated types pass diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.py b/erpnext/manufacturing/doctype/job_card/test_job_card.py index 414f8e67b25..2aca30c2296 100644 --- a/erpnext/manufacturing/doctype/job_card/test_job_card.py +++ b/erpnext/manufacturing/doctype/job_card/test_job_card.py @@ -1497,7 +1497,7 @@ class TestJobCard(ERPNextTestSuite): "qty": 1, "process_loss_per": 10, "cost_allocation_per": 5, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", "secondary_item_type": "Scrap", }, ) @@ -2956,7 +2956,7 @@ class TestJobCard(ERPNextTestSuite): "secondary_item_type": "Scrap", "qty": 1, "cost_allocation_per": cost_allocation_per, - "valuation_type": "% of FG Cost" if cost_allocation_per else "Valuation Rate", + "valuation_type": "% of Component Cost" if cost_allocation_per else "Valuation Rate", }, ) bom_doc.save() @@ -3012,7 +3012,7 @@ class TestJobCard(ERPNextTestSuite): self.assertEqual(rows[bom_links[0]].qty, 2) self.assertEqual(rows[bom_links[0]].valuation_type, "Valuation Rate") self.assertEqual(rows[bom_links[1]].qty, 3) - self.assertEqual(rows[bom_links[1]].valuation_type, "% of FG Cost") + self.assertEqual(rows[bom_links[1]].valuation_type, "% of Component Cost") @ERPNextTestSuite.change_settings( "Manufacturing Settings", {"overproduction_percentage_for_work_order": 100} diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py index 0561a7777ba..de6caf51a54 100644 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py @@ -4098,7 +4098,7 @@ def make_bom(**args): "stock_uom": item_doc.stock_uom, "qty": args.scrap_qty or 1, "cost_allocation_per": args.scrap_cost_allocation_per or 10, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", "process_loss_per": args.scrap_process_loss_per or 10, }, ) diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py index ba6f5ee165a..b4f504f1adc 100644 --- a/erpnext/manufacturing/doctype/work_order/test_work_order.py +++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py @@ -5403,7 +5403,7 @@ class TestWorkOrder(ERPNextTestSuite): "item_name": scrap_item, "qty": 3, "cost_allocation_per": 25, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", "process_loss_per": 0, }, ) @@ -5452,7 +5452,7 @@ class TestWorkOrder(ERPNextTestSuite): "item_name": scrap_item, "qty": 3, "cost_allocation_per": 25, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", "process_loss_per": 0, }, ) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 788f15bdea9..9a493df32b1 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -522,3 +522,4 @@ erpnext.patches.v16_0.append_fieldname_to_pos_search_fields erpnext.patches.v16_0.set_supplier_quotation_order_status erpnext.patches.v16_0.recalculate_holiday_list_totals erpnext.patches.v16_0.recalculate_returned_delivery_note_billing_status +erpnext.patches.v16_0.rename_component_cost_valuation_type diff --git a/erpnext/patches/v16_0/rename_component_cost_valuation_type.py b/erpnext/patches/v16_0/rename_component_cost_valuation_type.py new file mode 100644 index 00000000000..f2c980a17fc --- /dev/null +++ b/erpnext/patches/v16_0/rename_component_cost_valuation_type.py @@ -0,0 +1,15 @@ +import frappe + +DOCTYPES = ("BOM Secondary Item", "Stock Entry Detail", "Subcontracting Receipt Item") + + +def execute(): + """Rename the `% of FG Cost` valuation type: the percentage is of the component cost.""" + for doctype in DOCTYPES: + frappe.db.set_value( + doctype, + {"valuation_type": "% of FG Cost"}, + "valuation_type", + "% of Component Cost", + update_modified=False, + ) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 1bbcf569f60..23a4d31a6b6 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -291,7 +291,7 @@ frappe.ui.form.on("Stock Entry", { frm.trigger("toggle_weight_per_piece"); // only BOM-less rows are editable, and they cannot allocate a BOM percentage; - // read-only rows from a BOM still display their stored % of FG Cost + // read-only rows from a BOM still display their stored % of Component Cost frm.fields_dict.items.grid.update_docfield_property("valuation_type", "options", [ "Valuation Rate", "Manual", diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 9c234bd9d30..ad24efa914d 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -808,7 +808,7 @@ class StockEntry(StockController, SubcontractingInwardController): def set_bomless_secondary_valuation_types(self): """Secondary rows without a BOM link choose their own costing: valuation rate or manual. - There is no percentage to allocate without a BOM row, so % of FG Cost is rejected.""" + There is no percentage to allocate without a BOM row, so % of Component Cost is rejected.""" for d in self.get("items"): if d.bom_secondary_item: continue @@ -819,10 +819,10 @@ class StockEntry(StockController, SubcontractingInwardController): d.set_basic_rate_manually = 0 continue - if d.valuation_type == "% of FG Cost": + if d.valuation_type == "% of Component Cost": frappe.throw( _( - "Row #{0}: % of FG Cost needs a BOM secondary item. Choose Valuation Rate or Manual for {1}." + "Row #{0}: % of Component Cost needs a BOM secondary item. Choose Valuation Rate or Manual for {1}." ).format(d.idx, frappe.bold(d.item_code)) ) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index b96b9750ef0..6edd798901b 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -1362,7 +1362,7 @@ class TestStockEntry(ERPNextTestSuite): "secondary_item_type": "By-Product", "qty": 1, "cost_allocation_per": 10, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", }, ) bom_doc.save() @@ -1446,7 +1446,7 @@ class TestStockEntry(ERPNextTestSuite): "secondary_item_type": "By-Product", "qty": 1, "cost_allocation_per": 10, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", }, ) bom_doc.save() @@ -1660,7 +1660,7 @@ class TestStockEntry(ERPNextTestSuite): self.assertEqual(fg_row.basic_amount, 830) # there is no percentage to allocate without a BOM row - manual_row.valuation_type = "% of FG Cost" + manual_row.valuation_type = "% of Component Cost" self.assertRaises(frappe.ValidationError, entry.save) def test_valuation_rate_lookup_without_voucher_no(self): @@ -3658,7 +3658,7 @@ class TestStockEntry(ERPNextTestSuite): "qty": 5, "cost_allocation_per": 25, "process_loss_per": 0, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", }, ) bom.insert() @@ -3720,7 +3720,7 @@ class TestStockEntry(ERPNextTestSuite): "qty": 5, "cost_allocation_per": 0, "process_loss_per": 0, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", }, ) bom.insert() @@ -3777,7 +3777,7 @@ class TestStockEntry(ERPNextTestSuite): "qty": 5, "cost_allocation_per": 25, "process_loss_per": 0, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", }, ) bom.insert() diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json index c4bed814be6..0afac79d4c6 100644 --- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json +++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json @@ -693,7 +693,7 @@ "fieldname": "valuation_type", "fieldtype": "Select", "label": "Valuation Type", - "options": "\nValuation Rate\n% of FG Cost\nManual", + "options": "\nValuation Rate\n% of Component Cost\nManual", "read_only_depends_on": "eval:!doc.secondary_item_type || doc.bom_secondary_item" } ], diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py index 5d3cbbd630d..338d1f43f0a 100644 --- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py +++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.py @@ -80,7 +80,7 @@ class StockEntryDetail(Document): transferred_qty: DF.Float secondary_item_type: DF.Literal["", "Co-Product", "By-Product", "Scrap", "Additional Finished Good"] uom: DF.Link - valuation_type: DF.Literal["", "Valuation Rate", "% of FG Cost", "Manual"] + valuation_type: DF.Literal["", "Valuation Rate", "% of Component Cost", "Manual"] use_serial_batch_fields: DF.Check valuation_rate: DF.Currency # end: auto-generated types diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py index d9897c9af44..a86faa7e91c 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py @@ -1251,7 +1251,7 @@ class TestSubcontractingReceipt(ERPNextTestSuite): "item_code": percentage_item, "secondary_item_type": "Co-Product", "stock_qty": 1, - "valuation_type": "% of FG Cost", + "valuation_type": "% of Component Cost", "cost_allocation_per": 10, }, ) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json index 61dce1d4e7b..fdbf244ee29 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json +++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json @@ -645,7 +645,7 @@ "fieldname": "valuation_type", "fieldtype": "Select", "label": "Valuation Type", - "options": "\nValuation Rate\n% of FG Cost\nManual", + "options": "\nValuation Rate\n% of Component Cost\nManual", "read_only": 1 }, { diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py index 46c710afb48..03da2a50f5f 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py @@ -64,7 +64,7 @@ class SubcontractingReceiptItem(Document): subcontracting_receipt_item: DF.Data | None secondary_item_type: DF.Literal["", "Co-Product", "By-Product", "Scrap", "Additional Finished Good"] use_serial_batch_fields: DF.Check - valuation_type: DF.Literal["", "Valuation Rate", "% of FG Cost", "Manual"] + valuation_type: DF.Literal["", "Valuation Rate", "% of Component Cost", "Manual"] warehouse: DF.Link | None # end: auto-generated types