Files
tryton/modules/purchase/invoice.py
T

146 lines
4.8 KiB
Python
Raw Normal View History

2014-12-02 12:55:47 +01:00
# 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 functools import wraps
2018-12-29 14:20:29 +01:00
from trytond.i18n import gettext
2012-09-24 22:18:09 +02:00
from trytond.model import ModelView, Workflow, fields
2018-12-29 14:20:29 +01:00
from trytond.model.exceptions import AccessError
2012-09-24 22:18:09 +02:00
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
def process_purchase(func):
@wraps(func)
def wrapper(cls, invoices):
pool = Pool()
Purchase = pool.get('purchase.purchase')
2014-09-17 21:45:46 +02:00
with Transaction().set_context(_check_access=False):
2018-07-27 09:27:49 +02:00
purchases = set(
p for i in cls.browse(invoices) for p in i.purchases)
func(cls, invoices)
2018-07-27 09:27:49 +02:00
if purchases:
Purchase.__queue__.process(purchases)
return wrapper
2018-06-26 19:11:51 +02:00
class Invoice(metaclass=PoolMeta):
2012-09-24 22:18:09 +02:00
__name__ = 'account.invoice'
purchase_exception_state = fields.Function(fields.Selection([
('', ''),
('ignored', 'Ignored'),
('recreated', 'Recreated'),
], 'Exception State'), 'get_purchase_exception_state')
purchases = fields.Function(fields.Many2Many(
'purchase.purchase', None, None, "Purchases"),
'get_purchases', searcher='search_purchases')
2014-09-17 21:45:46 +02:00
def get_purchase_exception_state(self, name):
purchases = self.purchases
2012-09-24 22:18:09 +02:00
recreated = tuple(i for p in purchases for i in p.invoices_recreated)
ignored = tuple(i for p in purchases for i in p.invoices_ignored)
2014-09-17 21:45:46 +02:00
if self in recreated:
return 'recreated'
elif self in ignored:
return 'ignored'
return ''
2012-09-24 22:18:09 +02:00
def get_purchases(self, name):
2013-09-06 22:34:36 +02:00
pool = Pool()
PurchaseLine = pool.get('purchase.line')
purchases = set()
for line in self.lines:
if isinstance(line.origin, PurchaseLine):
purchases.add(line.origin.purchase.id)
return list(purchases)
@classmethod
def search_purchases(cls, name, clause):
2017-09-27 18:37:31 +02:00
return [('lines.origin.purchase' + clause[0].lstrip(name),)
+ tuple(clause[1:3]) + ('purchase.line',) + tuple(clause[3:])]
@classmethod
@process_purchase
def delete(cls, invoices):
2012-09-24 22:18:09 +02:00
super(Invoice, cls).delete(invoices)
@classmethod
def copy(cls, invoices, default=None):
2012-03-01 10:20:43 +01:00
if default is None:
default = {}
2018-09-01 01:02:03 +02:00
else:
default = default.copy()
2012-03-27 10:43:54 +02:00
default.setdefault('purchases', None)
2012-09-24 22:18:09 +02:00
return super(Invoice, cls).copy(invoices, default=default)
2012-03-01 10:20:43 +01:00
2012-09-24 22:18:09 +02:00
@classmethod
@ModelView.button
@Workflow.transition('draft')
def draft(cls, invoices):
2018-12-29 14:20:29 +01:00
for invoice in invoices:
if invoice.purchases and invoice.state == 'cancelled':
2018-12-29 14:20:29 +01:00
raise AccessError(
gettext('purchase.msg_purchase_invoice_reset_draft',
invoice=invoice.rec_name))
2012-09-24 22:18:09 +02:00
return super(Invoice, cls).draft(invoices)
@classmethod
@process_purchase
2021-02-27 15:23:46 +01:00
def _post(cls, invoices):
super()._post(invoices)
2012-03-25 00:18:10 +01:00
2012-09-24 22:18:09 +02:00
@classmethod
@process_purchase
def paid(cls, invoices):
super(Invoice, cls).paid(invoices)
@classmethod
@process_purchase
2012-09-24 22:18:09 +02:00
def cancel(cls, invoices):
super(Invoice, cls).cancel(invoices)
2018-06-26 19:11:51 +02:00
class InvoiceLine(metaclass=PoolMeta):
2012-09-24 22:18:09 +02:00
__name__ = 'account.invoice.line'
@fields.depends('origin')
def on_change_with_product_uom_category(self, name=None):
pool = Pool()
PurchaseLine = pool.get('purchase.line')
category = super().on_change_with_product_uom_category(name=name)
# Enforce the same unit category as they are used to compute the
# remaining quantity to invoice and the quantity to receive.
# Use getattr as reference field can have negative id
if (isinstance(self.origin, PurchaseLine)
and getattr(self.origin, 'unit', None)):
category = self.origin.unit.category.id
return category
2013-09-19 17:33:53 +02:00
@property
def origin_name(self):
pool = Pool()
PurchaseLine = pool.get('purchase.line')
name = super(InvoiceLine, self).origin_name
if isinstance(self.origin, PurchaseLine):
2019-05-22 18:37:08 +02:00
name = self.origin.purchase.rec_name
2013-09-19 17:33:53 +02:00
return name
@classmethod
def _get_origin(cls):
models = super(InvoiceLine, cls)._get_origin()
models.append('purchase.line')
return models
@classmethod
def delete(cls, lines):
pool = Pool()
Purchase = pool.get('purchase.purchase')
with Transaction().set_context(_check_access=False):
2018-07-27 09:27:49 +02:00
invoices = (l.invoice for l in cls.browse(lines)
if l.type == 'line' and l.invoice)
2018-07-27 09:27:49 +02:00
purchases = set(p for i in invoices for p in i.purchases)
super(InvoiceLine, cls).delete(lines)
2018-07-27 09:27:49 +02:00
if purchases:
Purchase.__queue__.process(purchases)