2018-08-05 20:33:56 +02:00
|
|
|
# Copyright 2009-2018 Noviat
|
|
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
|
2020-01-29 18:34:31 +01:00
|
|
|
from odoo import _, api, fields, models
|
2018-08-05 20:33:56 +02:00
|
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
|
|
|
|
|
|
class AccountAssetProfile(models.Model):
|
2020-01-29 18:34:31 +01:00
|
|
|
_name = "account.asset.profile"
|
2022-12-24 01:28:55 +01:00
|
|
|
_inherit = "analytic.mixin"
|
2021-02-11 11:48:48 +01:00
|
|
|
_check_company_auto = True
|
2020-01-29 18:34:31 +01:00
|
|
|
_description = "Asset profile"
|
|
|
|
_order = "name"
|
2018-08-05 20:33:56 +02:00
|
|
|
|
2022-04-13 12:18:36 +02:00
|
|
|
name = fields.Char(size=64, required=True, index=True)
|
2018-08-05 20:33:56 +02:00
|
|
|
note = fields.Text()
|
|
|
|
account_asset_id = fields.Many2one(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="account.account",
|
2021-02-11 11:48:48 +01:00
|
|
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Asset Account",
|
2021-02-11 11:48:48 +01:00
|
|
|
check_company=True,
|
2020-01-29 18:34:31 +01:00
|
|
|
required=True,
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
account_depreciation_id = fields.Many2one(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="account.account",
|
2021-02-11 11:48:48 +01:00
|
|
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Depreciation Account",
|
2021-02-11 11:48:48 +01:00
|
|
|
check_company=True,
|
2020-01-29 18:34:31 +01:00
|
|
|
required=True,
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
account_expense_depreciation_id = fields.Many2one(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="account.account",
|
2021-02-11 11:48:48 +01:00
|
|
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Depr. Expense Account",
|
2021-02-11 11:48:48 +01:00
|
|
|
check_company=True,
|
2020-01-29 18:34:31 +01:00
|
|
|
required=True,
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
account_plus_value_id = fields.Many2one(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="account.account",
|
2021-02-11 11:48:48 +01:00
|
|
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
|
|
|
|
check_company=True,
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Plus-Value Account",
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
account_min_value_id = fields.Many2one(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="account.account",
|
2021-02-11 11:48:48 +01:00
|
|
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
|
|
|
|
check_company=True,
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Min-Value Account",
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
account_residual_value_id = fields.Many2one(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="account.account",
|
2021-02-11 11:48:48 +01:00
|
|
|
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
|
|
|
|
check_company=True,
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Residual Value Account",
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
journal_id = fields.Many2one(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="account.journal",
|
2021-02-11 11:48:48 +01:00
|
|
|
domain="[('type', '=', 'general'), ('company_id', '=', company_id)]",
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Journal",
|
2021-02-11 11:48:48 +01:00
|
|
|
check_company=True,
|
2020-01-29 18:34:31 +01:00
|
|
|
required=True,
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
company_id = fields.Many2one(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="res.company",
|
|
|
|
string="Company",
|
|
|
|
required=True,
|
|
|
|
default=lambda self: self._default_company_id(),
|
|
|
|
)
|
2019-08-31 12:14:51 +02:00
|
|
|
group_ids = fields.Many2many(
|
2020-01-29 18:34:31 +01:00
|
|
|
comodel_name="account.asset.group",
|
2019-08-31 12:14:51 +02:00
|
|
|
relation="account_asset_profile_group_rel",
|
|
|
|
column1="profile_id",
|
|
|
|
column2="group_id",
|
2021-02-11 11:48:48 +01:00
|
|
|
check_company=True,
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Asset Groups",
|
|
|
|
)
|
2023-01-26 08:25:04 +01:00
|
|
|
salvage_value = fields.Float(
|
|
|
|
digits="Account",
|
|
|
|
help="The estimated value that an asset will realize upon "
|
|
|
|
"its sale at the end of its useful life.\n"
|
|
|
|
"This value is used to determine the depreciation amounts.",
|
|
|
|
)
|
|
|
|
salvage_type = fields.Selection(
|
|
|
|
selection=[("fixed", "Fixed"), ("percent", "Percentage of Price")]
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
method = fields.Selection(
|
|
|
|
selection=lambda self: self._selection_method(),
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Computation Method",
|
2018-08-05 20:33:56 +02:00
|
|
|
required=True,
|
|
|
|
help="Choose the method to use to compute the depreciation lines.\n"
|
2020-01-29 18:34:31 +01:00
|
|
|
" * Linear: Calculated on basis of: "
|
|
|
|
"Depreciation Base / Number of Depreciations. "
|
|
|
|
"Depreciation Base = Purchase Value - Salvage Value.\n"
|
|
|
|
" * Linear-Limit: Linear up to Salvage Value. "
|
|
|
|
"Depreciation Base = Purchase Value.\n"
|
|
|
|
" * Degressive: Calculated on basis of: "
|
|
|
|
"Residual Value * Degressive Factor.\n"
|
|
|
|
" * Degressive-Linear (only for Time Method = Year): "
|
|
|
|
"Degressive becomes linear when the annual linear "
|
|
|
|
"depreciation exceeds the annual degressive depreciation.\n"
|
|
|
|
" * Degressive-Limit: Degressive up to Salvage Value. "
|
|
|
|
"The Depreciation Base is equal to the asset value.",
|
|
|
|
default="linear",
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
method_number = fields.Integer(
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Number of Years",
|
2018-08-05 20:33:56 +02:00
|
|
|
help="The number of years needed to depreciate your asset",
|
2020-01-29 18:34:31 +01:00
|
|
|
default=5,
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
method_period = fields.Selection(
|
|
|
|
selection=lambda self: self._selection_method_period(),
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Period Length",
|
|
|
|
required=True,
|
|
|
|
default="year",
|
|
|
|
help="Period length for the depreciation accounting entries",
|
|
|
|
)
|
|
|
|
method_progress_factor = fields.Float(string="Degressive Factor", default=0.3)
|
2018-08-05 20:33:56 +02:00
|
|
|
method_time = fields.Selection(
|
|
|
|
selection=lambda self: self._selection_method_time(),
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Time Method",
|
|
|
|
required=True,
|
|
|
|
default="year",
|
2018-08-05 20:33:56 +02:00
|
|
|
help="Choose the method to use to compute the dates and "
|
2020-01-29 18:34:31 +01:00
|
|
|
"number of depreciation lines.\n"
|
|
|
|
" * Number of Years: Specify the number of years "
|
2021-04-19 13:04:19 +02:00
|
|
|
"for the depreciation.\n"
|
|
|
|
" * Number of Depreciations: Fix the number of "
|
|
|
|
"depreciation lines and the time between 2 depreciations.\n",
|
2020-01-29 18:34:31 +01:00
|
|
|
)
|
2019-07-08 13:21:20 +02:00
|
|
|
days_calc = fields.Boolean(
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Calculate by days",
|
2019-07-08 13:21:20 +02:00
|
|
|
default=False,
|
2020-01-29 18:34:31 +01:00
|
|
|
help="Use number of days to calculate depreciation amount",
|
|
|
|
)
|
2019-10-22 09:59:57 +02:00
|
|
|
use_leap_years = fields.Boolean(
|
|
|
|
default=False,
|
|
|
|
help="If not set, the system will distribute evenly the amount to "
|
2020-01-29 18:34:31 +01:00
|
|
|
"amortize across the years, based on the number of years. "
|
|
|
|
"So the amount per year will be the "
|
|
|
|
"depreciation base / number of years.\n "
|
|
|
|
"If set, the system will consider if the current year "
|
|
|
|
"is a leap year. The amount to depreciate per year will be "
|
|
|
|
"calculated as depreciation base / (depreciation end date - "
|
|
|
|
"start date + 1) * days in the current year.",
|
2019-10-22 09:59:57 +02:00
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
prorata = fields.Boolean(
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Prorata Temporis",
|
2020-03-19 13:17:36 +01:00
|
|
|
compute="_compute_prorrata",
|
|
|
|
readonly=False,
|
|
|
|
store=True,
|
2018-08-05 20:33:56 +02:00
|
|
|
help="Indicates that the first depreciation entry for this asset "
|
2020-01-29 18:34:31 +01:00
|
|
|
"has to be done from the depreciation start date instead of "
|
|
|
|
"the first day of the fiscal year.",
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
open_asset = fields.Boolean(
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Skip Draft State",
|
2018-08-05 20:33:56 +02:00
|
|
|
help="Check this if you want to automatically confirm the assets "
|
2020-01-29 18:34:31 +01:00
|
|
|
"of this profile when created by invoices.",
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
asset_product_item = fields.Boolean(
|
2020-01-29 18:34:31 +01:00
|
|
|
string="Create an asset by product item",
|
2018-08-05 20:33:56 +02:00
|
|
|
help="By default during the validation of an invoice, an asset "
|
2020-01-29 18:34:31 +01:00
|
|
|
"is created by invoice line as long as an accounting entry is "
|
|
|
|
"created by invoice line. "
|
|
|
|
"With this setting, an accounting entry will be created by "
|
|
|
|
"product item. So, there will be an asset by product item.",
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
active = fields.Boolean(default=True)
|
2021-07-06 17:34:48 +02:00
|
|
|
allow_reversal = fields.Boolean(
|
|
|
|
"Allow Reversal of journal entries",
|
|
|
|
help="If set, when pressing the Delete/Reverse Move button in a "
|
|
|
|
"posted depreciation line will prompt the option to reverse the "
|
|
|
|
"journal entry, instead of deleting them.",
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
|
|
|
|
@api.model
|
|
|
|
def _default_company_id(self):
|
2020-01-29 18:37:08 +01:00
|
|
|
return self.env.company
|
2018-08-05 20:33:56 +02:00
|
|
|
|
|
|
|
@api.model
|
|
|
|
def _selection_method(self):
|
2020-01-29 18:34:31 +01:00
|
|
|
return [
|
|
|
|
("linear", _("Linear")),
|
|
|
|
("linear-limit", _("Linear up to Salvage Value")),
|
|
|
|
("degressive", _("Degressive")),
|
|
|
|
("degr-linear", _("Degressive-Linear")),
|
|
|
|
("degr-limit", _("Degressive up to Salvage Value")),
|
2018-08-05 20:33:56 +02:00
|
|
|
]
|
|
|
|
|
|
|
|
@api.model
|
|
|
|
def _selection_method_period(self):
|
2020-01-29 18:34:31 +01:00
|
|
|
return [("month", _("Month")), ("quarter", _("Quarter")), ("year", _("Year"))]
|
2018-08-05 20:33:56 +02:00
|
|
|
|
|
|
|
@api.model
|
|
|
|
def _selection_method_time(self):
|
2021-04-19 13:04:19 +02:00
|
|
|
return [
|
|
|
|
("year", _("Number of Years or end date")),
|
|
|
|
("number", _("Number of Depreciations")),
|
|
|
|
]
|
2018-08-05 20:33:56 +02:00
|
|
|
|
2020-03-19 13:17:36 +01:00
|
|
|
@api.constrains("method", "method_time")
|
2018-08-05 20:33:56 +02:00
|
|
|
def _check_method(self):
|
2020-08-12 17:47:23 +02:00
|
|
|
if any(a.method == "degr-linear" and a.method_time != "year" for a in self):
|
2020-03-19 13:17:36 +01:00
|
|
|
raise UserError(
|
|
|
|
_("Degressive-Linear is only supported for Time Method = Year.")
|
|
|
|
)
|
2018-08-05 20:33:56 +02:00
|
|
|
|
2020-03-19 13:17:36 +01:00
|
|
|
@api.depends("method_time")
|
|
|
|
def _compute_prorrata(self):
|
|
|
|
for profile in self:
|
|
|
|
if profile.method_time != "year":
|
|
|
|
profile.prorata = True
|
2018-08-05 20:33:56 +02:00
|
|
|
|
2022-12-24 01:28:55 +01:00
|
|
|
@api.model_create_multi
|
|
|
|
def create(self, vals_list):
|
|
|
|
for vals in vals_list:
|
|
|
|
if vals.get("method_time") != "year" and not vals.get("prorata"):
|
|
|
|
vals["prorata"] = True
|
|
|
|
profile_ids = super().create(vals_list)
|
|
|
|
account_dict = {}
|
|
|
|
for profile_id in profile_ids.filtered(
|
|
|
|
lambda x: not x.account_asset_id.asset_profile_id
|
|
|
|
):
|
|
|
|
account_dict.setdefault(profile_id.account_asset_id, []).append(
|
|
|
|
profile_id.id
|
|
|
|
)
|
|
|
|
for account, profile_list in account_dict.items():
|
|
|
|
account.write({"asset_profile_id": profile_list[-1]})
|
|
|
|
return profile_ids
|
2018-08-05 20:33:56 +02:00
|
|
|
|
|
|
|
def write(self, vals):
|
2020-01-29 18:34:31 +01:00
|
|
|
if vals.get("method_time"):
|
|
|
|
if vals["method_time"] != "year" and not vals.get("prorata"):
|
|
|
|
vals["prorata"] = True
|
2018-10-01 11:57:07 +02:00
|
|
|
res = super().write(vals)
|
|
|
|
# TODO last profile in self is defined as default on the related
|
|
|
|
# account. must be improved.
|
2020-01-29 18:34:31 +01:00
|
|
|
account = self.env["account.account"].browse(vals.get("account_asset_id"))
|
2018-10-01 11:57:07 +02:00
|
|
|
if self and account and not account.asset_profile_id:
|
2020-01-29 18:34:31 +01:00
|
|
|
account.write({"asset_profile_id": self[-1].id})
|
2018-10-01 11:57:07 +02:00
|
|
|
return res
|