diff --git a/l10n_es_account_capital_asset/README.rst b/l10n_es_account_capital_asset/README.rst new file mode 100644 index 000000000..23d4f9cb7 --- /dev/null +++ b/l10n_es_account_capital_asset/README.rst @@ -0,0 +1,65 @@ +===================== +Account Capital Asset +===================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:3ac43149bebc77803d9f32dceaf33197a6fdb57d043b1fcc50ecb717542f48aa + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-NuoBiT%2Fodoo--addons-lightgray.png?logo=github + :target: https://github.com/NuoBiT/odoo-addons/tree/18.0/l10n_es_account_capital_asset + :alt: NuoBiT/odoo-addons + +|badge1| |badge2| |badge3| + +This module adds mapping for capital assets taxes, capital assets +category types and threshold amount on res_config + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* NuoBiT Solutions SL + +Contributors +------------ + +- `NuoBiT `__: + + - Kilian Niubo kniubo@nuobit.com + - Eric Antones eantones@nuobit.com + - Deniz Gallo dgallo@nuobit.com + +Maintainers +----------- + +This module is part of the `NuoBiT/odoo-addons `_ project on GitHub. + +You are welcome to contribute. diff --git a/l10n_es_account_capital_asset/__init__.py b/l10n_es_account_capital_asset/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/l10n_es_account_capital_asset/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/l10n_es_account_capital_asset/__manifest__.py b/l10n_es_account_capital_asset/__manifest__.py new file mode 100644 index 000000000..0d55b2156 --- /dev/null +++ b/l10n_es_account_capital_asset/__manifest__.py @@ -0,0 +1,29 @@ +# Copyright NuoBiT Solutions - Kilian Niubo +# Copyright 2026 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +{ + "name": "Account Capital Asset", + "summary": "This module adds mapping for capital assets taxes, capital assets" + " category types and threshold amount on res_config", + "version": "18.0.1.0.1", + "category": "Accounting", + "author": "NuoBiT Solutions SL", + "website": "https://github.com/NuoBiT/odoo-addons", + "license": "AGPL-3", + "depends": [ + "l10n_es_asset_extension", + ], + "data": [ + "security/ir.model.access.csv", + "security/l10n_es_account_capital_asset_map_tax_security.xml", + "data/account_capital_asset_type_data.xml", + "data/ir_config_parameter.xml", + "views/account_asset.xml", + "views/account_asset_profile_views.xml", + "views/account_capital_asset_map_tax_views.xml", + "views/account_capital_asset_type_view.xml", + "views/res_company_view.xml", + "views/res_config_settings_views.xml", + ], +} diff --git a/l10n_es_account_capital_asset/data/account_capital_asset_type_data.xml b/l10n_es_account_capital_asset/data/account_capital_asset_type_data.xml new file mode 100644 index 000000000..ce0675083 --- /dev/null +++ b/l10n_es_account_capital_asset/data/account_capital_asset_type_data.xml @@ -0,0 +1,19 @@ + + + + + Normal + 5 + + + Terrenos o Edificaciones + 10 + + diff --git a/l10n_es_account_capital_asset/data/ir_config_parameter.xml b/l10n_es_account_capital_asset/data/ir_config_parameter.xml new file mode 100644 index 000000000..53d54def8 --- /dev/null +++ b/l10n_es_account_capital_asset/data/ir_config_parameter.xml @@ -0,0 +1,11 @@ + + + + + l10n_es_account_capital_asset.capital_asset_threshold_amount + 3005.06 + + diff --git a/l10n_es_account_capital_asset/i18n/es.po b/l10n_es_account_capital_asset/i18n/es.po new file mode 100644 index 000000000..e3699d126 --- /dev/null +++ b/l10n_es_account_capital_asset/i18n/es.po @@ -0,0 +1,229 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_account_capital_asset +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-09-29 15:59+0000\n" +"PO-Revision-Date: 2022-09-29 15:59+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: l10n_es_account_capital_asset +#: model:ir.actions.act_window,name:l10n_es_account_capital_asset.l10n_es_account_capital_asset_map_tax_action +#: model:ir.ui.menu,name:l10n_es_account_capital_asset.l10n_es_account_capital_asset_map_tax_menu +msgid "Account Capital Asset Tax Map" +msgstr "Bienes de inversión - Mapeo de impuestos" + +#. module: l10n_es_account_capital_asset +#: model_terms:ir.ui.view,arch_db:l10n_es_account_capital_asset.view_company_aeat_form +msgid "Capital Asset" +msgstr "Bien de inversión" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_res_company__l10n_es_capital_asset_enabled +msgid "L10n ES Capital Asset Enabled" +msgstr "L10n ES - Bienes de inversión activados" + +#. module: l10n_es_account_capital_asset +#: code:addons/l10n_es_account_capital_asset/models/account_capital_asset_type.py:0 +#, python-format +msgid "years" +msgstr "años" + +#. module: l10n_es_account_capital_asset +#: model:ir.actions.act_window,name:l10n_es_account_capital_asset.capital_asset_type_action +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_account_asset__capital_asset_type_id +#: model:ir.ui.menu,name:l10n_es_account_capital_asset.aeat_vat_special_prorrate_capital_asset_type_menu +msgid "Capital Asset Type" +msgstr "Tipo de bien de inversión" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_account_asset_profile__capital_asset_set +msgid "Capital Asset Set" +msgstr "Conjunto de bienes de inversión" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,help:l10n_es_account_capital_asset.field_account_asset_profile__capital_asset_set +msgid "Indicates that this profile is used for a set of capital assets." +msgstr "Indica que este perfil se utiliza para un conjunto de bienes de inversión." + +#. module: l10n_es_account_capital_asset +#: code:addons/l10n_es_account_capital_asset/models/account_asset_profile.py:0 +#, python-format +msgid "" +"A profile for a set of capital assets is not compatible with the 'Product " +"per Asset' option. You cannot have both enabled. Please, select only one of " +"them." +msgstr "Un perfil para un conjunto de bienes de inversión no es compatible " +"con la opción 'Producto por activo'. No puede tener ambos habilitados. " +"Por favor, seleccione solo uno de ellos." + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_account_asset_profile__default_capital_asset_type_id +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_account_asset__default_capital_asset_type_id +msgid "Default Capital Asset Type" +msgstr "Tipo de bien de inversión por defecto" + +#. module: l10n_es_account_capital_asset +#: code:addons/l10n_es_account_capital_asset/models/account_asset.py:0 +#, python-format +msgid "The asset of type ‘%s’ has an unit amount %.2f€ greater than %.2f€, " +"so it is considered a capital asset, but the selected taxes " +"are not of a capital asset type. Please update the taxes " +"accordingly or define the asset type as a set of assets." +msgstr "El activo de tipo ‘%s’ tiene un importe unitario %.2f€ mayor que %.2f€, " +"por lo que se considera un bien de inversión, pero los impuestos seleccionados " +"no son de tipo bien de inversión. Por favor, actualice los impuestos " +"o defina el tipo de activo como un conjunto de activos." + +#. module: l10n_es_account_capital_asset +#: code:addons/l10n_es_account_capital_asset/models/account_asset.py:0 +#, python-format +msgid "The asset of type ‘%s’ has a unit amount %.2f€ lower than %.2f€, " +"so it is not considered a capital asset, " +"but capital asset taxes are selected. Please update the taxes " +"accordingly or define the asset type as a set of assets." +msgstr "El activo de tipo ‘%s’ tiene un importe unitario %.2f€ menor que %.2f€, " +"por lo que no se considera un bien de inversión, " +"pero se han seleccionado impuestos de bienes de inversión. Por favor, actualice los impuestos " +"o defina el tipo de activo como un conjunto de activos." + +#. module: l10n_es_account_capital_asset +#: model:ir.model.constraint,message:l10n_es_account_capital_asset.constraint_l10n_es_account_capital_asset_type_unique_name +msgid "Capital Asset Type name must be unique" +msgstr "El nombre del tipo de bien de inversión debe ser único" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.constraint,message:l10n_es_account_capital_asset.constraint_l10n_es_account_capital_asset_type_unique_period +msgid "Capital Asset Type period must be unique" +msgstr "El periodo del tipo de bien de inversión debe ser único" + +#. module: l10n_es_account_capital_asset +#: model_terms:ir.ui.view,arch_db:l10n_es_account_capital_asset.res_config_settings_view_form +msgid "Capital Assets" +msgstr "Bienes de inversión" + +#. module: l10n_es_account_capital_asset +#: code:addons/l10n_es_account_capital_asset/models/account_asset.py:0 +#, python-format +msgid "" +"Capital asset type must be the same as the one defined in the asset " +"category." +msgstr "El tipo de bien de inversion debe ser el mismo que el definido en la categoria de activo" + +#. module: l10n_es_account_capital_asset +#: model:ir.model,name:l10n_es_account_capital_asset.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: l10n_es_account_capital_asset +#: model:ir.model,name:l10n_es_account_capital_asset.model_res_config_settings +msgid "Config Settings" +msgstr "Opciones de configuración" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax__create_uid +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax__create_date +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax__display_name +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax__id +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type__id +msgid "ID" +msgstr "ID" + +#. module: l10n_es_account_capital_asset +#: code:addons/l10n_es_account_capital_asset/models/account_asset.py:0 +#, python-format +msgid "" +"If Tax Base Amount is greater than %s, capital asset type must be defined." +msgstr "Si el Importe de la Base Imponible es mayor que %s, el tipo de bien de inversión debe ser definido" + +#. module: l10n_es_account_capital_asset +#: code:addons/l10n_es_account_capital_asset/models/account_asset.py:0 +#, python-format +msgid "" +"If Tax Base Amount is less than %s, this asset is not considered as a " +"capital asset so capital asset type mustn't be defined" +msgstr "Si el Importe de la Base Imponible es menor que %s, este activo no es considerado " + "como un bien de inversión, por lo que el tipo de bien de inversión no debería estar definido" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_account_asset____last_update +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_account_asset_profile____last_update +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_account_move____last_update +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_account_move_line____last_update +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax____last_update +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type____last_update +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_res_company____last_update +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_res_config_settings____last_update +msgid "Last Modified on" +msgstr "Última modificación" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax__write_uid +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax__write_date +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,help:l10n_es_account_capital_asset.field_res_config_settings__capital_asset_threshold_amount +msgid "Minimum amount to consider the asset as a capital asset" +msgstr "Mínimo importe para considerar el activo como bien de inversión" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type__name +msgid "Name" +msgstr "Nombre" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_type__period +msgid "Period (years)" +msgstr "Periodo (años)" + +#. module: l10n_es_account_capital_asset +#: code:addons/l10n_es_account_capital_asset/models/account_capital_asset_type.py:0 +#, python-format +msgid "Period must be greater than 0." +msgstr "El periodo debe ser mayor que 0" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax__tax_dest_id +msgid "Replacement Tax" +msgstr "Impuesto de reemplazo" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_l10n_es_account_capital_asset_map_tax__tax_src_id +msgid "Tax Source" +msgstr "Impuesto original" + +#. module: l10n_es_account_capital_asset +#: model:ir.model.fields,field_description:l10n_es_account_capital_asset.field_res_config_settings__capital_asset_threshold_amount +msgid "Threshold Amount" +msgstr "Umbral de importe" diff --git a/l10n_es_account_capital_asset/migrations/18.0.1.0.1/pre-migration.py b/l10n_es_account_capital_asset/migrations/18.0.1.0.1/pre-migration.py new file mode 100644 index 000000000..1b53ed4ec --- /dev/null +++ b/l10n_es_account_capital_asset/migrations/18.0.1.0.1/pre-migration.py @@ -0,0 +1,18 @@ +# Copyright 2026 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from openupgradelib import openupgrade + +from odoo.tools.sql import column_exists + +_column_renames = { + "account_asset_profile": [ + ("capital_asset_type_id", "default_capital_asset_type_id"), + ], +} + + +@openupgrade.migrate() +def migrate(env, version): + if column_exists(env.cr, "account_asset_profile", "capital_asset_type_id"): + openupgrade.rename_columns(env.cr, _column_renames) diff --git a/l10n_es_account_capital_asset/models/__init__.py b/l10n_es_account_capital_asset/models/__init__.py new file mode 100644 index 000000000..8b218f273 --- /dev/null +++ b/l10n_es_account_capital_asset/models/__init__.py @@ -0,0 +1,9 @@ +from . import account_asset +from . import account_asset_profile +from . import account_capital_asset_map_tax +from . import account_move +from . import account_move_line +from . import account_capital_asset_type +from . import res_company +from . import res_config_settings +from . import account_tax diff --git a/l10n_es_account_capital_asset/models/account_asset.py b/l10n_es_account_capital_asset/models/account_asset.py new file mode 100644 index 000000000..ea714e8ee --- /dev/null +++ b/l10n_es_account_capital_asset/models/account_asset.py @@ -0,0 +1,77 @@ +# Copyright NuoBiT Solutions - Kilian Niubo +# Copyright NuoBiT Solutions - Eric Antones +# Copyright 2026 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class AccountAsset(models.Model): + _inherit = "account.asset" + + default_capital_asset_type_id = fields.Many2one( + string="Default Capital Asset Type", + related="profile_id.default_capital_asset_type_id", + ) + capital_asset_type_id = fields.Many2one( + comodel_name="l10n.es.account.capital.asset.type", + ondelete="restrict", + domain="[('id', '=', default_capital_asset_type_id)]", + ) + + @api.constrains("capital_asset_type_id", "company_id") + def _check_amount_type(self): + threshold_capital_asset_amount = float( + self.env["ir.config_parameter"] + .sudo() + .get_param("l10n_es_account_capital_asset.capital_asset_threshold_amount") + ) + for rec in self: + if rec.company_id.l10n_es_capital_asset_enabled: + if ( + rec.tax_base_amount >= threshold_capital_asset_amount + and not rec.capital_asset_type_id + ): + raise ValidationError( + _( + "If Tax Base Amount is greater than %s, " + "capital asset type must be defined." + ) + % threshold_capital_asset_amount + ) + if ( + rec.tax_base_amount < threshold_capital_asset_amount + and rec.capital_asset_type_id + ): + raise ValidationError( + _( + "If Tax Base Amount is less than %s, this asset " + "is not considered as a " + "capital asset so capital asset type mustn't be defined" + ) + % threshold_capital_asset_amount + ) + + @api.constrains("tax_ids") + def _check_tax_base_amount(self): + if not self.mapped("tax_ids") and self.env.context.get( + "allow_empty_taxes", False + ): + return + for rec in self: + rec.tax_ids.check_tax_base_amount(rec) + + @api.constrains("profile_id", "capital_asset_type_id") + def _check_capital_asset_type_integrity(self): + if ( + self.capital_asset_type_id + and self.profile_id.default_capital_asset_type_id + != self.capital_asset_type_id + ): + raise ValidationError( + _( + "Capital asset type must be the same as " + "the one defined in the asset category." + ) + ) diff --git a/l10n_es_account_capital_asset/models/account_asset_profile.py b/l10n_es_account_capital_asset/models/account_asset_profile.py new file mode 100644 index 000000000..254b5d1b4 --- /dev/null +++ b/l10n_es_account_capital_asset/models/account_asset_profile.py @@ -0,0 +1,35 @@ +# Copyright NuoBiT Solutions - Kilian Niubo +# Copyright NuoBiT Solutions - Eric Antones +# Copyright 2026 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class AccountAssetProfile(models.Model): + _inherit = "account.asset.profile" + + default_capital_asset_type_id = fields.Many2one( + string="Default Capital Asset Type", + comodel_name="l10n.es.account.capital.asset.type", + ondelete="restrict", + required=True, + ) + + capital_asset_set = fields.Boolean( + string="Capital asset set", + help="Indicates that this profile is used for a set of capital assets.", + ) + + @api.constrains("capital_asset_set", "asset_product_item") + def _check_capital_asset_set(self): + for rec in self: + if rec.capital_asset_set and rec.asset_product_item: + raise ValidationError( + _( + "A profile for a set of capital assets is not compatible with " + "the 'Product per Asset' option. You cannot have both enabled. " + "Please, select only one of them." + ) + ) diff --git a/l10n_es_account_capital_asset/models/account_capital_asset_map_tax.py b/l10n_es_account_capital_asset/models/account_capital_asset_map_tax.py new file mode 100644 index 000000000..593485530 --- /dev/null +++ b/l10n_es_account_capital_asset/models/account_capital_asset_map_tax.py @@ -0,0 +1,59 @@ +# Copyright NuoBiT Solutions - Kilian Niubo +# Copyright NuoBiT Solutions - Eric Antones +# Copyright 2026 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import api, fields, models + + +class AccountCapitalAssetMapTax(models.Model): + _name = "l10n.es.account.capital.asset.map.tax" + _description = "Capital Asset Map Tax" + + company_id = fields.Many2one( + comodel_name="res.company", + required=True, + default=lambda self: self.env.company, + ) + tax_src_id = fields.Many2one( + comodel_name="account.tax", + string="Tax Source", + required=True, + check_company=True, + ) + tax_dest_id = fields.Many2one( + comodel_name="account.tax", + string="Replacement Tax", + required=True, + check_company=True, + ) + + def _get_taxes_mapping(self): + return {mapping.tax_src_id: mapping.tax_dest_id for mapping in self.search([])} + + @api.model + def map_tax(self, taxes, company, asset_profile, amount, quantity): + if any( + [ + not taxes, + not company, + not company.l10n_es_capital_asset_enabled, + not asset_profile, + not amount, + not quantity, + ] + ): + return taxes + threshold_capital_asset_amount = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("l10n_es_account_capital_asset.capital_asset_threshold_amount") + ) + asset_price = amount + result = taxes + if asset_price >= float(threshold_capital_asset_amount): + tax_map = self._get_taxes_mapping() + result = self.env["account.tax"] + for tax in taxes: + result |= tax_map.get(tax._origin, tax) + return result diff --git a/l10n_es_account_capital_asset/models/account_capital_asset_type.py b/l10n_es_account_capital_asset/models/account_capital_asset_type.py new file mode 100644 index 000000000..273bccbe0 --- /dev/null +++ b/l10n_es_account_capital_asset/models/account_capital_asset_type.py @@ -0,0 +1,42 @@ +# Copyright NuoBiT Solutions - Eric Antones +# Copyright 2025 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class CapitalAssetType(models.Model): + _name = "l10n.es.account.capital.asset.type" + _description = "Capital Asset Type" + + name = fields.Char(required=True, translate=True) + period = fields.Integer(string="Period (years)", required=True) + + _sql_constraints = [ + ( + "unique_name", + "unique(name)", + "Capital Asset Type name must be unique", + ), + ( + "unique_period", + "unique(period)", + "Capital Asset Type period must be unique", + ), + ] + + @api.depends("name", "period") + def _compute_display_name(self): + for rec in self: + rec.display_name = f"{rec.name} ({rec.period} {_('years')})" + + @api.constrains("period") + def _check_period(self): + for rec in self: + if rec.period <= 0: + raise ValidationError(_("Period must be greater than 0.")) + + @api.model + def _get_max_period(self): + return max(self.search([]).mapped("period")) diff --git a/l10n_es_account_capital_asset/models/account_move.py b/l10n_es_account_capital_asset/models/account_move.py new file mode 100644 index 000000000..db9ebe2b5 --- /dev/null +++ b/l10n_es_account_capital_asset/models/account_move.py @@ -0,0 +1,26 @@ +# Copyright NuoBiT Solutions - Kilian Niubo +# Copyright 2026 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + + +from odoo import models + + +class AccountMove(models.Model): + _inherit = "account.move" + + def _prepare_asset_vals(self, aml): + vals = super()._prepare_asset_vals(aml) + if aml.company_id.l10n_es_capital_asset_enabled: + threshold_amount = float( + self.env["ir.config_parameter"] + .sudo() + .get_param( + "l10n_es_account_capital_asset.capital_asset_threshold_amount" + ) + ) + if aml.balance >= threshold_amount: + vals["capital_asset_type_id"] = ( + aml.asset_profile_id.default_capital_asset_type_id.id + ) + return vals diff --git a/l10n_es_account_capital_asset/models/account_move_line.py b/l10n_es_account_capital_asset/models/account_move_line.py new file mode 100644 index 000000000..794ca6bf8 --- /dev/null +++ b/l10n_es_account_capital_asset/models/account_move_line.py @@ -0,0 +1,47 @@ +# Copyright NuoBiT Solutions - Kilian Niubo +# Copyright NuoBiT Solutions - Eric Antones +# Copyright 2026 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + + +from odoo import api, models + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + @api.onchange( + "product_id", + "product_uom_id", + "account_id", + "tax_ids", + "asset_profile_id", + "price_subtotal", + "quantity", + ) + def _onchange_recompute_mapped_taxes(self): + self.compute_mapped_taxes() + + def _compute_tax_ids(self): + res = super()._compute_tax_ids() + self.compute_mapped_taxes() + return res + + def _inverse_account_id(self): + res = super()._inverse_account_id() + self.compute_mapped_taxes() + return res + + def compute_mapped_taxes(self): + for line in self: + if line.tax_ids: + line.tax_ids = line.env[ + "l10n.es.account.capital.asset.map.tax" + ].map_tax( + line.tax_ids, + line.company_id, + line.asset_profile_id, + line.balance, + line.quantity, + ) + return self diff --git a/l10n_es_account_capital_asset/models/account_tax.py b/l10n_es_account_capital_asset/models/account_tax.py new file mode 100644 index 000000000..dfa71bcc7 --- /dev/null +++ b/l10n_es_account_capital_asset/models/account_tax.py @@ -0,0 +1,66 @@ +# Copyright NuoBiT Solutions SL - Kilian Niubo +# Copyright NuoBiT Solutions SL - Eric Antones +# Copyright 2025 NuoBiT Solutions SL - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import _, models +from odoo.exceptions import ValidationError + + +class AccountTax(models.Model): + _inherit = "account.tax" + + def check_tax_base_amount(self, asset): + threshold_amount = float( + self.env["ir.config_parameter"] + .sudo() + .get_param("l10n_es_account_capital_asset.capital_asset_threshold_amount") + ) + tax_mappings = self.env["l10n.es.account.capital.asset.map.tax"].search([]) + capital_asset_dest_taxes = tax_mappings.mapped("tax_dest_id") + + for rec in self: + if rec.company_id.l10n_es_capital_asset_enabled: + is_capital_asset_tax = rec in capital_asset_dest_taxes + if ( + not asset.profile_id.asset_product_item + and asset.profile_id.capital_asset_set + ): + tax_base_amount_unit = asset.tax_base_amount_unit + else: + tax_base_amount_unit = asset.tax_base_amount + if ( + tax_base_amount_unit >= threshold_amount + and not is_capital_asset_tax + ): + raise ValidationError( + _( + "The asset of type '%(asset_type)s' has a unit amount " + "%(unit_amount).2f€ greater than %(threshold).2f€, so " + "it is considered a capital asset, but the selected " + "taxes are not of a capital asset type. Please update " + "the taxes accordingly or define the asset type as" + " a set of assets." + ) + % { + "asset_type": asset.profile_id.name, + "unit_amount": tax_base_amount_unit, + "threshold": threshold_amount, + } + ) + elif tax_base_amount_unit < threshold_amount and is_capital_asset_tax: + raise ValidationError( + _( + "The asset of type '%(asset_type)s' has a unit amount" + " %(unit_amount).2f€ lower than %(threshold).2f€, so " + "it is not considered a capital asset, but capital " + "asset taxes are selected. Please update the taxes " + "accordingly or define the asset type as a set of " + "assets." + ) + % { + "asset_type": asset.profile_id.name, + "unit_amount": tax_base_amount_unit, + "threshold": threshold_amount, + } + ) diff --git a/l10n_es_account_capital_asset/models/res_company.py b/l10n_es_account_capital_asset/models/res_company.py new file mode 100644 index 000000000..39f290673 --- /dev/null +++ b/l10n_es_account_capital_asset/models/res_company.py @@ -0,0 +1,13 @@ +# Copyright NuoBiT Solutions - Kilian Niubo +# Copyright 2025 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import fields, models + + +class ResCompany(models.Model): + _inherit = "res.company" + + l10n_es_capital_asset_enabled = fields.Boolean( + string="L10n ES Capital Asset Enabled" + ) diff --git a/l10n_es_account_capital_asset/models/res_config_settings.py b/l10n_es_account_capital_asset/models/res_config_settings.py new file mode 100644 index 000000000..1f3ea9295 --- /dev/null +++ b/l10n_es_account_capital_asset/models/res_config_settings.py @@ -0,0 +1,14 @@ +# Copyright NuoBiT Solutions - Kilian Niubo +# Copyright NuoBiT Solutions - Eric Antones +# Copyright 2025 NuoBiT Solutions - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + capital_asset_threshold_amount = fields.Float( + config_parameter="l10n_es_account_capital_asset.capital_asset_threshold_amount", + help="Minimum amount to consider the asset as a capital asset", + ) diff --git a/l10n_es_account_capital_asset/pyproject.toml b/l10n_es_account_capital_asset/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/l10n_es_account_capital_asset/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/l10n_es_account_capital_asset/readme/CONTRIBUTORS.md b/l10n_es_account_capital_asset/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..8d6d66521 --- /dev/null +++ b/l10n_es_account_capital_asset/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- [NuoBiT](): + - Kilian Niubo + - Eric Antones + - Deniz Gallo diff --git a/l10n_es_account_capital_asset/readme/DESCRIPTION.md b/l10n_es_account_capital_asset/readme/DESCRIPTION.md new file mode 100644 index 000000000..e410c924c --- /dev/null +++ b/l10n_es_account_capital_asset/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module adds mapping for capital assets taxes, capital assets category types and threshold amount on res_config diff --git a/l10n_es_account_capital_asset/security/ir.model.access.csv b/l10n_es_account_capital_asset/security/ir.model.access.csv new file mode 100644 index 000000000..338efa391 --- /dev/null +++ b/l10n_es_account_capital_asset/security/ir.model.access.csv @@ -0,0 +1,5 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"access_l10n_es_account_capital_asset_type_user","Account capital asset type - Account User","model_l10n_es_account_capital_asset_type","account.group_account_invoice",1,0,0,0 +"access_l10n_es_account_capital_asset_type_manager","Account capital asset type - Account Manager","model_l10n_es_account_capital_asset_type","account.group_account_manager",1,1,1,1 +"access_l10n_es_account_capital_asset_map_tax_user","Account capital asset - Account User","model_l10n_es_account_capital_asset_map_tax","account.group_account_invoice",1,0,0,0 +"access_l10n_es_account_capital_asset_map_tax_manager","Account capital asset - Account Manager","model_l10n_es_account_capital_asset_map_tax","account.group_account_manager",1,1,1,1 diff --git a/l10n_es_account_capital_asset/security/l10n_es_account_capital_asset_map_tax_security.xml b/l10n_es_account_capital_asset/security/l10n_es_account_capital_asset_map_tax_security.xml new file mode 100644 index 000000000..1e805b6e6 --- /dev/null +++ b/l10n_es_account_capital_asset/security/l10n_es_account_capital_asset_map_tax_security.xml @@ -0,0 +1,12 @@ + + + + + Capital Asset Map Tax: multi-company + + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + + diff --git a/l10n_es_account_capital_asset/static/description/icon.png b/l10n_es_account_capital_asset/static/description/icon.png new file mode 100644 index 000000000..1cd641e79 Binary files /dev/null and b/l10n_es_account_capital_asset/static/description/icon.png differ diff --git a/l10n_es_account_capital_asset/static/description/index.html b/l10n_es_account_capital_asset/static/description/index.html new file mode 100644 index 000000000..1dd4b198b --- /dev/null +++ b/l10n_es_account_capital_asset/static/description/index.html @@ -0,0 +1,422 @@ + + + + + +Account Capital Asset + + + +
+

