# -*- coding: utf-8 -*- from odoo import models, fields, api, _ from odoo.exceptions import UserError class SaleOrder(models.Model): _inherit = 'sale.order' fusion_purchase_count = fields.Integer( string='Purchase', compute='_compute_fusion_purchase_count', ) def _compute_fusion_purchase_count(self): for so in self: so.fusion_purchase_count = self.env['purchase.order'].search_count([ ('fusion_sale_ids', 'in', so.id), ]) def action_view_fusion_purchases(self): purchases = self.env['purchase.order'].search([ ('fusion_sale_ids', 'in', self.id), ]) return { 'name': _('Purchase Orders'), 'view_mode': 'list,form', 'res_model': 'purchase.order', 'domain': [('id', 'in', purchases.ids)], 'type': 'ir.actions.act_window', } class PurchaseOrder(models.Model): _inherit = 'purchase.order' fusion_sale_ids = fields.Many2many( 'sale.order', 'fusion_po_so_rel', 'purchase_order_id', 'sale_order_id', string='Sale Orders', help='Sale orders linked to this purchase order', ) fusion_marked_for_ids = fields.Many2many( 'res.partner', 'fusion_po_marked_for_rel', 'purchase_order_id', 'partner_id', string='Marked For', help='Customers this purchase order is marked for', ) fusion_sale_count = fields.Integer( string='Sales', compute='_compute_fusion_sale_count', ) def _compute_fusion_sale_count(self): for po in self: po.fusion_sale_count = len(po.fusion_sale_ids) def action_view_fusion_sale_order(self): self.ensure_one() if not self.fusion_sale_ids: raise UserError(_("No Sale Orders are linked to this Purchase Order.")) if len(self.fusion_sale_ids) == 1: return { 'name': _('Sale Order'), 'view_mode': 'form', 'res_model': 'sale.order', 'res_id': self.fusion_sale_ids.id, 'type': 'ir.actions.act_window', } return { 'name': _('Sale Orders'), 'view_mode': 'list,form', 'res_model': 'sale.order', 'domain': [('id', 'in', self.fusion_sale_ids.ids)], 'type': 'ir.actions.act_window', } def _open_fusion_match_wizard(self, search_hint=''): wizard = self.env['fusion.match.so.wiz'].create({ 'fusion_po_id': self.id, 'fusion_search_hint': search_hint, }) return { 'name': _('Match Sale Order'), 'type': 'ir.actions.act_window', 'res_model': 'fusion.match.so.wiz', 'res_id': wizard.id, 'view_mode': 'form', 'target': 'new', } def action_fusion_match_sale_order(self): """Match this PO to a Sale Order based on the Marked For field.""" self.ensure_one() marked_for_value = self.fusion_marked_for_ids[:1] if self.fusion_marked_for_ids else None if not marked_for_value: return self._open_fusion_match_wizard('') partner = marked_for_value search_hint = partner.name matching_sales = self.env['sale.order'].search([ ('partner_id', '=', partner.id), ]) if not matching_sales or len(matching_sales) > 1: return self._open_fusion_match_wizard(search_hint) self.write({ 'fusion_sale_ids': [(4, matching_sales.id)], }) return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': _('Success'), 'message': _('Linked to Sale Order: %s') % matching_sales.name, 'type': 'success', 'sticky': False, }, } def action_fusion_batch_match(self): """Batch match multiple POs to Sale Orders based on Marked For field.""" matched = 0 skipped = 0 errors = [] for po in self: if not po.fusion_marked_for_ids: skipped += 1 continue partner = po.fusion_marked_for_ids[:1] matching_sales = self.env['sale.order'].search([ ('partner_id', '=', partner.id), ]) if not matching_sales: errors.append(_("PO %s: No SO found for '%s'") % (po.name, partner.name)) continue if len(matching_sales) > 1: errors.append( _("PO %s: Multiple SOs (%d) for '%s'") % (po.name, len(matching_sales), partner.name) ) continue po.write({ 'fusion_sale_ids': [(4, matching_sales.id)], }) matched += 1 message = _("Matched: %d, Skipped: %d") % (matched, skipped) if errors: message += "\n" + "\n".join(errors[:5]) if len(errors) > 5: message += _("\n... and %d more errors") % (len(errors) - 5) return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'title': _('Batch Match Complete'), 'message': message, 'type': 'info' if matched > 0 else 'warning', 'sticky': True, }, } class ResPartner(models.Model): _inherit = 'res.partner' x_fc_account_number = fields.Char( string='Account Number', tracking=True, help='Vendor/supplier account number', )