[FIX] account_reconcile_model_oca: rounding issue reconciliation
Fix a decimal issue on reconciliation.
Steps:
- Set a reconciliation model with payment tolerance of 2%
- Create an invoice for $1210
- Create a bank stmt with a line for $1185.80
-> Reconciliation model is not apply
This is because of a decimal issue when calculating
the residual balance after reconciliation, leading to
the difference being 2.000000000000004% instead of 2%.
Related to d33e98b141
pull/819/head
parent
92580c31aa
commit
c533e46623
|
@ -701,7 +701,9 @@ class AccountReconcileModel(models.Model):
|
||||||
for aml_values in amls_values_list
|
for aml_values in amls_values_list
|
||||||
)
|
)
|
||||||
sign = 1 if st_line_amount_curr > 0.0 else -1
|
sign = 1 if st_line_amount_curr > 0.0 else -1
|
||||||
amount_curr_after_rec = sign * (amls_amount_curr + st_line_amount_curr)
|
amount_curr_after_rec = st_line_currency.round(
|
||||||
|
sign * (amls_amount_curr + st_line_amount_curr)
|
||||||
|
)
|
||||||
|
|
||||||
# The statement line will be fully reconciled.
|
# The statement line will be fully reconciled.
|
||||||
if st_line_currency.is_zero(amount_curr_after_rec):
|
if st_line_currency.is_zero(amount_curr_after_rec):
|
||||||
|
@ -720,7 +722,10 @@ class AccountReconcileModel(models.Model):
|
||||||
# amount doesn't exceed the tolerance.
|
# amount doesn't exceed the tolerance.
|
||||||
if (
|
if (
|
||||||
self.payment_tolerance_type == "fixed_amount"
|
self.payment_tolerance_type == "fixed_amount"
|
||||||
and -amount_curr_after_rec <= self.payment_tolerance_param
|
and st_line_currency.compare_amounts(
|
||||||
|
-amount_curr_after_rec, self.payment_tolerance_param
|
||||||
|
)
|
||||||
|
<= 0
|
||||||
):
|
):
|
||||||
return {"allow_write_off", "allow_auto_reconcile"}
|
return {"allow_write_off", "allow_auto_reconcile"}
|
||||||
|
|
||||||
|
@ -730,7 +735,10 @@ class AccountReconcileModel(models.Model):
|
||||||
) * 100.0
|
) * 100.0
|
||||||
if (
|
if (
|
||||||
self.payment_tolerance_type == "percentage"
|
self.payment_tolerance_type == "percentage"
|
||||||
and reconciled_percentage_left <= self.payment_tolerance_param
|
and st_line_currency.compare_amounts(
|
||||||
|
reconciled_percentage_left, self.payment_tolerance_param
|
||||||
|
)
|
||||||
|
<= 0
|
||||||
):
|
):
|
||||||
return {"allow_write_off", "allow_auto_reconcile"}
|
return {"allow_write_off", "allow_auto_reconcile"}
|
||||||
|
|
||||||
|
|
|
@ -508,17 +508,17 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
@freeze_time("2019-01-01")
|
@freeze_time("2019-01-01")
|
||||||
def test_enough_payment_tolerance(self):
|
def test_enough_payment_tolerance(self):
|
||||||
rule = self._create_reconcile_model(
|
rule = self._create_reconcile_model(
|
||||||
payment_tolerance_param=1.0,
|
payment_tolerance_param=2.0,
|
||||||
line_ids=[{}],
|
line_ids=[{}],
|
||||||
)
|
)
|
||||||
|
|
||||||
for inv_type, bsl_sign in (("out_invoice", 1), ("in_invoice", -1)):
|
for inv_type, bsl_sign in (("out_invoice", 1), ("in_invoice", -1)):
|
||||||
invl = self._create_invoice_line(
|
invl = self._create_invoice_line(
|
||||||
1000.0, self.partner_a, inv_type, inv_date="2019-01-01"
|
1210.0, self.partner_a, inv_type, inv_date="2019-01-01"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Enough tolerance to match the invoice line.
|
# Enough tolerance to match the invoice line.
|
||||||
st_line = self._create_st_line(amount=bsl_sign * 990.0)
|
st_line = self._create_st_line(amount=bsl_sign * 1185.80)
|
||||||
self._check_statement_matching(
|
self._check_statement_matching(
|
||||||
rule,
|
rule,
|
||||||
{st_line: {"amls": invl, "model": rule, "status": "write_off"}},
|
{st_line: {"amls": invl, "model": rule, "status": "write_off"}},
|
||||||
|
@ -527,7 +527,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
# The payment amount is higher than the invoice one.
|
# The payment amount is higher than the invoice one.
|
||||||
# However, since the invoice amount is lower than the payment amount,
|
# However, since the invoice amount is lower than the payment amount,
|
||||||
# the tolerance is not checked and the invoice line is matched.
|
# the tolerance is not checked and the invoice line is matched.
|
||||||
st_line = self._create_st_line(amount=bsl_sign * 1010.0)
|
st_line = self._create_st_line(amount=bsl_sign * 1234.20)
|
||||||
self._check_statement_matching(
|
self._check_statement_matching(
|
||||||
rule,
|
rule,
|
||||||
{st_line: {"amls": invl, "model": rule}},
|
{st_line: {"amls": invl, "model": rule}},
|
||||||
|
|
Loading…
Reference in New Issue