[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.
This commit is contained in:
oco-odoo
2021-01-08 11:09:48 +00:00
parent 82ca092bd1
commit d9c5c3e095
2 changed files with 29 additions and 1 deletions
@@ -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
@@ -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")