From 8b914b7cbdf633bbdc906430666d5f5e11847e35 Mon Sep 17 00:00:00 2001 From: sergio-teruel Date: Mon, 19 May 2025 22:58:50 +0200 Subject: [PATCH 1/4] [ADD] l10n_es_atc_sii_oca: New module --- l10n_es_atc_sii_oca/README.rst | 103 ++++ l10n_es_atc_sii_oca/__init__.py | 3 + l10n_es_atc_sii_oca/__manifest__.py | 27 ++ .../data/aeat_sii_map_data.xml | 138 ++++++ ...eat_sii_mapping_registration_keys_data.xml | 117 +++++ .../data/aeat_sii_tax_agency_data.xml | 19 + .../data/l10n.es.aeat.map.tax.line.tax.csv | 45 ++ l10n_es_atc_sii_oca/models/__init__.py | 1 + l10n_es_atc_sii_oca/models/account_move.py | 38 ++ l10n_es_atc_sii_oca/pyproject.toml | 3 + l10n_es_atc_sii_oca/readme/CONTRIBUTORS.md | 6 + l10n_es_atc_sii_oca/readme/DESCRIPTION.md | 4 + l10n_es_atc_sii_oca/readme/USAGE.md | 4 + .../static/description/icon.png | Bin 0 -> 7518 bytes .../static/description/index.html | 452 ++++++++++++++++++ 15 files changed, 960 insertions(+) create mode 100644 l10n_es_atc_sii_oca/README.rst create mode 100644 l10n_es_atc_sii_oca/__init__.py create mode 100644 l10n_es_atc_sii_oca/__manifest__.py create mode 100644 l10n_es_atc_sii_oca/data/aeat_sii_map_data.xml create mode 100644 l10n_es_atc_sii_oca/data/aeat_sii_mapping_registration_keys_data.xml create mode 100644 l10n_es_atc_sii_oca/data/aeat_sii_tax_agency_data.xml create mode 100644 l10n_es_atc_sii_oca/data/l10n.es.aeat.map.tax.line.tax.csv create mode 100644 l10n_es_atc_sii_oca/models/__init__.py create mode 100644 l10n_es_atc_sii_oca/models/account_move.py create mode 100644 l10n_es_atc_sii_oca/pyproject.toml create mode 100644 l10n_es_atc_sii_oca/readme/CONTRIBUTORS.md create mode 100644 l10n_es_atc_sii_oca/readme/DESCRIPTION.md create mode 100644 l10n_es_atc_sii_oca/readme/USAGE.md create mode 100644 l10n_es_atc_sii_oca/static/description/icon.png create mode 100644 l10n_es_atc_sii_oca/static/description/index.html diff --git a/l10n_es_atc_sii_oca/README.rst b/l10n_es_atc_sii_oca/README.rst new file mode 100644 index 00000000000..5b8f0ece7b3 --- /dev/null +++ b/l10n_es_atc_sii_oca/README.rst @@ -0,0 +1,103 @@ +============================================== +Suministro Inmediato de Información en el IGIC +============================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:dee86187a1c9e23db0830fff818b76d6039ecbec0d42faba6b237a0e65286634 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-OCA%2Fl10n--spain-lightgray.png?logo=github + :target: https://github.com/OCA/l10n-spain/tree/17.0/l10n_es_atc_sii_oca + :alt: OCA/l10n-spain +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/l10n-spain-17-0/l10n-spain-17-0-l10n_es_atc_sii_oca + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-spain&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +- `FAQ de la ATC para el + SII `__ +- `Parte + técnica `__ +- `Parte de + ayuda `__ +- `Parte de + normativa `__ + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Cuando se valida una factura automáticamente envía la comunicación al +servidor de la ATC. + +Se debe establecer en la configuración de la compañía la agencia +tributaria: **Agencia Tributaria Canaria (1.0)**. En caso contrario, se +enviará al SII de la **AEAT**. + +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 +------- + +* Sistemas de Datos S.L +* Comunitea +* Tecnativa + +Contributors +------------ + +- Sistemas de Datos S.L +- `Comunitea `__: + + - Omar Castiñeira + - Mario Montes + +- `Tecnativa `__: + + - Sergio Teruel + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/l10n-spain `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_es_atc_sii_oca/__init__.py b/l10n_es_atc_sii_oca/__init__.py new file mode 100644 index 00000000000..31660d6a965 --- /dev/null +++ b/l10n_es_atc_sii_oca/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import models diff --git a/l10n_es_atc_sii_oca/__manifest__.py b/l10n_es_atc_sii_oca/__manifest__.py new file mode 100644 index 00000000000..8b42f3793f9 --- /dev/null +++ b/l10n_es_atc_sii_oca/__manifest__.py @@ -0,0 +1,27 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Suministro Inmediato de Información en el IGIC", + "version": "17.0.1.0.0", + "category": "Accounting & Finance", + "website": "https://github.com/OCA/l10n-spain", + "author": "Sistemas de Datos S.L, " + "Comunitea, " + "Tecnativa, " + "Odoo Community Association (OCA)", + "license": "AGPL-3", + "installable": True, + "development_status": "Beta", + "depends": [ + "l10n_es_aeat_sii_oca", + "l10n_es_atc", + "l10n_es_igic", + ], + "data": [ + "data/aeat_sii_tax_agency_data.xml", + "data/aeat_sii_mapping_registration_keys_data.xml", + "data/l10n.es.aeat.map.tax.line.tax.csv", + "data/aeat_sii_map_data.xml", + ], + "images": ["static/description/icon.png"], +} diff --git a/l10n_es_atc_sii_oca/data/aeat_sii_map_data.xml b/l10n_es_atc_sii_oca/data/aeat_sii_map_data.xml new file mode 100644 index 00000000000..50c336f04fb --- /dev/null +++ b/l10n_es_atc_sii_oca/data/aeat_sii_map_data.xml @@ -0,0 +1,138 @@ + + + + + SII - ATC + + + + SFESB + + + SuministroFactEmitidas Sujetas Bienes + + + SFESISP + + + SuministroFactEmitidas Sujetas ISP + + + + SFESSE + + + SuministroFactEmitidas Servicios Exento + + + + + SFRS + + + SuministroFactRecibidas Sujetas + + + SFRISP + + + SuministroFactRecibidas ISP + + + SFRBI + + + SuministroFactRecibidas Bienes de Inversión + + + + RE + + + SuministroFact Recargo Equivalencia + + diff --git a/l10n_es_atc_sii_oca/data/aeat_sii_mapping_registration_keys_data.xml b/l10n_es_atc_sii_oca/data/aeat_sii_mapping_registration_keys_data.xml new file mode 100644 index 00000000000..8e9c99660bf --- /dev/null +++ b/l10n_es_atc_sii_oca/data/aeat_sii_mapping_registration_keys_data.xml @@ -0,0 +1,117 @@ + + + + + Régimen especial grupo de entidades en IVA-IGIC (Nivel Avanzado) + + + Régimen especial grupo de entidades en IVA-IGIC (Nivel Avanzado) + + + Operaciones sujetas al IPSI / IGIC-IVA + + + Operaciones sujetas al IPSI / IGIC-IVA + + + Factura con IVA-IGIC pendiente de devengo (certificaciones de obra cuyo destinatario sea una Administración Pública) + + + Factura con IVA-IGIC pendiente de devengo - operaciones de tracto sucesivo + + + Facturas anteriores a la inclusión en el SII + + + Facturas anteriores a la inclusión en el SII + + + + 17 + Régimen especial de comerciante minorista + sale + + + 18 + Régimen especial del pequeño empresario o profesional + sale + + + 19 + Operaciones interiores exentas por aplicación artículo 25 Ley 19/1994 + sale + + + 15 + Régimen especial de comerciante minorista + purchase + + + 16 + Régimen especial del pequeño empresario o profesional + purchase + + + 17 + Operaciones interiores exentas por aplicación artículo 25 Ley 19/1994 + purchase + + diff --git a/l10n_es_atc_sii_oca/data/aeat_sii_tax_agency_data.xml b/l10n_es_atc_sii_oca/data/aeat_sii_tax_agency_data.xml new file mode 100644 index 00000000000..bc086932708 --- /dev/null +++ b/l10n_es_atc_sii_oca/data/aeat_sii_tax_agency_data.xml @@ -0,0 +1,19 @@ + + + + + https://www.gobiernodecanarias.org/tributos/atc/estatico/asistencia_contribuyente/wsdl/SuministroFactEmitidas.wsdl + + https://www.gobiernodecanarias.org/tributos/atc/estatico/asistencia_contribuyente/wsdl/SuministroFactRecibidas.wsdl + + https://www.gobiernodecanarias.org/tributos/atc/estatico/asistencia_contribuyente/wsdl/SuministroBienesInversion.wsdl + + https://www.gobiernodecanarias.org/tributos/atc/estatico/asistencia_contribuyente/wsdl/SuministroInmueblesAdicionales.wsdl + + https://www.gobiernodecanarias.org/tributos/atc/estatico/asistencia_contribuyente/wsdl/SuministroCobrosEmitidas.wsdl + + https://www.gobiernodecanarias.org/tributos/atc/estatico/asistencia_contribuyente/wsdl/SuministroOpTrascendTribu.wsdl + + https://www.gobiernodecanarias.org/tributos/atc/estatico/asistencia_contribuyente/wsdl/SuministroPagosRecibidas.wsdl + + diff --git a/l10n_es_atc_sii_oca/data/l10n.es.aeat.map.tax.line.tax.csv b/l10n_es_atc_sii_oca/data/l10n.es.aeat.map.tax.line.tax.csv new file mode 100644 index 00000000000..b58aa7c7fde --- /dev/null +++ b/l10n_es_atc_sii_oca/data/l10n.es.aeat.map.tax.line.tax.csv @@ -0,0 +1,45 @@ +id,name +igic_r_0,account_tax_template_igic_r_0 +igic_r_3,account_tax_template_igic_r_3 +igic_r_7,account_tax_template_igic_r_7 +igic_r_9_5,account_tax_template_igic_r_9_5 +igic_r_15,account_tax_template_igic_r_15 +igic_r_20,account_tax_template_igic_r_20 +igic_s_ISP0,account_tax_template_igic_s_ISP0 +igic_re_ex,account_tax_template_igic_re_ex +igic_p_ex,account_tax_template_igic_p_ex +igic_sop_0,account_tax_template_igic_sop_0 +igic_sop_3,account_tax_template_igic_sop_3 +igic_sop_7,account_tax_template_igic_sop_7 +igic_sop_9_5,account_tax_template_igic_sop_9_5 +igic_sop_15,account_tax_template_igic_sop_15 +igic_sop_20,account_tax_template_igic_sop_20 +igic_sop_i_0,account_tax_template_igic_sop_i_0 +igic_sop_i_3,account_tax_template_igic_sop_i_3 +igic_sop_i_7,account_tax_template_igic_sop_i_7 +igic_sop_i_9_5,account_tax_template_igic_sop_i_9_5 +igic_sop_i_15,account_tax_template_igic_sop_i_15 +igic_sop_i_20,account_tax_template_igic_sop_i_20 +igic_sop_0_inv,account_tax_template_igic_sop_0_inv +igic_sop_3_inv,account_tax_template_igic_sop_3_inv +igic_sop_7_inv,account_tax_template_igic_sop_7_inv +igic_sop_9_5_inv,account_tax_template_igic_sop_9_5_inv +igic_sop_15_inv,account_tax_template_igic_sop_15_inv +igic_sop_20_inv,account_tax_template_igic_sop_20_inv +igic_sop_i_0_inv,account_tax_template_igic_sop_i_0_inv +igic_sop_i_3_inv,account_tax_template_igic_sop_i_3_inv +igic_sop_i_7_inv,account_tax_template_igic_sop_i_7_inv +igic_sop_i_9_5_inv,account_tax_template_igic_sop_i_9_5_inv +igic_sop_i_15_inv,account_tax_template_igic_sop_i_15_inv +igic_sop_i_20_inv,account_tax_template_igic_sop_i_20_inv +igic_ISP0,account_tax_template_igic_ISP0 +igic_ISP3,account_tax_template_igic_ISP3 +igic_ISP7,account_tax_template_igic_ISP7 +igic_ISP95,account_tax_template_igic_ISP95 +igic_ISP15,account_tax_template_igic_ISP15 +igic_ISP20,account_tax_template_igic_ISP20 +igic_p_re03,account_tax_template_igic_p_re03 +igic_p_re07,account_tax_template_igic_p_re07 +igic_p_re095,account_tax_template_igic_p_re095 +igic_p_re15,account_tax_template_igic_p_re15 +igic_p_re20,account_tax_template_igic_p_re20 diff --git a/l10n_es_atc_sii_oca/models/__init__.py b/l10n_es_atc_sii_oca/models/__init__.py new file mode 100644 index 00000000000..9c0a4213854 --- /dev/null +++ b/l10n_es_atc_sii_oca/models/__init__.py @@ -0,0 +1 @@ +from . import account_move diff --git a/l10n_es_atc_sii_oca/models/account_move.py b/l10n_es_atc_sii_oca/models/account_move.py new file mode 100644 index 00000000000..da46ad3589a --- /dev/null +++ b/l10n_es_atc_sii_oca/models/account_move.py @@ -0,0 +1,38 @@ +# Copyright 2025 Sistema de datos - Mario Montes +# Copyright 2025 Tecnativa - Sergio Teruel +import logging + +from odoo import models + +_logger = logging.getLogger(__name__) + + +class AccountMove(models.Model): + _inherit = "account.move" + + def _get_sii_header(self, tipo_comunicacion=False, cancellation=False): + header = super()._get_sii_header(tipo_comunicacion, cancellation) + header["IDVersionSii"] = "1.0" + return header + + def _get_sii_invoice_dict(self): + inv_dict = super()._get_sii_invoice_dict() + inv_dict["DetalleIVA"] = inv_dict.pop("DetalleIVA", ["DetalleIGIC"]) + inv_dict["DesgloseIVA"] = inv_dict.pop("DesgloseIVA", ["DetalleIGIC"]) + inv_dict["ImporteTransmisionInmueblesSujetoAIVA"] = inv_dict.pop( + "ImporteTransmisionInmueblesSujetoAIVA", + ["ImporteTransmisionInmueblesSujetoAIGIC"], + ) + inv_dict["PeriodoImpositivo"] = inv_dict.pop( + "PeriodoImpositivo", ["DetalleIGIC"] + ) + return inv_dict + + def _get_sii_invoice_dict_in(self, cancel=False): + inv_dict = super()._get_sii_invoice_dict_in(cancel) + if self.sii_registration_key.code == "15": + for p in inv_dict["FacturaRecibida"]["DesgloseFactura"]["DesgloseIGIC"][ + "DetalleIGIC" + ]: + p.pop("CuotaSoportada") + return inv_dict diff --git a/l10n_es_atc_sii_oca/pyproject.toml b/l10n_es_atc_sii_oca/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/l10n_es_atc_sii_oca/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/l10n_es_atc_sii_oca/readme/CONTRIBUTORS.md b/l10n_es_atc_sii_oca/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..42b59d0ef98 --- /dev/null +++ b/l10n_es_atc_sii_oca/readme/CONTRIBUTORS.md @@ -0,0 +1,6 @@ +- Sistemas de Datos S.L +- [Comunitea](https://comunitea.com/): + - Omar Castiñeira \<\> + - Mario Montes \<\> +- [Tecnativa](https://www.tecnativa.com): + - Sergio Teruel diff --git a/l10n_es_atc_sii_oca/readme/DESCRIPTION.md b/l10n_es_atc_sii_oca/readme/DESCRIPTION.md new file mode 100644 index 00000000000..ed75d9f5403 --- /dev/null +++ b/l10n_es_atc_sii_oca/readme/DESCRIPTION.md @@ -0,0 +1,4 @@ +- [FAQ de la ATC para el SII](https://www3.gobiernodecanarias.org/tributos/atc/estatico/asistencia_contribuyente/pdf/Preguntas_frecuentes_SII.pdf) +- [Parte técnica](https://www3.gobiernodecanarias.org/tributos/atc/jsf/publico/asistenciaContribuyente/sii/tecnica.jsp) +- [Parte de ayuda](https://www3.gobiernodecanarias.org/tributos/atc/jsf/publico/asistenciaContribuyente/sii/ayuda.jsp) +- [Parte de normativa](https://www3.gobiernodecanarias.org/tributos/atc/jsf/publico/asistenciaContribuyente/sii/normativa.jsp) diff --git a/l10n_es_atc_sii_oca/readme/USAGE.md b/l10n_es_atc_sii_oca/readme/USAGE.md new file mode 100644 index 00000000000..c1e3620bb3f --- /dev/null +++ b/l10n_es_atc_sii_oca/readme/USAGE.md @@ -0,0 +1,4 @@ +Cuando se valida una factura automáticamente envía la comunicación al servidor de la ATC. + +Se debe establecer en la configuración de la compañía la agencia tributaria: **Agencia Tributaria Canaria (1.0)**. +En caso contrario, se enviará al SII de la **AEAT**. diff --git a/l10n_es_atc_sii_oca/static/description/icon.png b/l10n_es_atc_sii_oca/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0856087de4986cdc8e9d669825b2363f7027e269 GIT binary patch literal 7518 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 + + + + +Suministro Inmediato de Información en el IGIC + + + +
+

