commit
1836d31cc9
|
@ -9,7 +9,7 @@ from dateutil.relativedelta import relativedelta
|
|||
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):
|
||||
|
@ -340,6 +340,28 @@ class AccountBankStatementLine(models.Model):
|
|||
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,
|
||||
|
@ -953,6 +975,68 @@ class AccountBankStatementLine(models.Model):
|
|||
)(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()
|
||||
|
||||
def _prepare_reconcile_line_data(self, lines):
|
||||
new_lines = []
|
||||
reverse_lines = {}
|
||||
|
|
|
@ -892,6 +892,7 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|||
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
|
||||
|
@ -1296,6 +1297,7 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|||
"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",
|
||||
|
@ -1309,6 +1311,17 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue