# This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. from trytond.model import ModelSQL, fields from trytond.transaction import Transaction from trytond.pool import Pool, PoolMeta __all__ = ['Purchase', 'PurchaseIgnoredInvoiceLine', 'HandleInvoiceException'] class Purchase(metaclass=PoolMeta): __name__ = 'purchase.purchase' invoice_lines = fields.Function(fields.One2Many('account.invoice.line', None, 'Invoice Lines'), 'get_invoice_lines', searcher='search_invoice_lines') invoice_lines_ignored = fields.Many2Many( 'purchase.purchase-ignored-account.invoice.line', 'purchase', 'invoice', 'Invoice Lines Ignored', readonly=True) def get_invoice_lines(self, name): return list({il.id for l in self.lines for il in l.invoice_lines}) @classmethod def search_invoice_lines(cls, name, clause): return [('lines.' + clause[0],) + tuple(clause[1:])] def create_invoice(self): pool = Pool() Invoice = pool.get('account.invoice') InvoiceLine = pool.get('account.invoice.line') invoice = super(Purchase, self).create_invoice() if invoice: lines_to_delete = [l for l in invoice.lines if l.type != 'line'] lines = [l for l in invoice.lines if l.type == 'line'] InvoiceLine.write(lines, { 'invoice': None, 'invoice_type': invoice.type, 'party': invoice.party.id, 'currency': invoice.currency.id, 'company': invoice.company.id, }) InvoiceLine.delete(lines_to_delete) Invoice.cancel([invoice]) Invoice.delete([invoice]) return None return invoice def get_invoice_state(self): state = super(Purchase, self).get_invoice_state() skips = set(x.id for x in self.invoice_lines_ignored) invoice_lines = [l for l in self.invoice_lines if l.id not in skips] if invoice_lines: if any(l.invoice and l.invoice.state == 'cancel' for l in invoice_lines): return 'exception' elif (state == 'paid' and all(l.invoice for l in invoice_lines) and all(l.invoice.state == 'paid' for l in invoice_lines)): return 'paid' else: return 'waiting' return state @classmethod def copy(cls, purchases, default=None): if default is None: default = {} else: default = default.copy() default.setdefault('invoice_lines_ignored', None) return super(Purchase, cls).copy(purchases, default=default) class PurchaseIgnoredInvoiceLine(ModelSQL): 'Purchase - Ignored Invoice Line' __name__ = 'purchase.purchase-ignored-account.invoice.line' _table = 'purchase_invoice_line_ignored_rel' purchase = fields.Many2One('purchase.purchase', 'Purchase', ondelete='CASCADE', select=True, required=True) invoice = fields.Many2One('account.invoice.line', 'Invoice Line', ondelete='RESTRICT', select=True, required=True) class HandleInvoiceException(metaclass=PoolMeta): __name__ = 'purchase.handle.invoice.exception' def transition_handle(self): Purchase = Pool().get('purchase.purchase') state = super(HandleInvoiceException, self).transition_handle() purchase = Purchase(Transaction().context['active_id']) invoice_lines = [] for invoice_line in purchase.invoice_lines: if (invoice_line.invoice and invoice_line.invoice.state == 'cancel'): invoice_lines.append(invoice_line.id) if invoice_lines: Purchase.write([purchase], { 'invoice_lines_ignored': [('add', invoice_lines)], }) Purchase.__queue__.process([purchase]) return state