diff --git a/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py b/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py index 8e882288..80e9e11b 100644 --- a/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py +++ b/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Fusion Plating — MRP Bridge", - 'version': '19.0.6.9.0', + 'version': '19.0.6.10.0', 'category': 'Manufacturing/Plating', 'summary': 'Bridge Fusion Plating facilities, baths and tanks to Odoo MRP work orders.', 'description': """ diff --git a/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py b/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py index 0caf28db..158630e8 100644 --- a/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py +++ b/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py @@ -131,10 +131,103 @@ class MrpProduction(models.Model): compute='_compute_consumption_count', ) + # Smart-button companions: source SO, WO count, receiving count. + # Surfaced on the MO form so operators / managers can jump back to + # the originating sale order, drill into the WO list, or inspect + # the receiving record without hunting through menus. + x_fc_sale_order_id = fields.Many2one( + 'sale.order', string='Source SO', + compute='_compute_sale_order_id', store=False, + help='The sale order this MO was created from (resolved via ' + 'mo.origin → sale.order.name).', + ) + x_fc_workorder_count = fields.Integer( + string='# Work Orders', + compute='_compute_workorder_count', + ) + x_fc_receiving_count = fields.Integer( + string='# Receiving', + compute='_compute_receiving_count', + ) + def _compute_consumption_count(self): for mo in self: mo.x_fc_consumption_count = len(mo.x_fc_consumption_ids) + @api.depends('origin') + def _compute_sale_order_id(self): + SO = self.env['sale.order'] + for mo in self: + mo.x_fc_sale_order_id = ( + SO.search([('name', '=', mo.origin)], limit=1) + if mo.origin else False + ) + + @api.depends('workorder_ids') + def _compute_workorder_count(self): + for mo in self: + mo.x_fc_workorder_count = len(mo.workorder_ids) + + def _compute_receiving_count(self): + Recv = self.env.get('fp.receiving') + for mo in self: + if Recv is None or not mo.x_fc_sale_order_id: + mo.x_fc_receiving_count = 0 + continue + mo.x_fc_receiving_count = Recv.search_count( + [('sale_order_id', '=', mo.x_fc_sale_order_id.id)] + ) + + def action_view_sale_order(self): + self.ensure_one() + if not self.x_fc_sale_order_id: + return False + return { + 'type': 'ir.actions.act_window', + 'name': _('Sale Order'), + 'res_model': 'sale.order', + 'res_id': self.x_fc_sale_order_id.id, + 'view_mode': 'form', + 'target': 'current', + } + + def action_view_workorders(self): + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'name': _('Work Orders — %s') % self.name, + 'res_model': 'mrp.workorder', + 'view_mode': 'list,form', + 'domain': [('production_id', '=', self.id)], + 'context': {'default_production_id': self.id, + 'search_default_production_id': self.id}, + 'target': 'current', + } + + def action_view_receiving(self): + self.ensure_one() + Recv = self.env.get('fp.receiving') + if Recv is None or not self.x_fc_sale_order_id: + return False + recvs = Recv.search([('sale_order_id', '=', self.x_fc_sale_order_id.id)]) + if len(recvs) == 1: + return { + 'type': 'ir.actions.act_window', + 'name': _('Receiving — %s') % recvs.name, + 'res_model': 'fp.receiving', + 'res_id': recvs.id, + 'view_mode': 'form', + 'target': 'current', + } + return { + 'type': 'ir.actions.act_window', + 'name': _('Receiving for %s') % self.x_fc_sale_order_id.name, + 'res_model': 'fp.receiving', + 'view_mode': 'list,form', + 'domain': [('sale_order_id', '=', self.x_fc_sale_order_id.id)], + 'target': 'current', + } + @api.depends( 'x_fc_consumption_ids.total_cost', 'workorder_ids.duration', diff --git a/fusion_plating/fusion_plating_bridge_mrp/views/mrp_production_views.xml b/fusion_plating/fusion_plating_bridge_mrp/views/mrp_production_views.xml index b6e7ce3b..6ed31fcf 100644 --- a/fusion_plating/fusion_plating_bridge_mrp/views/mrp_production_views.xml +++ b/fusion_plating/fusion_plating_bridge_mrp/views/mrp_production_views.xml @@ -64,6 +64,30 @@ + + + + + +