[FIX] account: reconciliation models: fix auto-reconciliation result when the reconciliation doesn't cover the whole invoice

Before that, using an auto-validate reconciliation model to match an invoice with a statement line with a lesser amount resulted in the creation of an payment entry with which the invoice got fully reconciled, and the difference amount was fowarded to the suspsense account in an additional line. This wasn't correct, as we expect the invoice to be only partially paid in that case (with an amount equal to the statement line's).

closes odoo/odoo#63303

X-original-commit: 7393aa3ebcea7b80762b729315f1c890bc677efb
Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
This commit is contained in:
oco-odoo
2020-12-14 10:16:22 +00:00
parent bbf860ae97
commit addd40a09f
2 changed files with 50 additions and 10 deletions
@@ -385,26 +385,45 @@ class AccountReconcileModel(models.Model):
liquidity_lines, suspense_lines, other_lines = st_line._seek_for_lines()
if st_line.to_check:
residual_balance = -liquidity_lines.balance
st_line_residual = -liquidity_lines.balance
elif suspense_lines.account_id.reconcile:
residual_balance = sum(suspense_lines.mapped('amount_residual'))
st_line_residual = sum(suspense_lines.mapped('amount_residual'))
else:
residual_balance = sum(suspense_lines.mapped('balance'))
st_line_residual = sum(suspense_lines.mapped('balance'))
partner = partner or st_line.partner_id
lines_vals_list = [{'id': aml_id} for aml_id in aml_ids]
lines_vals_list = []
amls = self.env['account.move.line'].browse(aml_ids)
st_line_residual_before = st_line_residual
aml_total_residual = 0
for aml in amls:
aml_total_residual += aml.amount_residual
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
else:
assigned_balance = min(-aml.amount_residual, st_line_residual, key=abs)
st_line_residual -= assigned_balance
lines_vals_list.append({
'id': aml.id,
'balance': assigned_balance,
'currency_id': st_line.move_id.company_id.currency_id.id,
})
write_off_amount = max(aml_total_residual, -st_line_residual_before, key=abs) + st_line_residual_before + st_line_residual
reconciliation_overview, open_balance_vals = st_line._prepare_reconciliation(lines_vals_list)
for reconciliation_vals in reconciliation_overview:
residual_balance -= reconciliation_vals['line_vals']['debit'] - reconciliation_vals['line_vals']['credit']
writeoff_vals_list = self._get_write_off_move_lines_dict(st_line, residual_balance)
writeoff_vals_list = self._get_write_off_move_lines_dict(st_line, write_off_amount)
for line_vals in writeoff_vals_list:
residual_balance -= st_line.company_currency_id.round(line_vals['balance'])
st_line_residual -= st_line.company_currency_id.round(line_vals['balance'])
# Check we have enough information to create an open balance.
if not st_line.company_currency_id.is_zero(residual_balance):
if not st_line.company_currency_id.is_zero(st_line_residual):
if st_line.amount > 0:
open_balance_account = partner.property_account_receivable_id
else:
@@ -447,6 +447,27 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
{'partner_id': self.partner_2.id, 'debit': 1000.0, 'credit': 0.0},
])
def test_larger_invoice_auto_reconcile(self):
''' Test auto reconciliation with an invoice with larger amount than the statement line's.'''
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._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 well reconciled.
self.assertRecordValues(self.bank_line_1.line_ids, [
{'partner_id': self.partner_1.id, 'debit': 40.0, 'credit': 0.0},
{'partner_id': self.partner_1.id, 'debit': 0.0, 'credit': 40.0},
])
self.assertEqual(self.invoice_line_1.amount_residual, 60.0, "The invoice should have been partially reconciled")
def test_auto_reconcile_with_tax(self):
''' Test auto reconciliation with a tax amount included in the bank statement line'''
self.rule_1.write({