Skip to content

Commit

Permalink
Merge PR #259 into 15.0
Browse files Browse the repository at this point in the history
Signed-off-by AaronHForgeFlow
  • Loading branch information
OCA-git-bot committed Sep 12, 2023
2 parents d0c0a35 + f897df4 commit f4fcac8
Show file tree
Hide file tree
Showing 19 changed files with 734 additions and 267 deletions.
2 changes: 2 additions & 0 deletions account_multicurrency_revaluation/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
"security/ir.model.access.csv",
"views/account_view.xml",
"views/account_move_views.xml",
"views/account_move_line_views.xml",
"wizard/print_currency_unrealized_report_view.xml",
"wizard/wizard_currency_revaluation_view.xml",
"wizard/wizard_reverse_currency_revaluation_view.xml",
"report/report.xml",
"report/unrealized_currency_gain_loss.xml",
],
Expand Down
167 changes: 154 additions & 13 deletions account_multicurrency_revaluation/model/account.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Copyright 2012-2018 Camptocamp SA
# Copyright 2020 CorporateHub (https://corporatehub.eu)
# Copyright 2022 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, fields, models
from odoo import _, api, fields, models
from odoo.exceptions import UserError


class AccountAccountLine(models.Model):
Expand All @@ -13,12 +15,72 @@ class AccountAccountLine(models.Model):
gl_revaluated_balance = fields.Float(string="Revaluated Amount")
gl_currency_rate = fields.Float(string="Currency rate")

revaluation_created_line_id = fields.Many2one(
comodel_name="account.move.line",
string="Revaluation Created Line",
readonly=True,
)

revaluation_origin_line_ids = fields.One2many(
comodel_name="account.move.line",
inverse_name="revaluation_created_line_id",
string="Revaluation Origin Lines",
readonly=True,
)
revaluation_origin_line_count = fields.Integer(
compute="_compute_revaluation_origin_line_count"
)

def _compute_revaluation_origin_line_count(self):
for line in self:
line.revaluation_origin_line_count = len(line.revaluation_origin_line_ids)

def action_view_revaluation_origin_lines(self):
self.ensure_one()
action = self.env["ir.actions.act_window"]._for_xml_id(
"account.action_account_moves_all"
)
action["context"] = {}
if len(self.revaluation_origin_line_ids) > 1:
action["domain"] = [("id", "in", self.revaluation_origin_line_ids.ids)]
elif self.revaluation_origin_line_ids:
form_view = [(self.env.ref("account.view_move_line_form").id, "form")]
if "views" in action:
action["views"] = form_view + [
(state, view) for state, view in action["views"] if view != "form"
]
else:
action["views"] = form_view
action["res_id"] = self.revaluation_origin_line_ids.id
else:
action = {"type": "ir.actions.act_window_close"}
return action

def action_view_revaluation_created_line(self):
self.ensure_one()
action = self.env["ir.actions.act_window"]._for_xml_id(
"account.action_account_moves_all"
)
action["context"] = {}
if self.revaluation_created_line_id:
form_view = [(self.env.ref("account.view_move_line_form").id, "form")]
if "views" in action:
action["views"] = form_view + [
(state, view) for state, view in action["views"] if view != "form"
]
else:
action["views"] = form_view
action["res_id"] = self.revaluation_created_line_id.id
else:
action = {"type": "ir.actions.act_window_close"}
return action


class AccountAccount(models.Model):
_inherit = "account.account"

currency_revaluation = fields.Boolean(
string="Allow currency revaluation",
string="Allow Currency Revaluation",
)

_sql_mapping = {
Expand All @@ -36,11 +98,34 @@ def init(self):
[
("user_type_id.id", "in", self._get_revaluation_account_types()),
("currency_revaluation", "=", False),
("user_type_id.include_initial_balance", "=", True),
]
)
accounts.write({"currency_revaluation": True})
return res

def write(self, vals):
if (
"currency_revaluation" in vals
and vals.get("currency_revaluation", False)
and any(
[not x for x in self.mapped("user_type_id.include_initial_balance")]
)
):
raise UserError(
_(
"There is an account that you are editing not having the Bring "
"Balance Forward set, the currency revaluation cannot be applied "
"on these accounts: \n\t - %s"
)
% "\n\t - ".join(
self.filtered(
lambda x: not x.user_type_id.include_initial_balance
).mapped("name")
)
)
return super(AccountAccount, self).write(vals)

