187 lines
5.6 KiB
Python
187 lines
5.6 KiB
Python
# -*- 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',
|
|
)
|