diff --git a/fusion_plating/fusion_plating_configurator/__manifest__.py b/fusion_plating/fusion_plating_configurator/__manifest__.py
index 71dffecc..3bb59aaf 100644
--- a/fusion_plating/fusion_plating_configurator/__manifest__.py
+++ b/fusion_plating/fusion_plating_configurator/__manifest__.py
@@ -5,7 +5,7 @@
{
'name': 'Fusion Plating — Configurator',
- 'version': '19.0.13.1.0',
+ 'version': '19.0.13.2.0',
'category': 'Manufacturing/Plating',
'summary': 'Quotation configurator with part catalog, coating configs, and formula-based pricing engine.',
'description': """
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 2876e019..1233e0ae 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
@@ -59,6 +59,47 @@ class FpDirectOrderLine(models.TransientModel):
string='Additional Treatments',
help='Extra pre/post treatments applied to this line.',
)
+ # Read-only preview of the process tree that WILL drive WO generation
+ # for this line. Resolution priority:
+ # 1. Part's composed process (fp.part.catalog.default_process_id)
+ # — a part-scoped customisation set via the Process Composer.
+ # 2. Primary Treatment's default recipe (fp.coating.config.recipe_id)
+ # — the shared template used if the part has no override.
+ # Shown so operators can see *what will run* before confirming the
+ # order. Treatment answers the "what coating"; process answers the
+ # "how" — they're distinct but coupled via the resolution chain.
+ effective_process_id = fields.Many2one(
+ 'fusion.plating.process.node',
+ string='Process',
+ compute='_compute_effective_process',
+ help='Process tree that will generate work orders for this line. '
+ 'Uses the part-composed process if one exists, otherwise the '
+ "primary treatment's default recipe.",
+ )
+ effective_process_source = fields.Char(
+ compute='_compute_effective_process',
+ help='Tells the estimator whether the process comes from the '
+ 'part (customised) or the coating (shared default).',
+ )
+
+ @api.depends('part_catalog_id.default_process_id',
+ 'coating_config_id.recipe_id')
+ def _compute_effective_process(self):
+ for rec in self:
+ part_proc = (rec.part_catalog_id.default_process_id
+ if rec.part_catalog_id else False)
+ if part_proc:
+ rec.effective_process_id = part_proc
+ rec.effective_process_source = 'Part (customised)'
+ continue
+ cc_proc = (rec.coating_config_id.recipe_id
+ if rec.coating_config_id else False)
+ if cc_proc:
+ rec.effective_process_id = cc_proc
+ rec.effective_process_source = 'Coating default'
+ continue
+ rec.effective_process_id = False
+ rec.effective_process_source = False
# ---- Qty / price ----
quantity = fields.Integer(string='Qty', default=1, required=True)
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 b9884089..8b6da084 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
@@ -106,6 +106,14 @@
+
+
+
+