Account Capital Asset

+ + +

Beta License: AGPL-3 NuoBiT/odoo-addons

+

This module adds mapping for capital assets taxes, capital assets +category types and threshold amount on res_config

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • NuoBiT Solutions SL
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is part of the NuoBiT/odoo-addons project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/l10n_es_account_capital_asset/views/account_asset.xml b/l10n_es_account_capital_asset/views/account_asset.xml new file mode 100644 index 000000000..73ec9d886 --- /dev/null +++ b/l10n_es_account_capital_asset/views/account_asset.xml @@ -0,0 +1,21 @@ + + + + + account.asset + + +
+ + + + + + +
+
diff --git a/l10n_es_account_capital_asset/views/account_asset_profile_views.xml b/l10n_es_account_capital_asset/views/account_asset_profile_views.xml new file mode 100644 index 000000000..b49c5fa48 --- /dev/null +++ b/l10n_es_account_capital_asset/views/account_asset_profile_views.xml @@ -0,0 +1,25 @@ + + + + + account.asset.profile + + + + + + + + + + + diff --git a/l10n_es_account_capital_asset/views/account_capital_asset_map_tax_views.xml b/l10n_es_account_capital_asset/views/account_capital_asset_map_tax_views.xml new file mode 100644 index 000000000..946e23812 --- /dev/null +++ b/l10n_es_account_capital_asset/views/account_capital_asset_map_tax_views.xml @@ -0,0 +1,28 @@ + + + + + account.capital.asset.list + l10n.es.account.capital.asset.map.tax + + + + + + + + + + Account Capital Asset Tax Map + l10n.es.account.capital.asset.map.tax + list + + + diff --git a/l10n_es_account_capital_asset/views/account_capital_asset_type_view.xml b/l10n_es_account_capital_asset/views/account_capital_asset_type_view.xml new file mode 100644 index 000000000..1e1f49d41 --- /dev/null +++ b/l10n_es_account_capital_asset/views/account_capital_asset_type_view.xml @@ -0,0 +1,55 @@ + + + + + aeat.vat.special.prorrate.capital.asset.type.view.form + l10n.es.account.capital.asset.type + +
+ + + + + + + + +
+
+
+ + + aeat.vat.special.prorrate.capital.asset.type.view.list + l10n.es.account.capital.asset.type + + + + + + + + + + Capital Asset Type + l10n.es.account.capital.asset.type + list,form + + + +
diff --git a/l10n_es_account_capital_asset/views/res_company_view.xml b/l10n_es_account_capital_asset/views/res_company_view.xml new file mode 100644 index 000000000..9dd1a87da --- /dev/null +++ b/l10n_es_account_capital_asset/views/res_company_view.xml @@ -0,0 +1,22 @@ + + + + + res.company.aeat.form + res.company + + + + + + + + + + + + + + diff --git a/l10n_es_account_capital_asset/views/res_config_settings_views.xml b/l10n_es_account_capital_asset/views/res_config_settings_views.xml new file mode 100644 index 000000000..0b642af42 --- /dev/null +++ b/l10n_es_account_capital_asset/views/res_config_settings_views.xml @@ -0,0 +1,19 @@ + + + + + res.config.settings + + + + + + + + + + + + diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 000000000..0e3aa5a11 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,3 @@ +odoo-addon-l10n_es_extension@git+https://github.com/nuobit/odoo-addons.git@refs/pull/769/head#subdirectory=l10n_es_extension +odoo-addon-account_asset_management_extension@git+https://github.com/nuobit/odoo-addons.git@refs/pull/754/head#subdirectory=account_asset_management_extension +odoo-addon-l10n_es_asset_extension@git+https://github.com/nuobit/odoo-addons.git@refs/pull/780/head#subdirectory=l10n_es_asset_extension