def _get_revaluation_account_types(self):
return [
self.env.ref("account.data_account_type_receivable").id,
Expand All @@ -55,14 +140,13 @@ def _onchange_user_type_id(self):
if rec.user_type_id.id in revaluation_accounts:
rec.currency_revaluation = True

def _revaluation_query(self, revaluation_date):
def _revaluation_query(self, revaluation_date, start_date=None):
tables, where_clause, where_clause_params = self.env[
"account.move.line"
]._query_get()
mapping = [
('"account_move_line".', "aml."),
('"account_move_line"', "account_move_line aml"),
('"account_move_line__move_id"', "am"),
("LEFT JOIN", "\n LEFT JOIN"),
(")) AND", "))\n" + " " * 12 + "AND"),
]
Expand All @@ -82,10 +166,12 @@ def _revaluation_query(self, revaluation_date):
aml.currency_id,
aml.debit,
aml.credit,
aml.amount_currency
aml.amount_currency,
aml.id as origin_aml_id
FROM """
+ tables
+ """
LEFT JOIN account_move am ON aml.move_id = am.id
INNER JOIN account_account acc ON aml.account_id = acc.id
INNER JOIN account_account_type aat ON acc.user_type_id = aat.id
LEFT JOIN account_partial_reconcile aprc
Expand All @@ -107,26 +193,32 @@ def _revaluation_query(self, revaluation_date):
WHERE
aml.account_id IN %s
AND aml.date <= %s
"""
+ (("AND aml.date >= %s") if start_date else "")
+ """
AND aml.currency_id IS NOT NULL
AND am.state = 'posted'
AND aml.balance <> 0
"""
+ where_clause
+ """
GROUP BY
aat.type,
aml.id
origin_aml_id
HAVING
aml.full_reconcile_id IS NULL
OR (MAX(amldf.id) IS NULL AND MAX(amlcf.id) IS NULL)
aml.amount_residual_currency <> 0
)
SELECT
account_id as id,
origin_aml_id,
partner_id,
currency_id,"""
+ ", ".join(self._sql_mapping.values())
+ """
FROM amount
GROUP BY
account_id,
origin_aml_id,
currency_id,
partner_id
ORDER BY account_id, partner_id, currency_id"""
Expand All @@ -139,30 +231,79 @@ def _revaluation_query(self, revaluation_date):
revaluation_date,
*where_clause_params,
]
if start_date:
# Insert the value after the revaluation date parameter
params.insert(4, start_date)

return query, params

def compute_revaluations(self, revaluation_date):
query, params = self._revaluation_query(revaluation_date)
def compute_revaluations(self, revaluation_date, start_date=None):
query, params = self._revaluation_query(revaluation_date, start_date)
self.env.cr.execute(query, params)
lines = self.env.cr.dictfetchall()

data = {}
for line in lines:
account_id, currency_id, partner_id = (
account_id, currency_id, partner_id, origin_aml_id = (
line["id"],
line["currency_id"],
line["partner_id"],
line["origin_aml_id"],
)
data.setdefault(account_id, {})
data[account_id].setdefault(partner_id, {})
data[account_id][partner_id].setdefault(currency_id, {})
data[account_id][partner_id][currency_id] = line
# If partially reconciled, we need to adjust the balance according to
# the partially reconciled items on the current line.
origin_aml = self.env["account.move.line"].browse(origin_aml_id)
if origin_aml.matched_debit_ids | origin_aml.matched_credit_ids:
debit_move_ids = origin_aml.matched_debit_ids.mapped("debit_move_id")
credit_move_ids = origin_aml.matched_credit_ids.mapped("credit_move_id")
total_debit = line["debit"] + sum(debit_move_ids.mapped("debit"))
total_credit = line["credit"] + sum(credit_move_ids.mapped("credit"))
total_balance = total_debit - total_credit
total_balance_currency = (
line["foreign_balance"]
+ sum(debit_move_ids.mapped("amount_currency"))
+ sum(credit_move_ids.mapped("amount_currency"))
)
line.update(
{
"debit": round(total_debit, 2),
"credit": round(total_credit, 2),
"balance": round(total_balance, 2),
"foreign_balance": round(total_balance_currency, 2),
}
)
existing_line = data[account_id][partner_id][currency_id]
if existing_line:
data[account_id][partner_id][
currency_id
] = self._merge_currency_revaluation_lines(existing_line, line)
else:
# Convert origin account move lines to list as there can be multiple
line["origin_aml_id"] = [line["origin_aml_id"]]
data[account_id][partner_id][currency_id] = line
return data

@api.model
def _merge_currency_revaluation_lines(self, first_line, second_line):
resulting_line = first_line
resulting_line["origin_aml_id"].append(second_line["origin_aml_id"])
resulting_line["balance"] += second_line["balance"]
resulting_line["debit"] += second_line["debit"]
resulting_line["credit"] += second_line["credit"]
resulting_line["foreign_balance"] += second_line["foreign_balance"]
return resulting_line


class AccountMove(models.Model):
_inherit = "account.move"

revaluation_to_reverse = fields.Boolean(
string="revaluation to reverse", default=False
string="Revaluation to reverse", default=False, readonly=True
)

revaluation_reversed = fields.Boolean(
string="Revaluation reversed", default=False, readonly=True
)
47 changes: 35 additions & 12 deletions account_multicurrency_revaluation/model/res_company.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2012-2018 Camptocamp SA
# Copyright 2022 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models
Expand All @@ -10,35 +11,61 @@ class ResCompany(models.Model):
revaluation_loss_account_id = fields.Many2one(
comodel_name="account.account",
string="Revaluation loss account",
domain=[("internal_type", "=", "other")],
domain=lambda self: [
("company_id", "=", self.env.company.id),
("internal_type", "=", "other"),
("deprecated", "=", False),
],
)
revaluation_gain_account_id = fields.Many2one(
comodel_name="account.account",
string="Revaluation gain account",
domain=[("internal_type", "=", "other")],
domain=lambda self: [
("company_id", "=", self.env.company.id),
("internal_type", "=", "other"),
("deprecated", "=", False),
],
)
revaluation_analytic_account_id = fields.Many2one(
comodel_name="account.analytic.account", string="Revaluation Analytic account"
comodel_name="account.analytic.account",
string="Revaluation Analytic account",
domain=lambda self: [("company_id", "=", self.env.company.id)],
)
provision_bs_loss_account_id = fields.Many2one(
comodel_name="account.account",
string="Provision B.S. loss account",
domain=[("internal_type", "=", "other")],
domain=lambda self: [
("company_id", "=", self.env.company.id),
("internal_type", "=", "other"),
("deprecated", "=", False),
],
)
provision_bs_gain_account_id = fields.Many2one(
comodel_name="account.account",
string="Provision B.S. gain account",
domain=[("internal_type", "=", "other")],
domain=lambda self: [
("company_id", "=", self.env.company.id),
("internal_type", "=", "other"),
("deprecated", "=", False),
],
)
provision_pl_loss_account_id = fields.Many2one(
comodel_name="account.account",
string="Provision P&L loss account",
domain=[("internal_type", "=", "other")],
domain=lambda self: [
("company_id", "=", self.env.company.id),
("internal_type", "=", "other"),
("deprecated", "=", False),
],
)
provision_pl_gain_account_id = fields.Many2one(
comodel_name="account.account",
string="Provision P&L gain account",
domain=[("internal_type", "=", "other")],
domain=lambda self: [
("company_id", "=", self.env.company.id),
("internal_type", "=", "other"),
("deprecated", "=", False),
],
)
provision_pl_analytic_account_id = fields.Many2one(
comodel_name="account.analytic.account", string="Provision P&L Analytic account"
Expand All @@ -48,14 +75,10 @@ class ResCompany(models.Model):
string="Currency gain & loss Default Journal",
domain=[("type", "=", "general")],
)
reversable_revaluations = fields.Boolean(
help="Revaluations entries will be created " 'as "To Be Reversed".',
default=True,
)
auto_post_entries = fields.Boolean(
string="Auto Post Created Entries",
help="If marked, the entries created in the process will be"
"posted automatically.",
" posted automatically.",
default=True,
readonly=False,
)
Loading

0 comments on commit f4fcac8

Please sign in to comment.