Suministro Inmediato de Información en el IGIC

+ + +

Beta License: AGPL-3 OCA/l10n-spain Translate me on Weblate Try me on Runboat

+ +

Table of contents

+ +
+

Usage

+

Cuando se valida una factura automáticamente envía la comunicación al +servidor de la ATC.

+

Se debe establecer en la configuración de la compañía la agencia +tributaria: Agencia Tributaria Canaria (1.0). En caso contrario, se +enviará al SII de la AEAT.

+
+
+

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

+
    +
  • Sistemas de Datos S.L
  • +
  • Comunitea
  • +
  • Tecnativa
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/l10n-spain project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From ee36824398834f7a226c67060551808774c9893e Mon Sep 17 00:00:00 2001 From: sergio-teruel Date: Thu, 18 Sep 2025 00:50:39 +0200 Subject: [PATCH 2/4] [IMP] l10n_es_atc_sii_oca: Change some data in schema for Canary tax agency --- l10n_es_atc_sii_oca/README.rst | 28 ++++++------ l10n_es_atc_sii_oca/models/account_move.py | 52 +++++++++++++--------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/l10n_es_atc_sii_oca/README.rst b/l10n_es_atc_sii_oca/README.rst index 5b8f0ece7b3..4f310d73030 100644 --- a/l10n_es_atc_sii_oca/README.rst +++ b/l10n_es_atc_sii_oca/README.rst @@ -28,14 +28,14 @@ Suministro Inmediato de Información en el IGIC |badge1| |badge2| |badge3| |badge4| |badge5| -- `FAQ de la ATC para el - SII `__ -- `Parte - técnica `__ -- `Parte de - ayuda `__ -- `Parte de - normativa `__ +- `FAQ de la ATC para el + SII `__ +- `Parte + técnica `__ +- `Parte de + ayuda `__ +- `Parte de + normativa `__ **Table of contents** @@ -75,15 +75,15 @@ Authors Contributors ------------ -- Sistemas de Datos S.L -- `Comunitea `__: +- Sistemas de Datos S.L +- `Comunitea `__: - - Omar Castiñeira - - Mario Montes + - Omar Castiñeira + - Mario Montes -- `Tecnativa `__: +- `Tecnativa `__: - - Sergio Teruel + - Sergio Teruel Maintainers ----------- diff --git a/l10n_es_atc_sii_oca/models/account_move.py b/l10n_es_atc_sii_oca/models/account_move.py index da46ad3589a..86407cff69c 100644 --- a/l10n_es_atc_sii_oca/models/account_move.py +++ b/l10n_es_atc_sii_oca/models/account_move.py @@ -10,29 +10,41 @@ class AccountMove(models.Model): _inherit = "account.move" - def _get_sii_header(self, tipo_comunicacion=False, cancellation=False): - header = super()._get_sii_header(tipo_comunicacion, cancellation) - header["IDVersionSii"] = "1.0" + # Do some changes for Canary tax agency + def _get_aeat_header(self, tipo_comunicacion=False, cancellation=False): + header = super()._get_aeat_header( + tipo_comunicacion=tipo_comunicacion, cancellation=cancellation + ) + if self._get_sii_tax_agency() == self.env.ref( + "l10n_es_aeat.aeat_tax_agency_canarias" + ): + header["IDVersionSii"] = "1.0" return header - def _get_sii_invoice_dict(self): - inv_dict = super()._get_sii_invoice_dict() - inv_dict["DetalleIVA"] = inv_dict.pop("DetalleIVA", ["DetalleIGIC"]) - inv_dict["DesgloseIVA"] = inv_dict.pop("DesgloseIVA", ["DetalleIGIC"]) - inv_dict["ImporteTransmisionInmueblesSujetoAIVA"] = inv_dict.pop( - "ImporteTransmisionInmueblesSujetoAIVA", - ["ImporteTransmisionInmueblesSujetoAIGIC"], - ) - inv_dict["PeriodoImpositivo"] = inv_dict.pop( - "PeriodoImpositivo", ["DetalleIGIC"] - ) + def _get_aeat_invoice_dict_out(self, cancel=False): + inv_dict = super()._get_aeat_invoice_dict_out(cancel=cancel) + if self._get_sii_tax_agency() == self.env.ref( + "l10n_es_aeat.aeat_tax_agency_canarias" + ): + inv_dict["DetalleIVA"] = inv_dict.pop("DetalleIVA", ["DetalleIGIC"]) + inv_dict["DesgloseIVA"] = inv_dict.pop("DesgloseIVA", ["DetalleIGIC"]) + inv_dict["ImporteTransmisionInmueblesSujetoAIVA"] = inv_dict.pop( + "ImporteTransmisionInmueblesSujetoAIVA", + ["ImporteTransmisionInmueblesSujetoAIGIC"], + ) + inv_dict["PeriodoImpositivo"] = inv_dict.pop( + "PeriodoImpositivo", ["DetalleIGIC"] + ) return inv_dict def _get_sii_invoice_dict_in(self, cancel=False): - inv_dict = super()._get_sii_invoice_dict_in(cancel) - if self.sii_registration_key.code == "15": - for p in inv_dict["FacturaRecibida"]["DesgloseFactura"]["DesgloseIGIC"][ - "DetalleIGIC" - ]: - p.pop("CuotaSoportada") + inv_dict = super()._get_aeat_invoice_dict_in(cancel=cancel) + if self._get_sii_tax_agency() == self.env.ref( + "l10n_es_aeat.aeat_tax_agency_canarias" + ): + if self.sii_registration_key.code == "15": + for p in inv_dict["FacturaRecibida"]["DesgloseFactura"]["DesgloseIGIC"][ + "DetalleIGIC" + ]: + p.pop("CuotaSoportada") return inv_dict From ff62e59555078ad3d64bf66fb1261bdb70546059 Mon Sep 17 00:00:00 2001 From: sergio-teruel Date: Thu, 8 Jan 2026 18:48:38 +0100 Subject: [PATCH 3/4] [FIX] l10n_es_atc_sii_oca: DetalleIVA not replaced by DetalleIGIC --- l10n_es_atc_sii_oca/models/account_move.py | 46 ++++++++++++++-------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/l10n_es_atc_sii_oca/models/account_move.py b/l10n_es_atc_sii_oca/models/account_move.py index 86407cff69c..26ea9da5b37 100644 --- a/l10n_es_atc_sii_oca/models/account_move.py +++ b/l10n_es_atc_sii_oca/models/account_move.py @@ -2,7 +2,7 @@ # Copyright 2025 Tecnativa - Sergio Teruel import logging -from odoo import models +from odoo import api, models _logger = logging.getLogger(__name__) @@ -21,30 +21,44 @@ def _get_aeat_header(self, tipo_comunicacion=False, cancellation=False): header["IDVersionSii"] = "1.0" return header + @api.model + def _sii_atc_replace_tax_keys(self, invoice_dic): + """ + Recursively replace specific tax-related keys in a nested structure. + Only exact key matches are replaced. + """ + + key_map = { + "DetalleIVA": "DetalleIGIC", + "DesgloseIVA": "DesgloseIGIC", + "ImporteTransmisionInmueblesSujetoAIVA": ( + "ImporteTransmisionInmueblesSujetoAIGIC" + ), + } + if isinstance(invoice_dic, dict): + new_dict = {} + for key, value in invoice_dic.items(): + new_key = key_map.get(key, key) + new_dict[new_key] = self._sii_atc_replace_tax_keys(value) + return new_dict + if isinstance(invoice_dic, list): + return [self._sii_atc_replace_tax_keys(item) for item in invoice_dic] + if isinstance(invoice_dic, tuple): + return tuple(self._sii_atc_replace_tax_keys(item) for item in invoice_dic) + return invoice_dic + def _get_aeat_invoice_dict_out(self, cancel=False): inv_dict = super()._get_aeat_invoice_dict_out(cancel=cancel) if self._get_sii_tax_agency() == self.env.ref( "l10n_es_aeat.aeat_tax_agency_canarias" ): - inv_dict["DetalleIVA"] = inv_dict.pop("DetalleIVA", ["DetalleIGIC"]) - inv_dict["DesgloseIVA"] = inv_dict.pop("DesgloseIVA", ["DetalleIGIC"]) - inv_dict["ImporteTransmisionInmueblesSujetoAIVA"] = inv_dict.pop( - "ImporteTransmisionInmueblesSujetoAIVA", - ["ImporteTransmisionInmueblesSujetoAIGIC"], - ) - inv_dict["PeriodoImpositivo"] = inv_dict.pop( - "PeriodoImpositivo", ["DetalleIGIC"] - ) + inv_dict = self._sii_atc_replace_tax_keys(inv_dict) return inv_dict - def _get_sii_invoice_dict_in(self, cancel=False): + def _get_aeat_invoice_dict_in(self, cancel=False): inv_dict = super()._get_aeat_invoice_dict_in(cancel=cancel) if self._get_sii_tax_agency() == self.env.ref( "l10n_es_aeat.aeat_tax_agency_canarias" ): - if self.sii_registration_key.code == "15": - for p in inv_dict["FacturaRecibida"]["DesgloseFactura"]["DesgloseIGIC"][ - "DetalleIGIC" - ]: - p.pop("CuotaSoportada") + inv_dict = self._sii_atc_replace_tax_keys(inv_dict) return inv_dict From 95e14645fd679d1ec183e2e3c65aab3b797a882a Mon Sep 17 00:00:00 2001 From: sergio-teruel Date: Tue, 13 Jan 2026 11:21:51 +0100 Subject: [PATCH 4/4] [FIX] l10n_es_atc_sii_oca: Identifier type '02' for Contraparte not exists in SII atc TT60254 --- l10n_es_atc_sii_oca/models/__init__.py | 1 + l10n_es_atc_sii_oca/models/account_move.py | 7 +++++ l10n_es_atc_sii_oca/models/res_partner.py | 32 ++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 l10n_es_atc_sii_oca/models/res_partner.py diff --git a/l10n_es_atc_sii_oca/models/__init__.py b/l10n_es_atc_sii_oca/models/__init__.py index 9c0a4213854..74548553bd8 100644 --- a/l10n_es_atc_sii_oca/models/__init__.py +++ b/l10n_es_atc_sii_oca/models/__init__.py @@ -1 +1,2 @@ from . import account_move +from . import res_partner diff --git a/l10n_es_atc_sii_oca/models/account_move.py b/l10n_es_atc_sii_oca/models/account_move.py index 26ea9da5b37..adca2de6c81 100644 --- a/l10n_es_atc_sii_oca/models/account_move.py +++ b/l10n_es_atc_sii_oca/models/account_move.py @@ -62,3 +62,10 @@ def _get_aeat_invoice_dict_in(self, cancel=False): ): inv_dict = self._sii_atc_replace_tax_keys(inv_dict) return inv_dict + + def _get_sii_identifier(self): + if self._get_sii_tax_agency() == self.env.ref( + "l10n_es_aeat.aeat_tax_agency_canarias" + ): + self = self.with_context(is_canary_tax_agency=True) + return super()._get_sii_identifier() diff --git a/l10n_es_atc_sii_oca/models/res_partner.py b/l10n_es_atc_sii_oca/models/res_partner.py new file mode 100644 index 00000000000..6cf47cbef42 --- /dev/null +++ b/l10n_es_atc_sii_oca/models/res_partner.py @@ -0,0 +1,32 @@ +# Copyright 2026 Tecnativa - Carlos Dauden +# Copyright 2026 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import models +from odoo.tools import ormcache_context + + +class ResPartner(models.Model): + _inherit = "res.partner" + + @ormcache_context("self.vat, self.country_id", keys=("is_canary_tax_agency",)) + def _parse_aeat_vat_info(self): + # NOTE: + # The Canary Islands Tax Agency (ATC) SII-IGIC implementation does NOT support + # IDType "02" (EU VAT number / NIF-IVA) used by the Spanish AEAT SII (VAT). + # + # Although the data structure is similar, ATC does not validate intra-community + # operators nor VIES registrations, since IGIC is not VAT. + # + # As a result, foreign VAT numbers must be reported using IDType "04" + # ("Official identification document") instead of "02". + # + # Using IDType "02" causes ATC to reject the record with error code 1103 + # ("Valor del campo IDType incorrecto"). + # + # This conversion is intentional and required for SII submissions to ATC. + country_code, identifier_type, identifier = super()._parse_aeat_vat_info() + is_canary_tax_agency = self.env.context.get("is_canary_tax_agency") + if is_canary_tax_agency and identifier_type == "02": + identifier_type = "04" + return country_code, identifier_type, identifier