Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16][account_reconcile_oca] FIX amounts inconsistencies between statement line reconcile_data and accounting entries #784

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 85 additions & 1 deletion account_reconcile_oca/models/account_bank_statement_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,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
from odoo.tools import float_compare, float_is_zero


class AccountBankStatementLine(models.Model):
Expand Down Expand Up @@ -340,6 +340,28 @@
or self.analytic_distribution != line.get("analytic_distribution", False)
)

def _check_reconcile_data_changed(self):
self.ensure_one()
data = self.reconcile_data_info.get("data", [])
liquidity_lines, _suspense_lines, _other_lines = self._seek_for_lines()
move_amount_cur = sum(liquidity_lines.mapped("amount_currency"))
move_credit = sum(liquidity_lines.mapped("credit"))
move_debit = sum(liquidity_lines.mapped("debit"))
stmt_amount_curr = stmt_debit = stmt_credit = 0.0
for line_data in data:
if line_data["kind"] != "liquidity":
continue
stmt_amount_curr += line_data["currency_amount"]
stmt_debit += line_data["debit"]
stmt_credit += line_data["credit"]
prec = self.currency_id.rounding
return (
float_compare(move_amount_cur, move_amount_cur, precision_rounding=prec)
!= 0
or float_compare(move_credit, stmt_credit, precision_rounding=prec) != 0
or float_compare(move_debit, stmt_debit, precision_rounding=prec) != 0
)

def _get_manual_delete_vals(self):
return {
"manual_reference": False,
Expand Down Expand Up @@ -953,6 +975,68 @@
)(self._prepare_reconcile_line_data(data["data"]))
return result

def _synchronize_to_moves(self, changed_fields):
"""We want to avoid to change stuff (mainly amounts ) in accounting entries
when some changes happen in the reconciliation widget. The only change
(among the fields triggering the synchronization) possible from the
reconciliation widget is the partner_id field.

So, in case of change on partner_id field we do not call super but make
only the required change (relative to partner) on accounting entries.

And if something else changes, we then re-define reconcile_data_info to
make the data consistent (for example, if debit/credit has changed by
applying a different rate or even if there was a correction on statement
line amount).
"""
if self._context.get("skip_account_move_synchronization"):
return
if "partner_id" in changed_fields and not any(
field_name in changed_fields
for field_name in (
"payment_ref",
"amount",
"amount_currency",
"foreign_currency_id",
"currency_id",
)
):
for st_line in self.with_context(skip_account_move_synchronization=True):

(
liquidity_lines,
suspense_lines,
_other_lines,
) = st_line._seek_for_lines()
line_vals = {"partner_id": st_line.partner_id}
line_ids_commands = [(1, liquidity_lines.id, line_vals)]
if suspense_lines:
line_ids_commands.append((1, suspense_lines.id, line_vals))
st_line_vals = {"line_ids": line_ids_commands}
if st_line.move_id.partner_id != st_line.partner_id:
st_line_vals["partner_id"] = st_line.partner_id.id
st_line.move_id.write(st_line_vals)
else:
super()._synchronize_to_moves(changed_fields=changed_fields)

if not any(
field_name in changed_fields
for field_name in (
"payment_ref",
"amount",
"amount_currency",
"foreign_currency_id",
"currency_id",
"partner_id",
)
):
return
# reset reconcile_data_info if amounts are not consistent anymore with the
# amounts of the accounting entries
for st_line in self:
if st_line._check_reconcile_data_changed():
st_line.reconcile_data_info = st_line._default_reconcile_data()

Check warning on line 1038 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#L1038

Added line #L1038 was not covered by tests

def _prepare_reconcile_line_data(self, lines):
new_lines = []
reverse_lines = {}
Expand Down
13 changes: 13 additions & 0 deletions account_reconcile_oca/tests/test_bank_account_reconcile.py
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,7 @@ def test_widget_invoice_change_partner(self):
self.assertFalse(f.partner_id)
f.manual_reference = "account.move.line;%s" % liquidity_lines.id
f.manual_partner_id = inv1.partner_id
f.save()
self.assertEqual(f.partner_id, inv1.partner_id)
bank_stmt_line.clean_reconcile()
# As we have a set a partner, the cleaning should assign the invoice automatically
Expand Down Expand Up @@ -1296,6 +1297,7 @@ def test_invoice_foreign_currency_late_change_of_rate(self):
"rate": 1.25,
}
)
liquidity_lines, suspense_lines, other_lines = bank_stmt_line._seek_for_lines()
with Form(
bank_stmt_line,
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
Expand All @@ -1309,6 +1311,17 @@ def test_invoice_foreign_currency_late_change_of_rate(self):
line["amount"],
83.33,
)
# check that adding a partner does not recompute the amounts on accounting
# entries, but is still synchronized with accounting entries
f.manual_reference = "account.move.line;%s" % liquidity_lines.id
f.manual_partner_id = inv1.partner_id
self.assertEqual(f.partner_id, inv1.partner_id)
self.assertEqual(liquidity_lines.debit, 83.33)
f.save()
# check liquidity line did not recompute debit with the new rate with
# partner change
self.assertEqual(liquidity_lines.debit, 83.33)
self.assertEqual(liquidity_lines.partner_id, inv1.partner_id)
f.manual_reference = "account.move.line;%s" % line["id"]
# simulate click on statement line, check amount does not recompute
f.manual_partner_id = inv1.partner_id
Expand Down