diff --git a/fusion_plating/fusion_plating_configurator/__manifest__.py b/fusion_plating/fusion_plating_configurator/__manifest__.py index c5d57cae..9b1d7d28 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.7.0.0', + 'version': '19.0.7.1.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/models/sale_order.py b/fusion_plating/fusion_plating_configurator/models/sale_order.py index 988a54db..25b8a568 100644 --- a/fusion_plating/fusion_plating_configurator/models/sale_order.py +++ b/fusion_plating/fusion_plating_configurator/models/sale_order.py @@ -119,6 +119,46 @@ class SaleOrder(models.Model): compute='_compute_workorder_count', ) + # ---- Phase E: list view helpers ---- + x_fc_wo_completion = fields.Char( + string='WO Progress', + compute='_compute_wo_completion', + help='Ratio of completed work orders, shown as "3/5 done".', + ) + x_fc_invoiced_amount = fields.Monetary( + string='Invoiced', + compute='_compute_invoiced_amount', + currency_field='currency_id', + ) + + def _compute_wo_completion(self): + WO = self.env['mrp.workorder'].sudo() + for rec in self: + if not rec.name: + rec.x_fc_wo_completion = '0/0' + continue + total = WO.search_count([('production_id.origin', '=', rec.name)]) + done = WO.search_count([ + ('production_id.origin', '=', rec.name), + ('state', '=', 'done'), + ]) + rec.x_fc_wo_completion = '%d/%d' % (done, total) if total else '0/0' + + @api.depends('invoice_ids.amount_total', 'invoice_ids.state', + 'invoice_ids.move_type') + def _compute_invoiced_amount(self): + for rec in self: + posted = rec.invoice_ids.filtered( + lambda m: m.state == 'posted' and m.move_type == 'out_invoice' + ) + refunds = rec.invoice_ids.filtered( + lambda m: m.state == 'posted' and m.move_type == 'out_refund' + ) + rec.x_fc_invoiced_amount = ( + sum(posted.mapped('amount_total')) + - sum(refunds.mapped('amount_total')) + ) + def _compute_workorder_count(self): WO = self.env['mrp.workorder'].sudo() for rec in self: 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 271e5cde..3c0d1438 100644 --- a/fusion_plating/fusion_plating_configurator/views/sale_order_views.xml +++ b/fusion_plating/fusion_plating_configurator/views/sale_order_views.xml @@ -153,19 +153,68 @@ + + + + + + + + + sale.order.search.fp + sale.order + + + + + + + + + + + + + + + + + + + + + + + + Quotations