Files
tryton/modules/account_statement/journal.py
T

185 lines
7.0 KiB
Python
Raw Normal View History

2014-12-02 12:54:50 +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 sql import Window
from sql.aggregate import Max
from sql.functions import FirstValue
from trytond import backend
2021-12-11 17:58:41 +01:00
from trytond.model import DeactivableMixin, ModelSQL, ModelView, Unique, fields
from trytond.modules.currency.fields import Monetary
2011-07-03 13:18:45 +02:00
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.rpc import RPC
from trytond.tools import (
cursor_dict, grouped_slice, reduce_ids, sqlite_apply_types)
2021-12-11 17:58:41 +01:00
from trytond.transaction import Transaction
2008-06-10 22:01:27 +02:00
2008-06-17 12:09:01 +02:00
2021-06-29 00:32:12 +02:00
class Journal(DeactivableMixin, ModelSQL, ModelView):
2012-09-24 22:17:36 +02:00
__name__ = 'account.statement.journal'
2008-06-17 12:09:01 +02:00
name = fields.Char('Name', required=True)
journal = fields.Many2One(
'account.journal', 'Journal', required=True,
domain=[('type', '=', 'statement')],
context={
'company': Eval('company', -1),
},
depends={'company'})
2008-06-10 22:01:27 +02:00
currency = fields.Many2One('currency.currency', 'Currency', required=True)
company = fields.Many2One('company.company', "Company", required=True)
company_party = fields.Function(
fields.Many2One(
'party.party', "Company Party",
context={
'company': Eval('company', -1),
},
depends={'company'}),
'on_change_with_company_party')
2014-07-20 13:45:45 +02:00
validation = fields.Selection([
('balance', 'Balance'),
('amount', 'Amount'),
('number_of_lines', 'Number of Lines'),
], 'Validation Type', required=True)
bank_account = fields.Many2One(
'bank.account', "Bank Account",
domain=[
('owners.id', '=', Eval('company_party', -1)),
['OR',
('currency', '=', Eval('currency', -1)),
('currency', '=', None),
],
])
2018-09-01 11:19:35 +02:00
account = fields.Many2One('account.account', "Account", required=True,
domain=[
2019-03-24 18:00:01 +01:00
('type', '!=', None),
('closed', '!=', True),
('company', '=', Eval('company', -1)),
('party_required', '=', False),
])
last_date = fields.Function(fields.Date("Last Date"), 'get_last_statement')
last_amount = fields.Function(Monetary(
"Last Amount", currency='currency', digits='currency',
states={
'invisible': ~Eval('validation').in_(['balance']),
}),
'get_last_statement')
@classmethod
def __setup__(cls):
super(Journal, cls).__setup__()
cls._order.insert(0, ('name', 'ASC'))
t = cls.__table__()
cls._sql_constraints = [
('bank_account_unique',
Unique(t, t.bank_account, t.company),
2018-12-29 14:20:29 +01:00
'account_statement.msg_journal_bank_account_unique'),
]
cls.__rpc__.update(
get_by_bank_account=RPC(
result=lambda r: int(r) if r is not None else None),
)
2008-06-10 22:01:27 +02:00
2012-09-24 22:17:36 +02:00
@staticmethod
def default_currency():
2010-08-16 19:23:32 +02:00
if Transaction().context.get('company'):
2012-09-24 22:17:36 +02:00
Company = Pool().get('company.company')
company = Company(Transaction().context['company'])
return company.currency.id
2008-06-10 22:01:27 +02:00
2012-09-24 22:17:36 +02:00
@staticmethod
def default_company():
2012-03-27 10:43:12 +02:00
return Transaction().context.get('company')
2014-07-20 13:45:45 +02:00
@fields.depends('company')
def on_change_with_company_party(self, name=None):
2023-03-26 09:49:00 +02:00
return self.company.party if self.company else None
2014-07-20 13:45:45 +02:00
@staticmethod
def default_validation():
return 'balance'
@classmethod
def get_by_bank_account(cls, company, number, currency=None):
domain = [
('company', '=', company),
['OR',
('bank_account.numbers.number', '=', number),
('bank_account.numbers.number_compact', '=', number),
],
]
if currency:
domain.append(['OR',
('currency.code', '=', currency),
('currency.numeric_code', '=', currency),
])
journals = cls.search(domain)
if journals:
journal, = journals
return journal
@classmethod
def get_last_statement(cls, journals, names):
pool = Pool()
Statement = pool.get('account.statement')
statement = Statement.__table__()
transaction = Transaction()
database = transaction.database
cursor = transaction.connection.cursor()
id2currency = {j.id: j.currency for j in journals}
result = {}
for name in names:
result[name] = dict.fromkeys(id2currency.keys(), None)
for sub_ids in grouped_slice(id2currency.keys()):
columns = [statement.journal]
if database.has_window_functions():
w = Window(
partition=[statement.journal],
order_by=[statement.date.desc, statement.id.desc])
if 'last_amount' in names:
columns.append(
FirstValue(statement.end_balance,
window=w).as_('last_amount'))
if 'last_date' in names:
columns.append(
FirstValue(statement.date, window=w).as_('last_date'))
query = statement.select(*columns,
distinct=True,
where=reduce_ids(statement.journal, sub_ids)
& (statement.state != 'cancelled'))
else:
if 'last_amount' in names:
columns.append(statement.end_balance).as_('last_amount')
if 'last_date' in names:
columns.append(statement.date.as_('last_date'))
maxdate = statement.select(
statement.journal,
Max(statement.date).as_('date'),
group_by=statement.journal)
query = statement.join(maxdate,
condition=maxdate.journal == statement.journal,
).select(*columns,
where=reduce_ids(statement.journal, sub_ids)
& (maxdate.date == statement.date)
& (statement.state != 'cancelled'),
order_by=statement.id.asc)
if backend.name == 'sqlite':
types = [None]
if 'last_amount' in names:
types.append('NUMERIC')
if 'last_date' in names:
types.append('DATE')
sqlite_apply_types(query, types)
cursor.execute(*query)
for row in cursor_dict(cursor):
journal = row['journal']
if 'last_amount' in names:
result['last_amount'][journal] = (
id2currency[journal].round(row['last_amount']))
if 'last_date' in names:
result['last_date'][journal] = row['last_date']
return result