Skip to content

Commit

Permalink
[FIX] partner update from reconciliation widget
Browse files Browse the repository at this point in the history
We cant to avoid to change amounts on accounting entries during the reconciliation process. One of the goal is to avoid a following case :
The statement line is created in a foreign currency journal, later, the rate is updated in Odoo.
During reconciliation process, the partner is set on liquidity line, the accounting entries are synchronized and the balance changes.
  • Loading branch information
florian-dacosta committed Feb 5, 2025
1 parent 2296473 commit 976fc59
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 43 deletions.
82 changes: 39 additions & 43 deletions account_reconcile_oca/models/account_bank_statement_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,8 @@ def _onchange_manual_reconcile_vals(self):
line["kind"] if line["kind"] != "suspense" else "other"
)
line.update(line_vals)
if line["kind"] == "liquidity":
self._update_move_partner()
if self.manual_line_id and self.manual_line_id.id == line.get(
"original_exchange_line_id"
):
Expand All @@ -522,6 +524,11 @@ def _onchange_manual_reconcile_vals(self):
)
self.can_reconcile = self.reconcile_data_info.get("can_reconcile", False)

def _update_move_partner(self):
if self.partner_id == self.manual_partner_id:
return
self.partner_id = self.manual_partner_id

@api.depends("reconcile_data", "is_reconciled")
def _compute_reconcile_data_info(self):
for record in self:
Expand Down Expand Up @@ -968,61 +975,49 @@ def create(self, mvals):
)(self._prepare_reconcile_line_data(data["data"]))
return result

def _synchronize_to_moves_custom(self, changed_fields):
"""Similar process to what _synchronize_to_moves() method would do but without
the relative to all the changed_fields, we just need to update partner_id.
We precisely do not do an onchange of self.partner_id = self.manual_partner_id
to avoid making all those unnecessary changes, but we need to apply this
change to the account.move and the lines without side effects.
A change of manual_partner_id that has been reconciled should NOT change the
values of the account.move lines.
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):

# we actually check reconcile_data to find the partner of the liquidity lines
# because the written manual_partner_id is not always related to the liquidity
# line...
if not any(f_name in changed_fields for f_name in ("reconcile_data",)):
return

for st_line in self.with_context(skip_account_move_synchronization=True):
data = st_line.reconcile_data_info.get("data", [])
partner_id = False
for line_data in data:
if line_data["kind"] == "liquidity":
partner_id = (
line_data.get("partner_id")
and line_data.get("partner_id")[0]
or False
)
break
if st_line.partner_id.id != partner_id:
(
liquidity_lines,
suspense_lines,
_other_lines,
) = st_line._seek_for_lines()
line_vals = {"partner_id": partner_id}
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.id != partner_id:
st_line_vals["partner_id"] = partner_id
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)
st_line.write({"partner_id": partner_id})

def _synchronize_to_moves(self, changed_fields):
"""We take advantage of this method to call the custom method that does
specific things. Also, if something is changed, we will re-define
reconcile_data_info to make the data consistent (for example, if debit/credit
has changed by applying a different rate).
"""
super()._synchronize_to_moves(changed_fields=changed_fields)
self._synchronize_to_moves_custom(changed_fields)
if self._context.get("skip_account_move_synchronization"):
return
else:
super()._synchronize_to_moves(changed_fields=changed_fields)

if not any(
field_name in changed_fields
Expand All @@ -1036,8 +1031,9 @@ def _synchronize_to_moves(self, changed_fields):
)
):
return

for st_line in self.with_context(skip_account_move_synchronization=True):
# 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

Expand Down
12 changes: 12 additions & 0 deletions account_reconcile_oca/tests/test_bank_account_reconcile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1297,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 @@ -1310,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

0 comments on commit 976fc59

Please sign in to comment.