From 43a26b6849a559b8d96be2d9a5f7724e733205da Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sun, 19 Apr 2026 21:01:25 -0400 Subject: [PATCH] =?UTF-8?q?feat(configurator):=20Phase=20C=20polish=20?= =?UTF-8?q?=E2=80=94=20to-node=20picker,=20WO=20description,=20one-off=20f?= =?UTF-8?q?lag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C1: start_at_node_id per wizard line, mirrors to x_fc_start_at_node_id on sale.order.line. Domain filters to nodes descending from the coating_config's recipe so the estimator only picks valid resume points. bridge_mrp will use this in a follow-up to skip ancestor steps in the generated work order. C2: part_wo_description (separate from customer-facing line_description) lets the planner add internal-only notes that appear on the travelling sheet only. Mirrors to x_fc_part_wo_description on sale.order.line. C5: is_one_off flag for prototype / non-catalog parts. Mirrors to x_fc_is_one_off. Actual skip-catalog behaviour will be wired in a later pass. All three fields appear in the wizard line drill-in form (under a new "Work Order (internal)" group) and as togglable columns on the sale.order.line tree. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../models/sale_order_line.py | 16 ++++++++++++++++ .../views/sale_order_views.xml | 2 ++ .../wizard/fp_direct_order_line.py | 19 +++++++++++++++++++ .../wizard/fp_direct_order_wizard.py | 3 +++ .../wizard/fp_direct_order_wizard_views.xml | 8 ++++++++ 5 files changed, 48 insertions(+) diff --git a/fusion_plating/fusion_plating_configurator/models/sale_order_line.py b/fusion_plating/fusion_plating_configurator/models/sale_order_line.py index 408663c6..81225030 100644 --- a/fusion_plating/fusion_plating_configurator/models/sale_order_line.py +++ b/fusion_plating/fusion_plating_configurator/models/sale_order_line.py @@ -25,3 +25,19 @@ class SaleOrderLine(models.Model): help='Lines sharing a tag (e.g. "WO#1") will be batched into one ' 'manufacturing order when bridge_mrp generates MOs.', ) + x_fc_part_wo_description = fields.Text( + string='On Work Order', + help='Extra detail printed on the work order travelling sheet. ' + 'Separate from the customer-facing line description.', + ) + x_fc_start_at_node_id = fields.Many2one( + 'fusion.plating.process.node', + string='Start at Node', + help='For re-work jobs: pick the recipe step where this job ' + 'should begin. bridge_mrp skips ancestor steps.', + ) + x_fc_is_one_off = fields.Boolean( + string='One-off Part', + help='Flag for prototype / non-catalog parts that should not be ' + 'reused after this order.', + ) diff --git a/fusion_plating/fusion_plating_configurator/views/sale_order_views.xml b/fusion_plating/fusion_plating_configurator/views/sale_order_views.xml index 4802b3e5..9430010e 100644 --- a/fusion_plating/fusion_plating_configurator/views/sale_order_views.xml +++ b/fusion_plating/fusion_plating_configurator/views/sale_order_views.xml @@ -101,6 +101,8 @@ + + diff --git a/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_line.py b/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_line.py index d5e8017a..d60bf854 100644 --- a/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_line.py +++ b/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_line.py @@ -85,6 +85,25 @@ class FpDirectOrderLine(models.TransientModel): 'will be batched into one manufacturing order.', ) + # ---- Phase C: polish ---- + part_wo_description = fields.Text( + string='On Work Order', + help='Extra detail printed on the work order travelling sheet. ' + 'Kept separate from the customer-facing description.', + ) + start_at_node_id = fields.Many2one( + 'fusion.plating.process.node', + string='Start at Node', + domain="[('parent_id', 'child_of', coating_config_id and coating_config_id.recipe_id.id)]", + help='For re-work jobs: pick the recipe step where this job should ' + 'begin. Skips ancestor steps in the generated work order.', + ) + is_one_off = fields.Boolean( + string='One-off Part', + help='Do not save this as a reusable part in the catalog after the ' + 'order is created. Useful for quote-only or prototype parts.', + ) + # ---- Description ---- description_template_id = fields.Many2one( 'fp.sale.description.template', diff --git a/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_wizard.py b/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_wizard.py index ccb5db0a..2a64740d 100644 --- a/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_wizard.py +++ b/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_wizard.py @@ -243,6 +243,9 @@ class FpDirectOrderWizard(models.TransientModel): 'x_fc_part_deadline': line.part_deadline, 'x_fc_rush_order': line.rush_order, 'x_fc_wo_group_tag': line.wo_group_tag or False, + 'x_fc_part_wo_description': line.part_wo_description or False, + 'x_fc_start_at_node_id': line.start_at_node_id.id or False, + 'x_fc_is_one_off': line.is_one_off, })) # 5. Create + confirm diff --git a/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_wizard_views.xml b/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_wizard_views.xml index 67950799..ac2717d0 100644 --- a/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_wizard_views.xml +++ b/fusion_plating/fusion_plating_configurator/wizard/fp_direct_order_wizard_views.xml @@ -149,6 +149,14 @@ nolabel="1" colspan="2" placeholder="Pick a template above, then tweak the text here."/> + + + + +