[FIX] account: Fix reconciliation with very tiny rate with one foreign currency

Suppose a very tiny rate 1:10000.
l1 is expressed in company currency and has an amount of -10.
l2 is expressed in foreign currency and has 1000000 in company currency for 100 in foreign currency.

The reconciliation is made in foreign currency but there is nothing left to reconcile after converting
-10 to the foreign currency because -10 / 10000 = 0.0001 ~= 0.0
So no partial is created.

After this fix, the reconciliation fallbacks to a reconciliation in company currency if there is nothing
left to reconcile after applying the rate.

closes odoo/odoo#132304

Issue: 128234
X-original-commit: 359710c7d51ee2b7510cae59cec5b728226a26c1
Signed-off-by: Brice Bartoletti (bib) <bib@odoo.com>
Signed-off-by: Laurent Smet (las) <las@odoo.com>
This commit is contained in:
Laurent Smet
2023-08-19 04:09:02 +02:00
parent 6a3f65ff63
commit fd910639da
2 changed files with 36 additions and 4 deletions
+6 -4
View File
@@ -1659,10 +1659,12 @@ class AccountMoveLine(models.Model):
and not has_zero_residual \
and counterpart_currency != company_currency:
rate = get_odoo_rate(aml, counterpart_currency)
available_residual_per_currency[counterpart_currency] = {
'residual': counterpart_currency.round(remaining_amount * rate),
'rate': rate,
}
residual_in_foreign_curr = counterpart_currency.round(remaining_amount * rate)
if not counterpart_currency.is_zero(residual_in_foreign_curr):
available_residual_per_currency[counterpart_currency] = {
'residual': residual_in_foreign_curr,
'rate': rate,
}
elif currency == counterpart_currency \
and currency != company_currency \
and not has_zero_residual_currency:
@@ -40,6 +40,12 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
'currency_unit_label': 'Diamond',
'currency_subunit_label': 'Carbon',
}, rate2016=6.0, rate2017=4.0)
cls.currency_data_3 = cls.setup_multi_currency_data(default_values={
'name': 'Sand',
'symbol': 'S',
'currency_unit_label': 'Sand',
'currency_subunit_label': 'Sand',
}, rate2016=0.0001, rate2017=0.00001)
# ==== Cash Basis Taxes setup ====
@@ -1150,6 +1156,30 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
{'amount_residual': 40.0, 'amount_residual_currency': 40.0, 'reconciled': False},
])
def test_reconcile_one_foreign_currency_fallback_company_currency(self):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data_3['currency']
line_1 = self.create_line_for_reconciliation(-10.0, -10.0, comp_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(1000000.0, 100.0, foreign_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
partials = self._get_partials(amls)
self.assertRecordValues(partials, [{
'amount': 10.0,
'debit_amount_currency': 0.001,
'credit_amount_currency': 10.0,
'debit_move_id': line_2.id,
'credit_move_id': line_1.id,
}])
self.assertFalse(partials.exchange_move_id)
self.assertRecordValues(line_1 + line_2, [
{'amount_residual': 0.0, 'amount_residual_currency': 0.0, 'reconciled': True},
{'amount_residual': 999990.0, 'amount_residual_currency': 99.999, 'reconciled': False},
])
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_debit_expense_full_payment(self):
currency = self.currency_data['currency']