diff --git a/l10n_it_asset_management/models/__init__.py b/l10n_it_asset_management/models/__init__.py index 9e043ec0841c..9f5013acbc28 100644 --- a/l10n_it_asset_management/models/__init__.py +++ b/l10n_it_asset_management/models/__init__.py @@ -1,7 +1,7 @@ -# Author(s): Silvio Gregorini (silviogregorini@openforce.it) -# Copyright 2019 Openforce Srls Unipersonale (www.openforce.it) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import asset_compute_depreciable_amount + from . import account_account from . import account_fiscal_year from . import account_journal diff --git a/l10n_it_asset_management/models/asset.py b/l10n_it_asset_management/models/asset.py index 949605621e62..f340bd3a5024 100644 --- a/l10n_it_asset_management/models/asset.py +++ b/l10n_it_asset_management/models/asset.py @@ -179,7 +179,9 @@ def onchange_company_currency(self): def onchange_purchase_amount(self): if self.purchase_amount: for dep in self.depreciation_ids: - dep.amount_depreciable = self.purchase_amount * dep.base_coeff + dep.amount_depreciable = dep._get_depreciable_amount( + self.purchase_amount + ) if self.depreciation_ids.mapped("line_ids").filtered( lambda line: line.move_type == "depreciated" ): diff --git a/l10n_it_asset_management/models/asset_category_depreciation_type.py b/l10n_it_asset_management/models/asset_category_depreciation_type.py index 0b81fa7b8061..af1586555895 100644 --- a/l10n_it_asset_management/models/asset_category_depreciation_type.py +++ b/l10n_it_asset_management/models/asset_category_depreciation_type.py @@ -1,5 +1,6 @@ # Author(s): Silvio Gregorini (silviogregorini@openforce.it) # Copyright 2019 Openforce Srls Unipersonale (www.openforce.it) +# Copyright 2024 Simone Rubino - Aion Tech # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import fields, models @@ -7,14 +8,9 @@ class AssetCategoryDepreciationType(models.Model): _name = "asset.category.depreciation.type" + _inherit = "l10n_it_asset_management.compute.depreciable_amount" _description = "Asset Category - Depreciation Type" - base_coeff = fields.Float( - default=1, - help="Coeff to compute depreciable amount from purchase amount", - string="Dep Base Coeff", - ) - category_id = fields.Many2one( "asset.category", ondelete="cascade", @@ -46,8 +42,9 @@ class AssetCategoryDepreciationType(models.Model): def get_depreciation_vals(self, amount_depreciable=0): self.ensure_one() return { - "amount_depreciable": amount_depreciable * self.base_coeff, + "amount_depreciable": self._get_depreciable_amount(amount_depreciable), "base_coeff": self.base_coeff, + "base_max_amount": self.base_max_amount, "mode_id": self.mode_id.id, "percentage": self.percentage, "pro_rata_temporis": self.pro_rata_temporis, diff --git a/l10n_it_asset_management/models/asset_compute_depreciable_amount.py b/l10n_it_asset_management/models/asset_compute_depreciable_amount.py new file mode 100644 index 000000000000..c85b68948536 --- /dev/null +++ b/l10n_it_asset_management/models/asset_compute_depreciable_amount.py @@ -0,0 +1,28 @@ +# Copyright 2024 Simone Rubino - Aion Tech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class AssetComputeDepreciableAmount(models.AbstractModel): + _name = "l10n_it_asset_management.compute.depreciable_amount" + _description = "Compute depreciable amount" + + base_coeff = fields.Float( + default=1, + help="Coeff to compute depreciable amount from purchase amount", + string="Dep Base Coeff", + ) + base_max_amount = fields.Float( + string="Maximum depreciable amount", + ) + + def _get_depreciable_amount(self, base_amount): + """Compute how much of `base_amount` can be depreciated.""" + self.ensure_one() + depreciable_amount = base_amount + if self.base_coeff: + depreciable_amount = base_amount * self.base_coeff + if self.base_max_amount: + depreciable_amount = min(depreciable_amount, self.base_max_amount) + return depreciable_amount diff --git a/l10n_it_asset_management/models/asset_depreciation.py b/l10n_it_asset_management/models/asset_depreciation.py index 78ef4ebbb9ed..25f58c1f98b6 100644 --- a/l10n_it_asset_management/models/asset_depreciation.py +++ b/l10n_it_asset_management/models/asset_depreciation.py @@ -11,6 +11,7 @@ class AssetDepreciation(models.Model): _name = "asset.depreciation" + _inherit = "l10n_it_asset_management.compute.depreciable_amount" _description = "Assets Depreciations" amount_depreciable = fields.Monetary(string="Initial Depreciable Amount") @@ -71,12 +72,6 @@ class AssetDepreciation(models.Model): string="Asset", ) - base_coeff = fields.Float( - default=1, - help="Coeff to compute amount depreciable from purchase amount", - string="Depreciable Base Coeff", - ) - company_id = fields.Many2one( "res.company", readonly=True, related="asset_id.company_id", string="Company" ) @@ -241,10 +236,14 @@ def _compute_state(self): for dep in self: dep.state = dep.get_depreciation_state() - @api.onchange("asset_id", "base_coeff") - def onchange_base_coeff(self): + @api.onchange( + "asset_id", + "base_coeff", + "base_max_amount", + ) + def onchange_depreciable_amount_computation(self): purchase_amount = self.asset_id.purchase_amount - self.amount_depreciable = self.base_coeff * purchase_amount + self.amount_depreciable = self._get_depreciable_amount(purchase_amount) @api.onchange("first_dep_nr") def onchange_normalize_first_dep_nr(self): diff --git a/l10n_it_asset_management/tests/test_assets_management.py b/l10n_it_asset_management/tests/test_assets_management.py index 41f80ac93cc9..6fc438dbd364 100644 --- a/l10n_it_asset_management/tests/test_assets_management.py +++ b/l10n_it_asset_management/tests/test_assets_management.py @@ -523,6 +523,52 @@ def test_entry_out_update_asset(self): depreciation_info.amount_residual, asset.purchase_amount - removed_amount ) + def test_max_amount_depreciable(self): + """ + Set max amount depreciable in category line, + if the asset has a higher amount, the max amount is set as depreciable instead. + """ + # Arrange + purchase_amount = 1000 + max_depreciable_amount = 120 + category = self.asset_category_1 + civ_type = self.env.ref("l10n_it_asset_management.ad_type_civilistico") + category_civ_depreciation_type = category.type_ids.filtered( + lambda x: x.depreciation_type_id == civ_type + ) + category_civ_depreciation_type.update( + { + "base_max_amount": max_depreciable_amount, + } + ) + purchase_invoice = self._create_purchase_invoice( + fields.Date.today(), amount=purchase_amount + ) + # pre-condition + self.assertEqual(purchase_invoice.amount_untaxed, purchase_amount) + self.assertEqual( + category_civ_depreciation_type.base_max_amount, max_depreciable_amount + ) + self.assertGreater(purchase_amount, max_depreciable_amount) + + # Act + asset = self._link_asset_move( + purchase_invoice, + "create", + wiz_values={ + "name": "Test asset", + "category_id": category, + }, + ) + + # Assert + self.assertEqual(asset.category_id, category) + civ_depreciation = asset.depreciation_ids.filtered( + lambda x: x.type_id == civ_type + ) + self.assertEqual(civ_depreciation.base_max_amount, max_depreciable_amount) + self.assertEqual(civ_depreciation.amount_depreciable, max_depreciable_amount) + def test_journal_prev_year(self): """ Previous year depreciation considers depreciation of all previous years diff --git a/l10n_it_asset_management/views/asset.xml b/l10n_it_asset_management/views/asset.xml index 4749ec39dc52..c571480f4b18 100644 --- a/l10n_it_asset_management/views/asset.xml +++ b/l10n_it_asset_management/views/asset.xml @@ -152,6 +152,7 @@ + diff --git a/l10n_it_asset_management/views/asset_category.xml b/l10n_it_asset_management/views/asset_category.xml index 25f52490e213..fd2959baeba0 100644 --- a/l10n_it_asset_management/views/asset_category.xml +++ b/l10n_it_asset_management/views/asset_category.xml @@ -40,6 +40,7 @@ + diff --git a/l10n_it_asset_management/views/asset_depreciation.xml b/l10n_it_asset_management/views/asset_depreciation.xml index 7f6f73bf097e..b0a111599157 100644 --- a/l10n_it_asset_management/views/asset_depreciation.xml +++ b/l10n_it_asset_management/views/asset_depreciation.xml @@ -44,7 +44,19 @@ /> +