Skip to content

Commit

Permalink
[FIX] account_reconcile_oca : foreign currency reconcile with late cu…
Browse files Browse the repository at this point in the history
…rrency rate

It is possible that the statement line in foreign currency is created before the rate of the day is updated in Odoo. In this case we need to take the real rate of the statement line to comput the exchange rate
  • Loading branch information
florian-dacosta authored and etobella committed Oct 9, 2024
1 parent 0553397 commit c810817
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
15 changes: 13 additions & 2 deletions account_reconcile_oca/models/account_bank_statement_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from odoo import Command, _, api, fields, models
from odoo.exceptions import UserError
from odoo.fields import first
from odoo.tools import float_is_zero


Expand Down Expand Up @@ -417,7 +418,11 @@ def _onchange_manual_reconcile_reference(self):

@api.onchange("manual_amount_in_currency")
def _onchange_manual_amount_in_currency(self):
if self.manual_line_id.exists() and self.manual_line_id:
if (
self.manual_line_id.exists()
and self.manual_line_id
and self.manual_kind != "liquidity"
):
self.manual_amount = self.manual_in_currency_id._convert(
self.manual_amount_in_currency,
self.company_id.currency_id,
Expand Down Expand Up @@ -1039,7 +1044,7 @@ def _get_reconcile_line(
return reconcile_auxiliary_id, new_vals

def _get_exchange_rate_amount(self, amount, currency_amount, currency, line):
if self.foreign_currency_id:
if self.foreign_currency_id == currency:
# take real rate of statement line to compute the exchange rate gain/loss
real_rate = self.amount / self.amount_currency
to_amount_journal_currency = currency_amount * real_rate
Expand All @@ -1050,6 +1055,12 @@ def _get_exchange_rate_amount(self, amount, currency_amount, currency, line):
self.date,
)
to_amount = self.company_id.currency_id.round(to_amount_company_currency)
elif self.currency_id == currency and not self.foreign_currency_id:
liquidity_lines, _suspense_lines, _other_lines = self._seek_for_lines()
real_rate = (
first(liquidity_lines).balance / first(liquidity_lines).amount_currency
)
to_amount = self.company_id.currency_id.round(currency_amount * real_rate)
else:
to_amount = currency._convert(

Check warning on line 1065 in account_reconcile_oca/models/account_bank_statement_line.py

View check run for this annotation

Codecov / codecov/patch

account_reconcile_oca/models/account_bank_statement_line.py#L1065

Added line #L1065 was not covered by tests
currency_amount,
Expand Down
72 changes: 72 additions & 0 deletions account_reconcile_oca/tests/test_bank_account_reconcile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1183,3 +1183,75 @@ def test_invoice_foreign_currency_change(self):
self.assertFalse(f.add_account_move_line_id)
self.assertTrue(f.can_reconcile)
self.assertEqual(3, len(f.reconcile_data_info["data"]))

def test_invoice_foreign_currency_late_change_of_rate(self):
# Test we can reconcile lines in foreign currency even if the rate was updated
# late in odoo, meaning the statement line was created and the rate was updated
# in odoo after that.
self.env["res.currency.rate"].create(
{
"currency_id": self.env.ref("base.USD").id,
"name": time.strftime("%Y-07-14"),
"rate": 1.15,
}
)
self.env["res.currency.rate"].create(
{
"currency_id": self.env.ref("base.USD").id,
"name": time.strftime("%Y-07-15"),
"rate": 1.2,
}
)
inv1 = self._create_invoice(
currency_id=self.currency_usd_id,
invoice_amount=100,
date_invoice=time.strftime("%Y-07-14"),
auto_validate=True,
)
bank_stmt = self.acc_bank_stmt_model.create(
{
"journal_id": self.bank_journal_usd.id,
"date": time.strftime("%Y-07-15"),
"name": "test",
}
)
bank_stmt_line = self.acc_bank_stmt_line_model.create(
{
"name": "testLine",
"journal_id": self.bank_journal_usd.id,
"statement_id": bank_stmt.id,
"amount": 100,
"date": time.strftime("%Y-07-16"),
}
)
# rate of 07-16 is create after the statement line, meaning the rate of the
# statement line is the one of the 07-15
self.env["res.currency.rate"].create(
{
"currency_id": self.env.ref("base.USD").id,
"name": time.strftime("%Y-07-16"),
"rate": 1.25,
}
)
with Form(
bank_stmt_line,
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
) as f:
line = f.reconcile_data_info["data"][0]
self.assertEqual(
line["currency_amount"],
100,
)
self.assertEqual(
line["amount"],
83.33,
)
f.manual_reference = "account.move.line;%s" % line["id"]
# simulate click on statement line, check amount does not recompute
self.assertEqual(f.manual_amount, 83.33)
f.add_account_move_line_id = inv1.line_ids.filtered(
lambda l: l.account_id.account_type == "asset_receivable"
)
self.assertEqual(3, len(f.reconcile_data_info["data"]))
self.assertTrue(f.can_reconcile)
self.assertEqual(f.reconcile_data_info["data"][-1]["amount"], 3.63)

0 comments on commit c810817

Please sign in to comment.