[IMP] account_reconcile_oca: Compute the exchange rate properly
parent
5c9e90c8e6
commit
1dd39fc695
|
@ -60,6 +60,19 @@ class AccountBankStatementLine(models.Model):
|
|||
"Percentage Analytic"
|
||||
),
|
||||
)
|
||||
manual_in_currency = fields.Boolean(readonly=True, store=False, prefetch=False)
|
||||
manual_in_currency_id = fields.Many2one(
|
||||
"res.currency", readonly=True, store=False, prefetch=False
|
||||
)
|
||||
manual_amount_in_currency = fields.Monetary(
|
||||
store=False,
|
||||
default=False,
|
||||
prefetch=False,
|
||||
currency_field="manual_in_currency_id",
|
||||
)
|
||||
manual_exchange_counterpart = fields.Boolean(
|
||||
store=False,
|
||||
)
|
||||
manual_model_id = fields.Many2one(
|
||||
"account.reconcile.model",
|
||||
check_company=True,
|
||||
|
@ -268,15 +281,29 @@ class AccountBankStatementLine(models.Model):
|
|||
self.ensure_one()
|
||||
data = self.reconcile_data_info.get("data", [])
|
||||
new_data = []
|
||||
related_move_line_id = False
|
||||
for line in data:
|
||||
if line.get("reference") == self.manual_reference:
|
||||
related_move_line_id = line.get("id")
|
||||
break
|
||||
for line in data:
|
||||
if (
|
||||
self.manual_delete
|
||||
and related_move_line_id
|
||||
and line.get("original_exchange_line_id") == related_move_line_id
|
||||
):
|
||||
# We should remove the related exchange rate line
|
||||
continue
|
||||
if line["reference"] == self.manual_reference:
|
||||
if self.manual_delete:
|
||||
self.update(
|
||||
{
|
||||
"manual_delete": False,
|
||||
"manual_reference": False,
|
||||
"manual_account_id": False,
|
||||
"manual_amount": False,
|
||||
"manual_exchange_counterpart": False,
|
||||
"manual_in_currency_id": False,
|
||||
"manual_in_currency": False,
|
||||
"manual_name": False,
|
||||
"manual_partner_id": False,
|
||||
"manual_line_id": False,
|
||||
|
@ -286,6 +313,7 @@ class AccountBankStatementLine(models.Model):
|
|||
"manual_original_amount": False,
|
||||
"manual_currency_id": False,
|
||||
"analytic_distribution": False,
|
||||
"manual_amount_in_currency": False,
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
@ -293,11 +321,22 @@ class AccountBankStatementLine(models.Model):
|
|||
self.manual_account_id = line["account_id"][0]
|
||||
self.manual_amount = line["amount"]
|
||||
self.manual_currency_id = line["currency_id"]
|
||||
self.manual_in_currency_id = line.get("line_currency_id")
|
||||
self.manual_in_currency = line.get("line_currency_id") and line[
|
||||
"currency_id"
|
||||
] != line.get("line_currency_id")
|
||||
self.manual_amount_in_currency = line.get("currency_amount")
|
||||
self.manual_name = line["name"]
|
||||
self.manual_exchange_counterpart = line.get(
|
||||
"is_exchange_counterpart", False
|
||||
)
|
||||
self.manual_partner_id = (
|
||||
line.get("partner_id") and line["partner_id"][0]
|
||||
)
|
||||
self.manual_line_id = line["id"]
|
||||
manual_line = (
|
||||
self.env["account.move.line"].browse(line["id"]).exists()
|
||||
)
|
||||
self.manual_line_id = manual_line
|
||||
self.analytic_distribution = line.get("analytic_distribution", {})
|
||||
if self.manual_line_id:
|
||||
self.manual_move_id = self.manual_line_id.move_id
|
||||
|
@ -305,6 +344,7 @@ class AccountBankStatementLine(models.Model):
|
|||
self.manual_kind = line["kind"]
|
||||
self.manual_original_amount = line.get("original_amount", 0.0)
|
||||
new_data.append(line)
|
||||
self.update({"manual_delete": False})
|
||||
self.reconcile_data_info = self._recompute_suspense_line(
|
||||
new_data,
|
||||
self.reconcile_data_info["reconcile_auxiliary_id"],
|
||||
|
@ -312,6 +352,17 @@ class AccountBankStatementLine(models.Model):
|
|||
)
|
||||
self.can_reconcile = self.reconcile_data_info.get("can_reconcile", False)
|
||||
|
||||
@api.onchange("manual_amount_in_currency")
|
||||
def _onchange_manual_amount_in_currency(self):
|
||||
if self.manual_line_id.exists() and self.manual_line_id:
|
||||
self.manual_amount = self.manual_in_currency_id._convert(
|
||||
self.manual_amount_in_currency,
|
||||
self.company_id.currency_id,
|
||||
self.company_id,
|
||||
self.manual_line_id.date,
|
||||
)
|
||||
self._onchange_manual_reconcile_vals()
|
||||
|
||||
@api.onchange(
|
||||
"manual_account_id",
|
||||
"manual_partner_id",
|
||||
|
@ -357,6 +408,23 @@ class AccountBankStatementLine(models.Model):
|
|||
)
|
||||
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"
|
||||
):
|
||||
# Now, we should edit the amount of the exchange rate
|
||||
amount = self._get_exchange_rate_amount(
|
||||
self.manual_amount,
|
||||
self.manual_amount_in_currency,
|
||||
self.manual_line_id.currency_id,
|
||||
self.manual_line_id,
|
||||
)
|
||||
line.update(
|
||||
{
|
||||
"amount": amount,
|
||||
"credit": -amount if amount < 0 else 0.0,
|
||||
"debit": amount if amount > 0 else 0.0,
|
||||
}
|
||||
)
|
||||
new_data.append(line)
|
||||
self.reconcile_data_info = self._recompute_suspense_line(
|
||||
new_data,
|
||||
|
@ -485,6 +553,11 @@ class AccountBankStatementLine(models.Model):
|
|||
reconcile_auxiliary_id,
|
||||
self.manual_reference,
|
||||
)
|
||||
else:
|
||||
other_lines = (
|
||||
other_lines.matched_credit_ids.credit_move_id
|
||||
| other_lines.matched_debit_ids.debit_move_id
|
||||
)
|
||||
for line in other_lines:
|
||||
reconcile_auxiliary_id, lines = self._get_reconcile_line(
|
||||
line, "other", from_unreconcile=from_unreconcile
|
||||
|
@ -504,7 +577,7 @@ class AccountBankStatementLine(models.Model):
|
|||
self.ensure_one()
|
||||
self.reconcile_mode = self.journal_id.reconcile_mode
|
||||
result = getattr(self, "_reconcile_bank_line_%s" % self.reconcile_mode)(
|
||||
self.reconcile_data_info["data"]
|
||||
self._prepare_reconcile_line_data(self.reconcile_data_info["data"])
|
||||
)
|
||||
self.reconcile_data_info = False
|
||||
return result
|
||||
|
@ -713,9 +786,37 @@ class AccountBankStatementLine(models.Model):
|
|||
continue
|
||||
getattr(
|
||||
record, "_reconcile_bank_line_%s" % record.journal_id.reconcile_mode
|
||||
)(data["data"])
|
||||
)(self._prepare_reconcile_line_data(data["data"]))
|
||||
return result
|
||||
|
||||
def _prepare_reconcile_line_data(self, lines):
|
||||
new_lines = []
|
||||
reverse_lines = {}
|
||||
for line in lines:
|
||||
if not line.get("id") and not line.get("original_exchange_line_id"):
|
||||
new_lines.append(line)
|
||||
elif not line.get("original_exchange_line_id"):
|
||||
reverse_lines[line["id"]] = line
|
||||
for line in lines:
|
||||
if line.get("original_exchange_line_id"):
|
||||
reverse_lines[line["original_exchange_line_id"]].update(
|
||||
{
|
||||
"amount": reverse_lines[line["original_exchange_line_id"]][
|
||||
"amount"
|
||||
]
|
||||
+ line["amount"],
|
||||
"credit": reverse_lines[line["original_exchange_line_id"]][
|
||||
"credit"
|
||||
]
|
||||
+ line["credit"],
|
||||
"debit": reverse_lines[line["original_exchange_line_id"]][
|
||||
"debit"
|
||||
]
|
||||
+ line["debit"],
|
||||
}
|
||||
)
|
||||
return new_lines + list(reverse_lines.values())
|
||||
|
||||
def button_manual_reference_full_paid(self):
|
||||
self.ensure_one()
|
||||
if not self.reconcile_data_info["manual_reference"]:
|
||||
|
@ -801,6 +902,17 @@ class AccountBankStatementLine(models.Model):
|
|||
new_vals += rates
|
||||
return reconcile_auxiliary_id, new_vals
|
||||
|
||||
def _get_exchange_rate_amount(self, amount, currency_amount, currency, line):
|
||||
return (
|
||||
currency._convert(
|
||||
currency_amount,
|
||||
self.company_id.currency_id,
|
||||
self.company_id,
|
||||
self.date,
|
||||
)
|
||||
- amount
|
||||
)
|
||||
|
||||
def _compute_exchange_rate(
|
||||
self,
|
||||
vals,
|
||||
|
@ -815,18 +927,17 @@ class AccountBankStatementLine(models.Model):
|
|||
if not foreign_currency or self.is_reconciled:
|
||||
return reconcile_auxiliary_id, False
|
||||
currency = self.env["res.currency"].browse(vals["line_currency_id"])
|
||||
amount = currency._convert(
|
||||
vals["currency_amount"],
|
||||
self.company_id.currency_id,
|
||||
self.company_id,
|
||||
self.date,
|
||||
) - vals.get("amount", 0)
|
||||
amount = self._get_exchange_rate_amount(
|
||||
vals.get("amount", 0), vals.get("currency_amount", 0), currency, line
|
||||
)
|
||||
if currency.is_zero(amount):
|
||||
return reconcile_auxiliary_id, False
|
||||
account = self.company_id.expense_currency_exchange_account_id
|
||||
if amount < 0:
|
||||
account = self.company_id.income_currency_exchange_account_id
|
||||
data = {
|
||||
"is_exchange_counterpart": True,
|
||||
"original_exchange_line_id": line.id,
|
||||
"reference": "reconcile_auxiliary;%s" % reconcile_auxiliary_id,
|
||||
"id": False,
|
||||
"account_id": account.name_get()[0],
|
||||
|
|
|
@ -1020,6 +1020,11 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|||
self.assertTrue(bank_stmt_line.can_reconcile)
|
||||
bank_stmt_line.reconcile_bank_line()
|
||||
self.assertEqual(0, inv1.amount_residual)
|
||||
self.assertTrue(
|
||||
inv1.line_ids.filtered(
|
||||
lambda line: line.account_id.account_type == "asset_receivable"
|
||||
).full_reconcile_id
|
||||
)
|
||||
|
||||
def test_journal_foreign_currency_change(self):
|
||||
self.env["res.currency.rate"].create(
|
||||
|
|
|
@ -258,16 +258,22 @@
|
|||
<group>
|
||||
<group>
|
||||
<field name="manual_line_id" invisible="1" />
|
||||
<field
|
||||
name="manual_exchange_counterpart"
|
||||
invisible="1"
|
||||
/>
|
||||
<field name="manual_in_currency_id" invisible="1" />
|
||||
<field name="manual_in_currency" invisible="1" />
|
||||
<field name="manual_kind" invisible="1" />
|
||||
<field
|
||||
name="manual_account_id"
|
||||
string="Account"
|
||||
readonly="manual_reference == False or is_reconciled == True or manual_line_id != False"
|
||||
modifiers="{'readonly': ['|', '|', '|', ('manual_exchange_counterpart', '=', True),('manual_reference', '=', False), ('is_reconciled', '=', True), ('manual_line_id', '!=', False)]}"
|
||||
/>
|
||||
<field
|
||||
name="manual_partner_id"
|
||||
string="Partner"
|
||||
readonly="manual_reference == False or is_reconciled == True or (manual_line_id != False and manual_kind != 'liquidity')"
|
||||
modifiers="{'readonly': ['|', '|', '|', ('manual_exchange_counterpart', '=', True),('manual_reference', '=', False), ('is_reconciled', '=', True), '&', ('manual_line_id', '!=', False), ('manual_kind', '!=', 'liquidity')]}"
|
||||
/>
|
||||
<field
|
||||
name="analytic_distribution"
|
||||
|
@ -282,12 +288,17 @@
|
|||
<field
|
||||
name="manual_name"
|
||||
string="Name"
|
||||
readonly="manual_reference == False or is_reconciled == True or (manual_line_id != False and manual_kind != 'liquidity')"
|
||||
modifiers="{'readonly': ['|', '|', '|', ('manual_exchange_counterpart', '=', True), ('manual_reference', '=', False), ('is_reconciled', '=', True), '&', ('manual_line_id', '!=', False), ('manual_kind', '!=', 'liquidity')]}"
|
||||
/>
|
||||
<field
|
||||
name="manual_amount_in_currency"
|
||||
string="Amount in Currency"
|
||||
modifiers="{'invisible': [('manual_in_currency', '=', False)], 'readonly': ['|', '|', ('manual_exchange_counterpart', '=', True), ('manual_reference', '=', False), ('is_reconciled', '=', True)]}"
|
||||
/>
|
||||
<field
|
||||
name="manual_amount"
|
||||
string="Amount"
|
||||
readonly="manual_reference == False or is_reconciled == True"
|
||||
modifiers="{'readonly': ['|', '|', ('manual_exchange_counterpart', '=', True), ('manual_reference', '=', False), ('is_reconciled', '=', True)]}"
|
||||
/>
|
||||
<field name="manual_currency_id" invisible="1" />
|
||||
<field name="manual_original_amount" invisible="1" />
|
||||
|
|
Loading…
Reference in New Issue