trytond-account_payment_amo.../account.py
José Antonio Díaz Miralles b913d023bd Improve performance.
This commit refs #22848


(cherry picked from commit a25399ae99)
2022-05-05 14:11:17 +00:00

150 lines
5 KiB
Python

# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.pool import Pool, PoolMeta
from trytond.model import fields
from trytond.transaction import Transaction
from trytond.pyson import If, Eval, Bool
from sql import Null
from sql.aggregate import Sum
from sql.conditionals import Case, Coalesce
from sql.functions import Abs
class Move(metaclass=PoolMeta):
__name__ = 'account.move'
@classmethod
def post(cls, moves):
pool = Pool()
MoveLine = pool.get('account.move.line')
super().post(moves)
lines = [line for move in moves
for line in move.lines]
MoveLine.set_payment_amount(lines)
class MoveLine(metaclass=PoolMeta):
__name__ = 'account.move.line'
payment_amount_store = fields.Numeric('Payment amount store',
readonly=True, digits=(16,
If(Bool(Eval('second_currency_digits')),
Eval('second_currency_digits', 2),
Eval('currency_digits', 2))),
depends=['second_currency_digits', 'currency_digits'])
@classmethod
def __setup__(cls):
super().__setup__()
cls.payment_amount.getter = 'get_payment_amount_store'
cls._check_modify_exclude.add('payment_amount_store')
@classmethod
def __register__(cls, module_name):
pool = Pool()
Payment = pool.get('account.payment')
Account = pool.get('account.account')
AccountType = pool.get('account.account.type')
payment = Payment.__table__()
account = Account.__table__()
account_type = AccountType.__table__()
cursor = Transaction().connection.cursor()
table_handler = cls.__table_handler__(module_name)
table = cls.__table__()
sql_table = cls.__table__()
exists = table_handler.column_exist('payment_amount_store')
super().__register__(module_name)
if not exists:
# query from searcher
payment_amount = Sum(Coalesce(payment.amount, 0))
main_amount = Abs(table.credit - table.debit) - payment_amount
second_amount = Abs(table.amount_second_currency) - payment_amount
amount = Case((table.second_currency == Null, main_amount),
else_=second_amount)
query = (table
.join(payment, type_='LEFT', condition=(
(table.id == payment.line)
& (payment.state != 'failed')))
.join(account, condition=table.account == account.id)
.join(account_type, condition=account.type == account_type.id)
.select(
amount.as_('amount'),
where=(
(account_type.payable | account_type.receivable)
& (table.id == sql_table.id)),
group_by=(table.id, table.second_currency)
))
cursor.execute(*sql_table.update(
[sql_table.payment_amount_store],
[query]))
@classmethod
def get_payment_amount_store(cls, lines, name=None):
return {line.id: line.payment_amount_store
for line in lines}
@classmethod
def set_payment_amount(cls, lines):
lines = cls.browse(lines)
lines_amounts = cls.get_payment_amount(lines, None)
lines2ids = {line.id: line for line in lines}
to_save = []
for line_id, amount in lines_amounts.items():
move_line = lines2ids[line_id]
move_line.payment_amount_store = amount
to_save.append(move_line)
if to_save:
cls.save(to_save)
@classmethod
def search_payment_amount(cls, name, clause):
return [('%s_store' % name, ) + tuple(clause[1:])]
class Payment(metaclass=PoolMeta):
__name__ = 'account.payment'
@classmethod
def create(cls, vlist):
MoveLine = Pool().get('account.move.line')
payments = super().create(vlist)
lines = [payment.line for payment in payments if payment.line]
MoveLine.set_payment_amount(lines)
return payments
@classmethod
def write(cls, *args):
MoveLine = Pool().get('account.move.line')
super().write(*args)
actions = iter(args)
lines = []
line_changes = {'line', 'amount'}
for payments, values in zip(actions, actions):
if line_changes & (set(values)):
lines.extend(payment.line for payment in payments
if payment.line)
if values.get('line', None):
# if change line adds the new one
lines.append(MoveLine(values['line']))
MoveLine.set_payment_amount(lines)
@classmethod
def delete(cls, payments):
MoveLine = Pool().get('account.move.line')
lines = [payment.line for payment in payments if payment.line]
super().delete(payments)
MoveLine.set_payment_amount(lines)