trytond-account_invoice_con.../invoice.py

133 lines
5.2 KiB
Python
Raw Normal View History

2015-05-11 17:48:45 +02:00
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
2012-08-27 12:19:36 +02:00
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from sql.aggregate import Sum
from sql.functions import Round
2012-08-27 12:19:36 +02:00
2012-10-17 11:18:43 +02:00
__all__ = ['Invoice']
2012-08-27 12:19:36 +02:00
2013-04-16 23:07:22 +02:00
2012-10-17 11:18:43 +02:00
class Invoice:
2016-03-29 11:43:12 +02:00
__metaclass__ = PoolMeta
2012-10-17 11:18:43 +02:00
__name__ = 'account.invoice'
2012-08-27 12:19:36 +02:00
2012-10-17 11:18:43 +02:00
@classmethod
def __setup__(cls):
super(Invoice, cls).__setup__()
cls._error_messages.update({
'invalid_number_date': 'You are trying to create '
2018-01-09 15:53:17 +01:00
'%(invoice_number)s invoice on date %(invoice_date)s. '
'There are %(invoice_count)d invoices after this date:'
'\n\n%(invoices)s',
'not_same_dates': 'You are trying to validate an invoice '
2018-01-09 15:53:17 +01:00
'where invoice date (%(invoice_date)s) and accounting '
'date (%(accounting_date)s) are different. That is not '
'permitted, because of invoice number and date '
'correlation.',
})
@classmethod
def validate(cls, invoices):
super(Invoice, cls).validate(invoices)
for invoice in invoices:
2016-03-29 17:30:01 +02:00
if invoice.type != 'in':
invoice.check_same_dates()
def check_same_dates(self):
2018-01-09 15:53:17 +01:00
pool = Pool()
Lang = pool.get('ir.lang')
if (self.invoice_date and self.accounting_date
2018-01-09 15:53:17 +01:00
and self.invoice_date != self.accounting_date):
language = Transaction().language
languages = Lang.search([('code', '=', language)])
if not languages:
2016-12-12 11:38:23 +01:00
language, = Lang.search([('code', '=', 'en')], limit=1)
self.raise_user_error('not_same_dates', {
'invoice_date': Lang.strftime(self.invoice_date, language.code,
language.date),
'accounting_date': Lang.strftime(self.accounting_date,
language.code, language.date),
2012-08-27 12:19:36 +02:00
})
@classmethod
def set_number(cls, invoices):
2012-08-27 12:19:36 +02:00
# TODO: When do we check this?
2015-05-11 17:48:45 +02:00
# if not invoice.journal_id.check_invoice_lines_tax:
# continue
pool = Pool()
Period = pool.get('account.period')
Move = pool.get('account.move')
InvoiceLine = pool.get('account.invoice.line')
Lang = pool.get('ir.lang')
2015-09-29 15:43:31 +02:00
Module = pool.get('ir.module')
to_check = [i for i in invoices if i.type == 'out']
super(Invoice, cls).set_number(invoices)
for invoice in to_check:
table = cls.__table__()
move = Move.__table__()
period = Period.__table__()
iline = InvoiceLine.__table__()
# As we have a control in the validate that make the
# accounting_date have to be the same as invoice_date, in cas it
# exist, we can use invoice_date to calculate the period.
period_id = Period.find(
invoice.company.id, date=invoice.invoice_date)
fiscalyear = Period(period_id).fiscalyear
query = table.join(iline, condition=(table.id == iline.invoice))
query = query.join(move, condition=(table.move == move.id)).join(
period, condition=move.period == period.id)
where = ((table.state != 'draft') &
(table.type == invoice.type) &
(table.company == invoice.company.id) &
(period.fiscalyear == fiscalyear.id))
account_invoice_sequence_module_installed = Module.search([
('name', '=', 'account_invoice_multisequence'),
('state', '=', 'activated'),
])
if account_invoice_sequence_module_installed:
where &= (table.journal == invoice.journal.id)
subselect = query.select(table.id, table.number,
Round(Sum(iline.quantity * iline.unit_price)).as_('amount'),
where=where, group_by=(table.id, table.number))
if invoice.untaxed_amount > 0:
where2 = (subselect.amount > 0)
else:
where2 = (subselect.amount <= 0)
where &= (
(table.id.in_(subselect.select(subselect.id, where=where2))) &
(((table.number < invoice.number) &
(table.invoice_date > invoice.invoice_date)) |
((table.number > invoice.number) &
(table.invoice_date < invoice.invoice_date))))
query = query.select(table.number, table.invoice_date, where=where,
limit=5)
cursor = Transaction().connection.cursor()
2014-07-18 16:22:06 +02:00
cursor.execute(*query)
2012-08-27 12:19:36 +02:00
records = cursor.fetchall()
if records:
language = Lang.get()
2012-10-17 11:18:43 +02:00
info = ['%(number)s - %(date)s' % {
'number': record[0],
'date': language.strftime(record[1]),
2012-10-17 11:18:43 +02:00
} for record in records]
info = '\n'.join(info)
cls.raise_user_error('invalid_number_date', {
'invoice_number': invoice.number,
'invoice_date': language.strftime(invoice.invoice_date),
2012-10-17 11:18:43 +02:00
'invoice_count': len(records),
'invoices': info,
})