diff --git a/fusion_plating/fusion_plating_configurator/models/fp_part_catalog.py b/fusion_plating/fusion_plating_configurator/models/fp_part_catalog.py
index cf2049ee..c2e6b0cc 100644
--- a/fusion_plating/fusion_plating_configurator/models/fp_part_catalog.py
+++ b/fusion_plating/fusion_plating_configurator/models/fp_part_catalog.py
@@ -131,6 +131,21 @@ class FpPartCatalog(models.Model):
notes = fields.Html(string='Notes')
active = fields.Boolean(string='Active', default=True)
+ # ---- Direct-order defaults (Phase C — C4) ----
+ x_fc_default_coating_config_id = fields.Many2one(
+ 'fp.coating.config',
+ string='Default Treatment',
+ help='Default coating applied when this part is dropped onto a '
+ 'direct order line. Updated when "Save as Default" is ticked.',
+ )
+ x_fc_default_treatment_ids = fields.Many2many(
+ 'fp.treatment',
+ relation='fp_part_catalog_default_treatment_rel',
+ string='Default Additional Treatments',
+ help='Default additional treatments. Seeded when "Save as Default" '
+ 'is ticked on a direct order line.',
+ )
+
# Substrate density mapping (g/cm³) for material weight calculation
_SUBSTRATE_DENSITY = {
'aluminium': 2.70,
diff --git a/fusion_plating/fusion_plating_configurator/views/fp_part_catalog_views.xml b/fusion_plating/fusion_plating_configurator/views/fp_part_catalog_views.xml
index 488f960f..d0bc4b48 100644
--- a/fusion_plating/fusion_plating_configurator/views/fp_part_catalog_views.xml
+++ b/fusion_plating/fusion_plating_configurator/views/fp_part_catalog_views.xml
@@ -224,6 +224,20 @@
+
+
+
+
+
+
+ Seeds the treatment fields on new direct-order
+ lines. Updated whenever "Save as Default" is
+ ticked while placing an order.
+
+
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 d60bf854..a37edd9b 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
@@ -103,6 +103,11 @@ class FpDirectOrderLine(models.TransientModel):
help='Do not save this as a reusable part in the catalog after the '
'order is created. Useful for quote-only or prototype parts.',
)
+ push_to_defaults = fields.Boolean(
+ string='Save as Default',
+ help='After submit, write this line\'s coating + additional '
+ 'treatments back onto the part catalog as its new defaults.',
+ )
# ---- Description ----
description_template_id = fields.Many2one(
@@ -138,6 +143,16 @@ class FpDirectOrderLine(models.TransientModel):
)
# ---- Onchange ----
+ @api.onchange('part_catalog_id')
+ def _onchange_part_defaults(self):
+ """When a part is picked, seed coating + treatments from its catalog defaults."""
+ if not self.part_catalog_id:
+ return
+ if not self.coating_config_id and self.part_catalog_id.x_fc_default_coating_config_id:
+ self.coating_config_id = self.part_catalog_id.x_fc_default_coating_config_id
+ if not self.treatment_ids and self.part_catalog_id.x_fc_default_treatment_ids:
+ self.treatment_ids = self.part_catalog_id.x_fc_default_treatment_ids
+
@api.onchange('coating_config_id', 'quantity', 'part_catalog_id')
def _onchange_lookup_price(self):
"""Auto-fill unit_price from customer price list when available."""
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 2a64740d..c1bb5204 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
@@ -251,6 +251,20 @@ class FpDirectOrderWizard(models.TransientModel):
# 5. Create + confirm
so = self.env['sale.order'].create(so_vals)
so.action_confirm()
+
+ # 6. Push-to-defaults (C4) — after the part has been resolved /
+ # revision-bumped, write coating + treatments back onto the part
+ # catalog entry so the next order inherits the same defaults.
+ for line in self.line_ids:
+ if not line.push_to_defaults:
+ continue
+ part = line.part_catalog_id
+ if not part or line.is_one_off:
+ continue
+ part.write({
+ 'x_fc_default_coating_config_id': line.coating_config_id.id or False,
+ 'x_fc_default_treatment_ids': [(6, 0, line.treatment_ids.ids)],
+ })
so.message_post(body=_(
'Direct order created from PO %s with %d line(s). '
'Quotation stage skipped.'
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 ac2717d0..d79f4929 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
@@ -156,6 +156,8 @@
+