Skip to content
Snippets Groups Projects
Commit eef0deb5 authored by Andrea Grazioso (agr-odoo)'s avatar Andrea Grazioso (agr-odoo)
Browse files

[FIX] account: autoreconciliation multicurrency rounding


Have the company currency USD
Enable multicurrency and activate EUR with rate 11.2674
Create an invoice in EUR (i.e 100€)
Create a Bank Journal in EUR:
Have the invoice matching reconciliation model set to autovalidate
Create a bank statement (eur) matching the invoice
Click Post > Reconcile
Statement and Invoice will be automatically reconciled
Check the reconciled entry

Issue: Amount currency of the bank statement move line will be 100.05
This does not occur when manually reconciling and it's due to the high
exchange rate.
When converting the amount of the statement line (8.88) to company currency,
result will be incorrect (100.05)

opw-3196003

closes odoo/odoo#114285

Signed-off-by: default avatarLaurent Smet <las@odoo.com>
Co-authored-by: default avatarLaurent Smet <las@odoo.com>
parent f36c5c8a
No related branches found
No related tags found
No related merge requests found
......@@ -410,18 +410,23 @@ class AccountReconcileModel(models.Model):
:return: A list of dictionary to be passed to the account.bank.statement.line's 'reconcile' method.
'''
self.ensure_one()
journal = st_line.journal_id
company_currency = journal.company_id.currency_id
foreign_currency = st_line.foreign_currency_id or journal.currency_id or company_currency
liquidity_lines, suspense_lines, other_lines = st_line._seek_for_lines()
if st_line.to_check:
st_line_residual = -liquidity_lines.balance
st_line_residual_currency = st_line._prepare_move_line_default_vals()[1]['amount_currency']
elif suspense_lines.account_id.reconcile:
st_line_residual = sum(suspense_lines.mapped('amount_residual'))
st_line_residual_currency = sum(suspense_lines.mapped('amount_residual_currency'))
else:
st_line_residual = sum(suspense_lines.mapped('balance'))
st_line_residual_currency = sum(suspense_lines.mapped('amount_currency'))
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)
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)
......@@ -433,18 +438,30 @@ 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
assigned_amount_currency = -aml.amount_residual_currency
elif has_full_write_off:
assigned_balance = -aml.amount_residual
st_line_residual -= min(-aml.amount_residual, st_line_residual, key=abs)
assigned_amount_currency = -aml.amount_residual_currency
st_line_residual -= min(assigned_balance, st_line_residual, key=abs)
st_line_residual_currency -= min(assigned_amount_currency, st_line_residual_currency, key=abs)
else:
assigned_balance = min(-aml.amount_residual, st_line_residual, key=abs)
assigned_amount_currency = min(-aml.amount_residual_currency, st_line_residual_currency, 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,
})
st_line_residual_currency -= assigned_amount_currency
if aml.currency_id == foreign_currency:
lines_vals_list.append({
'id': aml.id,
'balance': assigned_amount_currency,
'currency_id': foreign_currency.id,
})
else:
lines_vals_list.append({
'id': aml.id,
'balance': assigned_balance,
'currency_id': company_currency.id,
})
write_off_amount = max(aml_total_residual, -st_line_residual_before, key=abs) + st_line_residual_before + st_line_residual
......
......@@ -1161,3 +1161,67 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
[(6, 0, tax.refund_repartition_line_ids[1].tag_ids.ids)],
'The tags of the second repartition line are not inverted'
)
def test_matching_multi_currency_auto_validate(self):
currency = self.setup_multi_currency_data(
default_values={
'name': 'Black Chocolate Coin',
'symbol': '🍫',
'currency_unit_label': 'Black Choco',
'currency_subunit_label': 'Black Cacao Powder',
},
rate2016=11.2674,
rate2017=11.2674,
)['currency']
bank_journal = self.company_data['default_journal_bank'].copy()
bank_journal.currency_id = currency
invoice_line = self._create_invoice_line(100.0, self.partner_1, 'out_invoice', currency=currency)
statement = self.env['account.bank.statement'].create({
'name': 'test_matching_multi_currency_auto_validate',
'journal_id': bank_journal.id,
'line_ids': [
(0, 0, {
'journal_id': bank_journal.id,
'partner_id': self.partner_1.id,
'date': invoice_line.date,
'payment_ref': invoice_line.move_name,
'amount': invoice_line.amount_currency,
}),
],
})
statement_line = statement.line_ids
statement.button_post()
matching_rule = self.env['account.reconcile.model'].create({
'name': 'test_matching_multi_currency_auto_validate',
'rule_type': 'invoice_matching',
'match_partner': True,
'match_partner_ids': [(6, 0, self.partner_1.ids)],
'match_total_amount': True,
'match_total_amount_param': 100.0,
'match_same_currency': True,
'past_months_limit': False,
'auto_reconcile': True,
})
self._check_statement_matching(
matching_rule,
{
statement_line.id: {
'aml_ids': invoice_line.ids,
'model': matching_rule,
'status': 'reconciled',
'partner': self.partner_1,
},
},
statements=statement,
)
self.assertRecordValues(statement_line.line_ids, [
# pylint: disable=bad-whitespace
{'amount_currency': 100.0, 'debit': 8.88, 'credit': 0.0},
{'amount_currency': -100.0, 'debit': 0.0, 'credit': 8.88},
])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment