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 81225030..c6e923ee 100644 --- a/fusion_plating/fusion_plating_configurator/models/sale_order_line.py +++ b/fusion_plating/fusion_plating_configurator/models/sale_order_line.py @@ -41,3 +41,8 @@ class SaleOrderLine(models.Model): help='Flag for prototype / non-catalog parts that should not be ' 'reused after this order.', ) + x_fc_quote_id = fields.Many2one( + 'fp.quote.configurator', + string='Linked Quote', + help='Quote that seeded this line. Links back for audit trail.', + ) 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 9430010e..59d01e26 100644 --- a/fusion_plating/fusion_plating_configurator/views/sale_order_views.xml +++ b/fusion_plating/fusion_plating_configurator/views/sale_order_views.xml @@ -103,6 +103,7 @@ + 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 a37edd9b..e0d7a8a3 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 @@ -108,6 +108,13 @@ class FpDirectOrderLine(models.TransientModel): help='After submit, write this line\'s coating + additional ' 'treatments back onto the part catalog as its new defaults.', ) + quote_id = fields.Many2one( + 'fp.quote.configurator', + string='Linked Quote', + domain="[('partner_id', '=', parent.partner_id), ('state', 'in', ['sent','accepted','won'])]", + help='Optional: link this line to a prior quote. The unit price ' + 'auto-fills from the quote\'s final price (or override).', + ) # ---- Description ---- description_template_id = fields.Many2one( @@ -143,6 +150,21 @@ class FpDirectOrderLine(models.TransientModel): ) # ---- Onchange ---- + @api.onchange('quote_id') + def _onchange_quote_id(self): + """Auto-fill part, coating, and unit price from the linked quote.""" + if not self.quote_id: + return + q = self.quote_id + if q.part_catalog_id and not self.part_catalog_id: + self.part_catalog_id = q.part_catalog_id + if q.coating_config_id and not self.coating_config_id: + self.coating_config_id = q.coating_config_id + if not self.unit_price: + final = q.estimator_override_price or q.calculated_price + if final and q.quantity: + self.unit_price = final / q.quantity + @api.onchange('part_catalog_id') def _onchange_part_defaults(self): """When a part is picked, seed coating + treatments from its catalog defaults.""" 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 c1bb5204..939d05c9 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 @@ -246,6 +246,7 @@ class FpDirectOrderWizard(models.TransientModel): '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, + 'x_fc_quote_id': line.quote_id.id or False, })) # 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 d79f4929..3f22533e 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 @@ -118,6 +118,8 @@ widget="many2many_tags"/> +