109 lines
3.9 KiB
Python
109 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
from odoo import models, fields, api, _
|
|
from odoo.exceptions import ValidationError
|
|
|
|
class MergeBillWizard(models.TransientModel):
|
|
_name = 'merge.bill.wizard'
|
|
_description = 'Assistant de fusion des factures'
|
|
|
|
invoice_ids = fields.Many2many(
|
|
'account.move',
|
|
string='Factures à fusionner',
|
|
required=True
|
|
)
|
|
partner_id = fields.Many2one(
|
|
'res.partner',
|
|
string='Fournisseur',
|
|
required=True
|
|
)
|
|
merge_invoices = fields.Boolean(
|
|
string='Fusionner les factures',
|
|
default=True,
|
|
help='Si coché, les factures seront fusionnées en une seule'
|
|
)
|
|
|
|
def _merge_invoices(self):
|
|
"""Fusionne plusieurs factures en une seule"""
|
|
if not self.invoice_ids:
|
|
return False
|
|
|
|
# Collecte les informations des factures existantes
|
|
invoice_origin = ', '.join(self.invoice_ids.mapped('invoice_origin'))
|
|
journal = self.env['account.journal'].search([('type', '=', 'purchase')], limit=1)
|
|
if not journal:
|
|
raise ValidationError(_('Aucun journal de factures fournisseur trouvé'))
|
|
|
|
# Regroupe les lignes par produit
|
|
product_lines = {}
|
|
for invoice in self.invoice_ids:
|
|
for line in invoice.invoice_line_ids:
|
|
key = (line.product_id.id, line.price_unit, tuple(line.tax_ids.ids))
|
|
if key not in product_lines:
|
|
product_lines[key] = {
|
|
'product_id': line.product_id.id,
|
|
'name': line.name,
|
|
'quantity': 0,
|
|
'price_unit': line.price_unit,
|
|
'tax_ids': line.tax_ids.ids,
|
|
'purchase_line_ids': [],
|
|
}
|
|
product_lines[key]['quantity'] += line.quantity
|
|
if line.purchase_line_id:
|
|
product_lines[key]['purchase_line_ids'].append(line.purchase_line_id.id)
|
|
|
|
# Crée les lignes de la nouvelle facture
|
|
invoice_lines = []
|
|
for values in product_lines.values():
|
|
line_vals = {
|
|
'product_id': values['product_id'],
|
|
'name': values['name'],
|
|
'quantity': values['quantity'],
|
|
'price_unit': values['price_unit'],
|
|
'tax_ids': [(6, 0, values['tax_ids'])],
|
|
}
|
|
if values['purchase_line_ids']:
|
|
line_vals['purchase_line_id'] = values['purchase_line_ids'][0]
|
|
invoice_lines.append((0, 0, line_vals))
|
|
|
|
# Supprime les factures originales
|
|
self.invoice_ids.unlink()
|
|
|
|
# Crée la nouvelle facture
|
|
vals = {
|
|
'move_type': 'in_invoice',
|
|
'partner_id': self.partner_id.id,
|
|
'invoice_date': fields.Date.context_today(self),
|
|
'invoice_origin': invoice_origin,
|
|
'journal_id': journal.id,
|
|
'state': 'draft',
|
|
'invoice_line_ids': invoice_lines,
|
|
}
|
|
|
|
# Crée et valide la facture
|
|
merged_invoice = self.env['account.move'].create(vals)
|
|
merged_invoice.action_post()
|
|
|
|
return merged_invoice
|
|
|
|
def action_process(self):
|
|
"""Traite les factures selon l'option choisie"""
|
|
self.ensure_one()
|
|
|
|
if self.merge_invoices and len(self.invoice_ids) > 1:
|
|
# Fusionne les factures et affiche la nouvelle facture
|
|
merged_invoice = self._merge_invoices()
|
|
if not merged_invoice:
|
|
raise ValidationError(_('Erreur lors de la fusion des factures'))
|
|
invoice = merged_invoice
|
|
else:
|
|
invoice = self.invoice_ids[0]
|
|
|
|
# Retourne la vue de la facture
|
|
return {
|
|
'name': _('Facture fournisseur'),
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'account.move',
|
|
'res_id': invoice.id,
|
|
'view_mode': 'form',
|
|
'target': 'current',
|
|
}
|