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 @@ +