From f094d11f53fe5abe8b83ed9645aea06fcb44bb7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 19 Mar 2022 22:16:29 +0100 Subject: [PATCH] Reconcile payment clearing line with all statement lines issue11173 review385851002 --- CHANGELOG | 1 + __init__.py | 3 +++ payment.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ statement.py | 52 +++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 95 insertions(+), 14 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fe7112e5b1..65821708c2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Reconcile payment clearing line with all statement lines * Use reference field for statement line relation * Add support for Python 3.10 * Remove support for Python 3.6 diff --git a/__init__.py b/__init__.py index a8352df06e..bd58aa721b 100644 --- a/__init__.py +++ b/__init__.py @@ -9,11 +9,14 @@ def register(): Pool.register( payment.Journal, payment.Payment, + payment.Group, payment.SucceedStart, account.Move, ir.Cron, module='account_payment_clearing', type_='model') Pool.register( + statement.Payment, + statement.PaymentGroup, statement.Statement, statement.StatementLine, module='account_payment_clearing', type_='model', diff --git a/payment.py b/payment.py index c8e77852e6..4a19d49e76 100644 --- a/payment.py +++ b/payment.py @@ -192,6 +192,7 @@ class Payment(metaclass=PoolMeta): if not sum(l.debit - l.credit for l in lines): to_reconcile.append(lines) Line.reconcile(*to_reconcile) + cls.reconcile_clearing(payments) @property def clearing_account(self): @@ -277,6 +278,34 @@ class Payment(metaclass=PoolMeta): def fail(cls, payments): super(Payment, cls).fail(payments) + @classmethod + def reconcile_clearing(cls, payments): + pool = Pool() + MoveLine = pool.get('account.move.line') + Group = pool.get('account.payment.group') + to_reconcile = [] + for payment in payments: + if not payment.clearing_move: + continue + clearing_account = payment.journal.clearing_account + if not clearing_account or not clearing_account.reconcile: + continue + lines = [l for l in payment.clearing_lines if not l.reconciliation] + if lines and not sum((l.debit - l.credit) for l in lines): + to_reconcile.append(lines) + if to_reconcile: + MoveLine.reconcile(*to_reconcile) + Group.reconcile_clearing( + Group.browse(list({p.group for p in payments if p.group}))) + + @property + def clearing_lines(self): + clearing_account = self.journal.clearing_account + if self.clearing_move: + for line in self.clearing_move.lines: + if line.account == clearing_account: + yield line + @classmethod def copy(cls, payments, default=None): if default is None: @@ -287,6 +316,30 @@ class Payment(metaclass=PoolMeta): return super(Payment, cls).copy(payments, default=default) +class Group(metaclass=PoolMeta): + __name__ = 'account.payment.group' + + @classmethod + def reconcile_clearing(cls, groups): + pool = Pool() + MoveLine = pool.get('account.move.line') + to_reconcile = [] + for group in groups: + clearing_account = group.journal.clearing_account + if not clearing_account or not clearing_account.reconcile: + continue + lines = [l for l in group.clearing_lines if not l.reconciliation] + if lines and not sum((l.debit - l.credit) for l in lines): + to_reconcile.append(lines) + if to_reconcile: + MoveLine.reconcile(*to_reconcile) + + @property + def clearing_lines(self): + for payment in self.payments: + yield from payment.clearing_lines + + class Succeed(Wizard): "Succeed Payment" __name__ = 'account.payment.succeed' diff --git a/statement.py b/statement.py index 01c666e578..284d333ee5 100644 --- a/statement.py +++ b/statement.py @@ -8,13 +8,48 @@ from trytond.pyson import Eval from trytond.transaction import Transaction +class Payment(metaclass=PoolMeta): + __name__ = 'account.payment' + + statement_lines = fields.One2Many( + 'account.statement.line', 'related_to', "Statement Lines", + readonly=True) + + @property + def clearing_lines(self): + clearing_account = self.journal.clearing_account + yield from super().clearing_lines + for statement_line in self.statement_lines: + if statement_line.move: + for line in statement_line.move.lines: + if line.account == clearing_account: + yield line + + +class PaymentGroup(metaclass=PoolMeta): + __name__ = 'account.payment.group' + + statement_lines = fields.One2Many( + 'account.statement.line', 'related_to', "Statement Lines", + readonly=True) + + @property + def clearing_lines(self): + clearing_account = self.journal.clearing_account + yield from super().clearing_lines + for statement_line in self.statement_lines: + if statement_line.move: + for line in statement_line.move.lines: + if line.account == clearing_account: + yield line + + class Statement(metaclass=PoolMeta): __name__ = 'account.statement' @classmethod def create_move(cls, statements): pool = Pool() - MoveLine = pool.get('account.move.line') Payment = pool.get('account.payment') moves = super(Statement, cls).create_move(statements) @@ -46,19 +81,8 @@ class Statement(metaclass=PoolMeta): with Transaction().set_context(clearing_date=date): Payment.fail(Payment.browse(payments)) - for move, statement, lines in moves: - assert len({l.payment for l in lines}) == 1 - line = lines[0] - if line.payment and line.payment.clearing_move: - clearing_account = line.payment.journal.clearing_account - if clearing_account.reconcile: - to_reconcile = [] - for line in move.lines + line.payment.clearing_move.lines: - if (line.account == clearing_account - and not line.reconciliation): - to_reconcile.append(line) - if not sum((l.debit - l.credit) for l in to_reconcile): - MoveLine.reconcile(to_reconcile) + Payment.__queue__.reconcile_clearing( + list(set.union(*to_success.values(), *to_fail.values()))) return moves def _group_key(self, line):