From a1ebe9000fd06d8502a330e5b31b027a6be51e4f Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Wed, 22 Apr 2026 08:46:32 -0400 Subject: [PATCH] =?UTF-8?q?feat(fusion=5Fplating):=20Sub=203=20=E2=80=94?= =?UTF-8?q?=20process=5Fnode=20gets=20part=5Fcatalog=5Fid,=20cloned=5Ffrom?= =?UTF-8?q?=5Fid,=20treatment=5Fuom;=20opt=5Fin=5Fout=20label=20rename=20(?= =?UTF-8?q?Task=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fusion_plating/models/fp_process_node.py | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/fusion_plating/fusion_plating/models/fp_process_node.py b/fusion_plating/fusion_plating/models/fp_process_node.py index e5be8016..d51d745c 100644 --- a/fusion_plating/fusion_plating/models/fp_process_node.py +++ b/fusion_plating/fusion_plating/models/fp_process_node.py @@ -172,9 +172,9 @@ class FpProcessNode(models.Model): ) opt_in_out = fields.Selection( [ - ('disabled', 'Disabled'), - ('opt_in', 'Opt-In'), - ('opt_out', 'Opt-Out'), + ('disabled', 'Always Included'), + ('opt_out', 'Included by Default'), + ('opt_in', 'Excluded by Default'), ], string='Opt In/Out', default='disabled', @@ -199,6 +199,39 @@ class FpProcessNode(models.Model): tracking=True, ) + # ---- Part ownership & provenance (Sub 3) -------------------------------- + + # Sub 3 — part ownership. NULL on shared templates (admin-managed); + # populated on every node in a part's cloned tree. + part_catalog_id = fields.Many2one( + 'fp.part.catalog', + string='Part', + ondelete='cascade', + index=True, + help='Populated on nodes that belong to a specific part\'s ' + 'composed process tree. NULL on shared templates.', + ) + # Sub 3 — source-template reference on cloned nodes. Enables + # future "template drifted" indicators. Optional, not load-bearing. + cloned_from_id = fields.Many2one( + 'fusion.plating.process.node', + string='Cloned From', + ondelete='set null', + help='On a part-cloned node, points back at the source template ' + 'node it was copied from.', + ) + # Sub 3 — per-node treatment UoM for pricing / cost tracking. + treatment_uom = fields.Selection( + [ + ('lbs', 'Lbs (weight-based)'), + ('sq_in', 'Sq in (area-based)'), + ], + string='Treatment UoM', + help='How this process step is measured for costing / pricing. ' + 'Picks which physical property of the part to multiply by ' + 'the per-unit rate: weight (Lbs) or surface area (Sq in).', + ) + # ---- Recipe-only fields (apply when node_type='recipe') ----------------- # These migrate Steelhead's recipe-level metadata: lead time, the # product/service tied to this recipe, the contract review approver