From d9c5c3e09543f4a2101db444ab4e260cccff14ed Mon Sep 17 00:00:00 2001 From: oco-odoo Date: Wed, 6 Jan 2021 12:29:48 +0000 Subject: [PATCH] [FIX] account: reconciliation models: make auto_reconcile rules work properly with write-offs - Create an invoice for 100 - Create a bank statement for 95 - Setup your reconciliation model so that it will match them and create a write-off for the remaining 5. Make it auto_reconciled. => Doing that, we expect the bank journal move to be created like this: - 100 on payable/receivable, reconciled with the invoice - 95 on the bank account - 5 on the write-off account This wasn't the case. Instead, Odoo created the following (correct from an accounting point of view, but weird): - 95 on payable/receivable, reconciled with the invoice - 5 on payable/receivable, not reconciled - 95 on the bank account - 5 on the write-off account => So an open balance of 5 was actually created. This was weird, and also caused an additional bug, as only the first payable/receivable line was reconciled with the invoice, making it only partially paid. This commit restores the expected behavior. --- .../account/models/account_reconcile_model.py | 5 ++++ .../test_reconciliation_matching_rules.py | 25 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py index fcd21149a07..f5088f59458 100644 --- a/addons/account/models/account_reconcile_model.py +++ b/addons/account/models/account_reconcile_model.py @@ -393,6 +393,8 @@ class AccountReconcileModel(models.Model): partner = partner or st_line.partner_id + has_full_write_off= any(rec_mod_line.amount == 100.0 for rec_mod_line in self.line_ids) + lines_vals_list = [] amls = self.env['account.move.line'].browse(aml_ids) st_line_residual_before = st_line_residual @@ -403,6 +405,9 @@ class AccountReconcileModel(models.Model): if aml.balance * st_line_residual > 0: # Meaning they have the same signs, so they can't be reconciled together assigned_balance = -aml.amount_residual + elif has_full_write_off: + assigned_balance = -aml.amount_residual + st_line_residual -= min(-aml.amount_residual, st_line_residual, key=abs) else: assigned_balance = min(-aml.amount_residual, st_line_residual, key=abs) st_line_residual -= assigned_balance diff --git a/addons/account/tests/test_reconciliation_matching_rules.py b/addons/account/tests/test_reconciliation_matching_rules.py index ef471961a03..69cdb506faf 100644 --- a/addons/account/tests/test_reconciliation_matching_rules.py +++ b/addons/account/tests/test_reconciliation_matching_rules.py @@ -448,12 +448,14 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): ]) def test_larger_invoice_auto_reconcile(self): - ''' Test auto reconciliation with an invoice with larger amount than the statement line's.''' + ''' Test auto reconciliation with an invoice with larger amount than the + statement line's, for rules without write-offs.''' self.bank_line_1.amount = 40 self.invoice_line_1.move_id.payment_reference = self.bank_line_1.payment_ref self.rule_1.sequence = 2 self.rule_1.auto_reconcile = True + self.rule_1.line_ids = [(5, 0, 0)] self._check_statement_matching(self.rule_1, { self.bank_line_1.id: {'aml_ids': [self.invoice_line_1.id], 'model': self.rule_1, 'status': 'reconciled', 'partner': self.bank_line_1.partner_id}, @@ -767,3 +769,24 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): } self.assertDictEqual(expected_write_off, to_compare) + + def test_inv_matching_with_write_off_autoreconcile(self): + self.bank_line_1.amount = 95 + + self.rule_1.sequence = 2 + self.rule_1.auto_reconcile = True + self.rule_1.match_total_amount_param = 90 + + self._check_statement_matching(self.rule_1, { + self.bank_line_1.id: {'aml_ids': [self.invoice_line_1.id], 'model': self.rule_1, 'status': 'reconciled', 'partner': self.bank_line_1.partner_id}, + self.bank_line_2.id: {'aml_ids': []}, + }, statements=self.bank_st) + + # Check first line has been properly reconciled. + self.assertRecordValues(self.bank_line_1.line_ids, [ + {'partner_id': self.partner_1.id, 'debit': 95.0, 'credit': 0.0, 'account_id': self.bank_journal.default_account_id.id, 'reconciled': False}, + {'partner_id': self.partner_1.id, 'debit': 5.0, 'credit': 0.0, 'account_id': self.current_assets_account.id, 'reconciled': False}, + {'partner_id': self.partner_1.id, 'debit': 0.0, 'credit': 100.0, 'account_id': self.invoice_line_1.account_id.id, 'reconciled': True}, + ]) + + self.assertEqual(self.invoice_line_1.amount_residual, 0.0, "The invoice should have been fully reconciled")