[FIX] account: Fix statement line rounding issue multi-currency
When reconciling a statement line with multiple lines in a multi-currency environment, it could lead to a rounding issue due to the currency rates. It could lead to an auto-generated open-balance of 0.01 amount to auto-balance the journal entry but the result is wrong since the partner has an open amount left on the receivable/payable account. closes odoo/odoo#64636 X-original-commit: 4d4e6e588d14742f153a1c6b67d510e0c21e5d64 Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com> Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
This commit is contained in:
@@ -1028,6 +1028,9 @@ class AccountBankStatementLine(models.Model):
|
||||
'''
|
||||
|
||||
self.ensure_one()
|
||||
journal = self.journal_id
|
||||
company_currency = journal.company_id.currency_id
|
||||
foreign_currency = self.foreign_currency_id or journal.currency_id or company_currency
|
||||
|
||||
liquidity_lines, suspense_lines, other_lines = self._seek_for_lines()
|
||||
|
||||
@@ -1044,6 +1047,7 @@ class AccountBankStatementLine(models.Model):
|
||||
reconciliation_overview = []
|
||||
|
||||
total_balance = liquidity_lines.balance
|
||||
total_amount_currency = liquidity_lines.amount_currency
|
||||
|
||||
# Step 1: Split 'lines_vals_list' into two batches:
|
||||
# - The existing account.move.lines that need to be reconciled with the statement line.
|
||||
@@ -1065,6 +1069,7 @@ class AccountBankStatementLine(models.Model):
|
||||
# Newly created account.move.line from scratch.
|
||||
line_vals = self._prepare_counterpart_move_line_vals(vals)
|
||||
total_balance += line_vals['debit'] - line_vals['credit']
|
||||
total_amount_currency += line_vals['amount_currency']
|
||||
|
||||
reconciliation_overview.append({
|
||||
'line_vals': line_vals,
|
||||
@@ -1076,6 +1081,7 @@ class AccountBankStatementLine(models.Model):
|
||||
for line, counterpart_vals in zip(existing_lines, to_process_vals):
|
||||
line_vals = self._prepare_counterpart_move_line_vals(counterpart_vals, move_line=line)
|
||||
balance = line_vals['debit'] - line_vals['credit']
|
||||
amount_currency = line_vals['amount_currency']
|
||||
|
||||
reconciliation_vals = {
|
||||
'line_vals': line_vals,
|
||||
@@ -1088,7 +1094,7 @@ class AccountBankStatementLine(models.Model):
|
||||
payment_vals = self.env['account.payment.register']\
|
||||
.with_context(active_model='account.move.line', active_ids=line.ids)\
|
||||
.create({
|
||||
'amount': abs(line_vals['amount_currency']) if line_vals['currency_id'] else abs(balance),
|
||||
'amount': abs(amount_currency) if line_vals['currency_id'] else abs(balance),
|
||||
'payment_date': self.date,
|
||||
'payment_type': 'inbound' if balance < 0.0 else 'outbound',
|
||||
'journal_id': self.journal_id.id,
|
||||
@@ -1131,8 +1137,21 @@ class AccountBankStatementLine(models.Model):
|
||||
reconciliation_overview.append(reconciliation_vals)
|
||||
|
||||
total_balance += balance
|
||||
total_amount_currency += amount_currency
|
||||
|
||||
# Step 3: If the journal entry is not yet balanced, create an open balance.
|
||||
# Step 3: Fix rounding issue due to currency conversions.
|
||||
# Add the remaining balance on the first encountered line starting with the custom ones.
|
||||
|
||||
if foreign_currency.is_zero(total_amount_currency) and not company_currency.is_zero(total_balance):
|
||||
vals = reconciliation_overview[0]['line_vals']
|
||||
new_balance = vals['debit'] - vals['credit'] - total_balance
|
||||
vals.update({
|
||||
'debit': new_balance if new_balance > 0.0 else 0.0,
|
||||
'credit': -new_balance if new_balance < 0.0 else 0.0,
|
||||
})
|
||||
total_balance = 0.0
|
||||
|
||||
# Step 4: If the journal entry is not yet balanced, create an open balance.
|
||||
|
||||
if self.company_currency_id.round(total_balance):
|
||||
counterpart_vals = {
|
||||
|
||||
@@ -1498,3 +1498,54 @@ class TestAccountBankStatementLine(TestAccountBankStatementCommon):
|
||||
'amount_residual_currency': 0.0,
|
||||
},
|
||||
])
|
||||
|
||||
def test_conversion_rate_rounding_issue(self):
|
||||
''' Ensure the reconciliation is well handling the rounding issue due to multiple currency conversion rates.
|
||||
|
||||
In this test, the resulting journal entry after reconciliation is:
|
||||
{'amount_currency': 7541.66, 'debit': 6446.97, 'credit': 0.0}
|
||||
{'amount_currency': 226.04, 'debit': 193.22, 'credit': 0.0}
|
||||
{'amount_currency': -7767.70, 'debit': 0.0, 'credit': 6640.19}
|
||||
... but 226.04 / 1.1698 = 193.23. In this situation, 0.01 has been removed from this write-off line in order to
|
||||
avoid an unecessary open-balance line being an exchange difference issue.
|
||||
'''
|
||||
self.bank_journal_2.currency_id = self.currency_2
|
||||
self.currency_data['rates'][-1].rate = 1.1698
|
||||
|
||||
statement = self.env['account.bank.statement'].create({
|
||||
'name': 'test_statement',
|
||||
'date': '2017-01-01',
|
||||
'journal_id': self.bank_journal_2.id,
|
||||
'line_ids': [
|
||||
(0, 0, {
|
||||
'date': '2019-01-01',
|
||||
'payment_ref': 'line_1',
|
||||
'partner_id': self.partner_a.id,
|
||||
'amount': 7541.66,
|
||||
}),
|
||||
],
|
||||
})
|
||||
statement.button_post()
|
||||
statement_line = statement.line_ids
|
||||
|
||||
payment = self.env['account.payment'].create({
|
||||
'amount': 7767.70,
|
||||
'date': '2019-01-01',
|
||||
'currency_id': self.currency_2.id,
|
||||
'payment_type': 'inbound',
|
||||
'partner_type': 'customer',
|
||||
})
|
||||
payment.action_post()
|
||||
liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines()
|
||||
self.assertRecordValues(liquidity_lines, [{'amount_currency': 7767.70}])
|
||||
|
||||
statement_line.reconcile([
|
||||
{'id': liquidity_lines.id},
|
||||
{'balance': 226.04, 'account_id': self.company_data['default_account_revenue'].id, 'name': "write-off"},
|
||||
])
|
||||
|
||||
self.assertRecordValues(statement_line.line_ids, [
|
||||
{'amount_currency': 7541.66, 'debit': 6446.97, 'credit': 0.0},
|
||||
{'amount_currency': 226.04, 'debit': 193.22, 'credit': 0.0},
|
||||
{'amount_currency': -7767.70, 'debit': 0.0, 'credit': 6640.19},
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user