diff --git a/l10n_es_aeat_sii_oca_extension/README.rst b/l10n_es_aeat_sii_oca_extension/README.rst new file mode 100644 index 000000000..37dfda777 --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/README.rst @@ -0,0 +1,174 @@ +======================================================= +Suministro Inmediato de Información en el IVA Extension +======================================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:9eca57c8e44bf6514362004fcb23f016cda0be94835c9130dbe2fa010b81ddef + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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_aeat_sii_oca_extension + :alt: NuoBiT/odoo-addons + +|badge1| |badge2| |badge3| + +This module extends the OCA SII (Suministro Inmediato de Información en +el IVA) module with additional functionalities and fixes that are not +accepted or delayed by the OCA l10n_spain localization community. + +**All Features Provided:** + +**1. CuotaDeducible Support (Partially Deductible Taxes)** + +For Received Invoices (Vendor Bills): + +- Automatically calculates the actual deductible amount of VAT based on + tax configuration +- Only includes the portion that is truly deductible (based on tax + repartition lines with account) +- Adds the CuotaDeducible field to SII submissions for received invoices +- Works for taxes mapped as SFRS (IVA Soportado) and SFRISP (IVA + Inversión del Sujeto Pasivo) + +How it works: + +- Extends ``account.move.line`` to track actual deductible amounts + during tax processing +- Automatically sums deductible portions based on tax repartition + configuration +- No configuration needed - works automatically if tax has partial + deductibility configured + +**2. Clave "06" Support (Grupo de Entidades - Modalidad Avanzada)** + +Problem Solved: + +Companies using **ClaveRegimenEspecialOTrascendencia = "06"** (VAT group +in advanced mode) receive **SII Error 1234** when submitting invoices +with both services and goods. + +What the module does automatically: + +- For Outgoing Invoices (Customer Invoices): + + - Merges services (PrestacionServicios) and goods (Entrega) into a + single tax breakdown + - Consolidates multiple tax lines with the same rate (TipoImpositivo) + into one line + - Transforms from DesgloseTipoOperacion to DesgloseFactura structure + - Calculates and adds BaseImponibleACoste field automatically + - Rounds BaseImponibleACoste to proper decimal precision + +- For Incoming Invoices (Vendor Bills): + + - Calculates and adds BaseImponibleACoste field automatically + - Ensures proper structure for AEAT validation + +Result: SII submissions pass AEAT validation without Error 1234 + +**3. Extensible Tax Agency Hooks** + +For Advanced Customizations: + +- Provides hooks in ``aeat.tax.agency`` model to extend SII web service + configurations +- Methods ``_prepare_sii_wdsl_mapping()`` and + ``_prepare_sii_port_name_mapping()`` can be overridden +- Allows custom modules to add new WSDL endpoints or modify connection + parameters +- Useful for specialized tax agency configurations or testing + environments + +**When to Use This Module:** + +Install this module if you need: + +- Partially deductible VAT reporting (CuotaDeducible field in received + invoices) +- VAT group in advanced mode (modalidad avanzada) with clave "06" +- Fix for SII Error 1234 when submitting invoices with services + goods +- Custom tax agency configurations (extensibility hooks) + +**How It Works:** + +The module works automatically after installation: + +- No configuration required for standard features +- Only activates clave "06" transformations when registration key = "06" + is detected +- Doesn't affect other invoices - backwards compatible +- CuotaDeducible is calculated for all received invoices based on tax + configuration +- All transformations happen transparently during SII submission + +**Technical Details:** + +Models Extended: + +- ``account.move`` - Adds SII invoice processing for clave "06" and + CuotaDeducible +- ``account.move.line`` - Tracks actual deductible amounts during tax + processing +- ``aeat.tax.agency`` - Provides extensibility hooks for custom + configurations + +Key Methods: + +- ``_get_sii_in_taxes_deductible()`` - Calculates deductible VAT amount +- ``_get_sii_out_taxes()`` - Transforms tax breakdown for clave "06" + outgoing invoices +- ``_get_sii_invoice_dict_in()`` - Adds CuotaDeducible and + BaseImponibleACoste to received invoices +- ``_get_sii_invoice_dict_out()`` - Adds BaseImponibleACoste to sent + invoices +- ``_process_aeat_tax_base_info()`` / ``_process_aeat_tax_fee_info()`` - + Track deductible amounts + +**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 `__: + + - Frank Cespedes fcespedes@nuobit.com + - Kilian Niubo kniubo@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_aeat_sii_oca_extension/__init__.py b/l10n_es_aeat_sii_oca_extension/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/l10n_es_aeat_sii_oca_extension/__manifest__.py b/l10n_es_aeat_sii_oca_extension/__manifest__.py new file mode 100644 index 000000000..a5e51e10f --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright NuoBiT Solutions SL - Eric Antones +# Copyright NuoBiT Solutions SL - Kilian Niubo +# Copyright 2025 NuoBiT Solutions SL - Deniz Gallo +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Suministro Inmediato de Información en el IVA Extension", + "summary": "This module extends the OCA SII module with new functionalities " + "and fixes that are not accepted or delayed recurrently by " + "the OCA l10n_spain localization community", + "author": "NuoBiT Solutions SL", + "category": "Accounting & Finance", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "website": "https://github.com/NuoBiT/odoo-addons", + "depends": [ + "l10n_es_aeat_sii_oca", + ], +} diff --git a/l10n_es_aeat_sii_oca_extension/models/__init__.py b/l10n_es_aeat_sii_oca_extension/models/__init__.py new file mode 100644 index 000000000..5f984201c --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/models/__init__.py @@ -0,0 +1,2 @@ +from . import account_move +from . import aeat_tax_agency diff --git a/l10n_es_aeat_sii_oca_extension/models/account_move.py b/l10n_es_aeat_sii_oca_extension/models/account_move.py new file mode 100644 index 000000000..7b5459d33 --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/models/account_move.py @@ -0,0 +1,209 @@ +# Copyright NuoBiT Solutions- Eric Antones +# Copyright 2026 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 UserError, ValidationError + +from odoo.addons.l10n_es_aeat.models.aeat_mixin import round_by_keys + + +def sum_key(elem, key): + value = 0 + if isinstance(elem, (list | tuple)): + for v in elem: + value += sum_key(v, key) + elif isinstance(elem, dict): + for k, v in elem.items(): + value += v if k == key else sum_key(v, key) + return value + + +def merge_nested_dicts(target_dict, source_dict, key_funcs=None, path=None, level=0): + def get_path_value(data, path): + for key in path: + data = data[key] + return data + + def set_path_value(data, path, value): + for key in path[:-1]: + data = data[key] + data[path[-1]] = value + + def path_exists(data, path): + for key in path: + if key not in data: + return False + data = data[key] + return True + + if key_funcs is None: + key_funcs = {} + if path is None: + path = [] + if isinstance(source_dict, (str | int | float | bool)): + if get_path_value(target_dict, path) != source_dict: + raise ValidationError( + _( + "SII data merge error: No match at path %(path)s:" + " %(target_value)s != %(source_value)s" + ) + % { + "path": path, + "target_value": get_path_value(target_dict, path), + "source_value": source_dict, + } + ) + elif isinstance(source_dict, dict): + for key, value in source_dict.items(): + new_path = path + [key] + if path_exists(target_dict, new_path): + if key in key_funcs: + func = key_funcs[key] + existing_value = get_path_value(target_dict, new_path) + merged_value = func(existing_value, source_dict[key]) + set_path_value(target_dict, new_path, merged_value) + else: + merge_nested_dicts( + target_dict, + value, + key_funcs=key_funcs, + path=new_path, + level=level + 1, + ) + else: + set_path_value(target_dict, new_path, value) + else: + raise UserError( + _("SII data merge error: Unsupported type: %(type)s: %(value)s") + % {"type": type(source_dict), "value": source_dict} + ) + + +def merge_detalle_iva(tax_details_list1, tax_details_list2): + """Merge tax details (DetalleIVA) by grouping and summing by TipoImpositivo.""" + merged_by_rate = {} + rate_key = "TipoImpositivo" + + for tax_detail in tax_details_list1 + tax_details_list2: + if rate_key not in tax_detail: + raise ValidationError( + _("SII tax detail merge error: Missing '%(key)s' key in %(detail)s") + % {"key": rate_key, "detail": tax_detail} + ) + tax_detail = dict(tax_detail) + tax_rate = tax_detail.pop(rate_key) + + if tax_rate not in merged_by_rate: + merged_by_rate[tax_rate] = tax_detail + else: + for key, value in tax_detail.items(): + if key not in merged_by_rate[tax_rate]: + raise ValidationError( + _( + "SII tax detail merge error:" + " Missing '%(key)s' key in %(detail)s" + ) + % {"key": key, "detail": merged_by_rate[tax_rate]} + ) + merged_by_rate[tax_rate][key] += value + + result_list = [] + for tax_rate, tax_data in merged_by_rate.items(): + result_list.append( + { + rate_key: tax_rate, + **tax_data, + } + ) + return result_list + + +class AccountMove(models.Model): + _inherit = "account.move" + + def _get_sii_in_taxes_deductible(self): + self.ensure_one() + taxes_sfrs = self._get_aeat_taxes_map(["SFRS"], self.date) + taxes_sfrisp = self._get_aeat_taxes_map(["SFRISP"], self.date) + tax_deductible_amount = 0.0 + tax_lines = self._get_aeat_tax_info() + for tax_line in tax_lines.values(): + tax = tax_line["tax"] + if tax in taxes_sfrisp + taxes_sfrs: + tax_deductible_amount += tax_line["actual_deductible_amount"] + return tax_deductible_amount + + def _get_aeat_invoice_dict_in(self, cancel=False): + inv_dict = super()._get_aeat_invoice_dict_in(cancel=cancel) + if not cancel: + inv_dict["FacturaRecibida"]["CuotaDeducible"] = ( + self._get_sii_in_taxes_deductible() + ) + if "06" in ( + self.sii_registration_key.code, + self.sii_registration_key_additional1.code, + self.sii_registration_key_additional2.code, + ): + inv_dict["FacturaRecibida"]["BaseImponibleACoste"] = sum_key( + inv_dict["FacturaRecibida"]["DesgloseFactura"], + "BaseImponible", + ) + return inv_dict + + def _get_sii_out_taxes(self): + tipo_desglose, not_in_amount_total = super()._get_sii_out_taxes() + if "06" in ( + self.sii_registration_key.code, + self.sii_registration_key_additional1.code, + self.sii_registration_key_additional2.code, + ): + if "DesgloseTipoOperacion" in tipo_desglose: + operation_types = list(tipo_desglose["DesgloseTipoOperacion"].values()) + merged_data = operation_types[0] + for operation_type in operation_types[1:]: + merge_nested_dicts( + merged_data, operation_type, {"DetalleIVA": merge_detalle_iva} + ) + tipo_desglose = {"DesgloseFactura": merged_data} + return tipo_desglose, not_in_amount_total + + def _get_aeat_invoice_dict_out(self, cancel=False): + inv_dict = super()._get_aeat_invoice_dict_out(cancel=cancel) + if not cancel: + if "06" in ( + self.sii_registration_key.code, + self.sii_registration_key_additional1.code, + self.sii_registration_key_additional2.code, + ): + inv_dict["FacturaExpedida"]["BaseImponibleACoste"] = sum_key( + inv_dict["FacturaExpedida"]["TipoDesglose"], "BaseImponible" + ) + return inv_dict + + def _get_aeat_invoice_dict(self): + inv_dict = super()._get_aeat_invoice_dict() + round_by_keys( + inv_dict, + [ + "BaseImponibleACoste", + ], + ) + return inv_dict + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + def _process_aeat_tax_base_info(self, res, tax, sign): + super()._process_aeat_tax_base_info(res, tax, sign) + for tax in res.keys(): + res[tax].setdefault("actual_deductible_amount", 0) + return res + + def _process_aeat_tax_fee_info(self, res, tax, sign): + super()._process_aeat_tax_fee_info(res, tax, sign) + res[tax].setdefault("actual_deductible_amount", 0) + if self.tax_repartition_line_id.account_id: + res[tax]["actual_deductible_amount"] += self.balance * sign + return res diff --git a/l10n_es_aeat_sii_oca_extension/models/aeat_tax_agency.py b/l10n_es_aeat_sii_oca_extension/models/aeat_tax_agency.py new file mode 100644 index 000000000..38cc80db2 --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/models/aeat_tax_agency.py @@ -0,0 +1,41 @@ +# Copyright NuoBiT Solutions SL - Eric Antones +# Copyright NuoBiT Solutions SL - Kilian Niubo +# 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.addons.l10n_es_aeat_sii_oca.models.aeat_tax_agency import ( + SII_PORT_NAME_MAPPING, + SII_WDSL_MAPPING, +) + + +class AeatTaxAgency(models.Model): + _inherit = "aeat.tax.agency" + + def _prepare_sii_wdsl_mapping(self): + return SII_WDSL_MAPPING + + def _prepare_sii_port_name_mapping(self): + return SII_PORT_NAME_MAPPING + + def _connect_params_sii(self, mapping_key, company): + self.ensure_one() + if SII_WDSL_MAPPING.get(mapping_key) and SII_PORT_NAME_MAPPING.get(mapping_key): + return super()._connect_params_sii(mapping_key, company) + sii_wdsl_mapping = self._prepare_sii_wdsl_mapping() + sii_port_name_mapping = self._prepare_sii_port_name_mapping() + + wsdl_field = sii_wdsl_mapping[mapping_key] + wsdl_test_field = wsdl_field + "_test_address" + port_name = sii_port_name_mapping[mapping_key] + address = getattr(self, wsdl_test_field) if company.sii_test else False + if not address and company.sii_test: + # If not test address is provides we try to get it using the port name. + port_name += "Pruebas" + return { + "wsdl": getattr(self, wsdl_field), + "address": address, + "port_name": port_name, + } diff --git a/l10n_es_aeat_sii_oca_extension/pyproject.toml b/l10n_es_aeat_sii_oca_extension/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/l10n_es_aeat_sii_oca_extension/readme/CONTRIBUTORS.md b/l10n_es_aeat_sii_oca_extension/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..3dd5aac73 --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- [NuoBiT](https://www.nuobit.com): + - Frank Cespedes + - Kilian Niubo + - Deniz Gallo diff --git a/l10n_es_aeat_sii_oca_extension/readme/DESCRIPTION.md b/l10n_es_aeat_sii_oca_extension/readme/DESCRIPTION.md new file mode 100644 index 000000000..8741af7a5 --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/readme/DESCRIPTION.md @@ -0,0 +1,108 @@ +This module extends the OCA SII (Suministro Inmediato de Información en +el IVA) module with additional functionalities and fixes that are not +accepted or delayed by the OCA l10n_spain localization community. + +**All Features Provided:** + +**1. CuotaDeducible Support (Partially Deductible Taxes)** + +For Received Invoices (Vendor Bills): + +- Automatically calculates the actual deductible amount of VAT based on + tax configuration +- Only includes the portion that is truly deductible (based on tax + repartition lines with account) +- Adds the CuotaDeducible field to SII submissions for received invoices +- Works for taxes mapped as SFRS (IVA Soportado) and SFRISP (IVA + Inversión del Sujeto Pasivo) + +How it works: + +- Extends `account.move.line` to track actual deductible amounts during + tax processing +- Automatically sums deductible portions based on tax repartition + configuration +- No configuration needed - works automatically if tax has partial + deductibility configured + +**2. Clave "06" Support (Grupo de Entidades - Modalidad Avanzada)** + +Problem Solved: + +Companies using **ClaveRegimenEspecialOTrascendencia = "06"** (VAT group +in advanced mode) receive **SII Error 1234** when submitting invoices +with both services and goods. + +What the module does automatically: + +- For Outgoing Invoices (Customer Invoices): + - Merges services (PrestacionServicios) and goods (Entrega) into a + single tax breakdown + - Consolidates multiple tax lines with the same rate (TipoImpositivo) + into one line + - Transforms from DesgloseTipoOperacion to DesgloseFactura structure + - Calculates and adds BaseImponibleACoste field automatically + - Rounds BaseImponibleACoste to proper decimal precision +- For Incoming Invoices (Vendor Bills): + - Calculates and adds BaseImponibleACoste field automatically + - Ensures proper structure for AEAT validation + +Result: SII submissions pass AEAT validation without Error 1234 + +**3. Extensible Tax Agency Hooks** + +For Advanced Customizations: + +- Provides hooks in `aeat.tax.agency` model to extend SII web service + configurations +- Methods `_prepare_sii_wdsl_mapping()` and + `_prepare_sii_port_name_mapping()` can be overridden +- Allows custom modules to add new WSDL endpoints or modify connection + parameters +- Useful for specialized tax agency configurations or testing + environments + +**When to Use This Module:** + +Install this module if you need: + +- Partially deductible VAT reporting (CuotaDeducible field in received + invoices) +- VAT group in advanced mode (modalidad avanzada) with clave "06" +- Fix for SII Error 1234 when submitting invoices with services + goods +- Custom tax agency configurations (extensibility hooks) + +**How It Works:** + +The module works automatically after installation: + +- No configuration required for standard features +- Only activates clave "06" transformations when registration key = "06" + is detected +- Doesn't affect other invoices - backwards compatible +- CuotaDeducible is calculated for all received invoices based on tax + configuration +- All transformations happen transparently during SII submission + +**Technical Details:** + +Models Extended: + +- `account.move` - Adds SII invoice processing for clave "06" and + CuotaDeducible +- `account.move.line` - Tracks actual deductible amounts during tax + processing +- `aeat.tax.agency` - Provides extensibility hooks for custom + configurations + +Key Methods: + +- `_get_sii_in_taxes_deductible()` - Calculates deductible VAT amount +- `_get_sii_out_taxes()` - Transforms tax breakdown for clave "06" + outgoing invoices +- `_get_sii_invoice_dict_in()` - Adds CuotaDeducible and + BaseImponibleACoste to received invoices +- `_get_sii_invoice_dict_out()` - Adds BaseImponibleACoste to sent + invoices +- `_process_aeat_tax_base_info()` / `_process_aeat_tax_fee_info()` - + Track deductible amounts diff --git a/l10n_es_aeat_sii_oca_extension/static/description/icon.png b/l10n_es_aeat_sii_oca_extension/static/description/icon.png new file mode 100644 index 000000000..1cd641e79 Binary files /dev/null and b/l10n_es_aeat_sii_oca_extension/static/description/icon.png differ diff --git a/l10n_es_aeat_sii_oca_extension/static/description/index.html b/l10n_es_aeat_sii_oca_extension/static/description/index.html new file mode 100644 index 000000000..f6a25be1c --- /dev/null +++ b/l10n_es_aeat_sii_oca_extension/static/description/index.html @@ -0,0 +1,522 @@ + + + + + +Suministro Inmediato de Información en el IVA Extension + + + +
+

Suministro Inmediato de Información en el IVA Extension

+ + +

Beta License: AGPL-3 NuoBiT/odoo-addons

+

This module extends the OCA SII (Suministro Inmediato de Información en +el IVA) module with additional functionalities and fixes that are not +accepted or delayed by the OCA l10n_spain localization community.

+

All Features Provided:

+

1. CuotaDeducible Support (Partially Deductible Taxes)

+

For Received Invoices (Vendor Bills):

+
    +
  • Automatically calculates the actual deductible amount of VAT based on +tax configuration
  • +
  • Only includes the portion that is truly deductible (based on tax +repartition lines with account)
  • +
  • Adds the CuotaDeducible field to SII submissions for received invoices
  • +
  • Works for taxes mapped as SFRS (IVA Soportado) and SFRISP (IVA +Inversión del Sujeto Pasivo)
  • +
+

How it works:

+
    +
  • Extends account.move.line to track actual deductible amounts +during tax processing
  • +
  • Automatically sums deductible portions based on tax repartition +configuration
  • +
  • No configuration needed - works automatically if tax has partial +deductibility configured
  • +
+

2. Clave “06” Support (Grupo de Entidades - Modalidad Avanzada)

+

Problem Solved:

+

Companies using ClaveRegimenEspecialOTrascendencia = “06” (VAT group +in advanced mode) receive SII Error 1234 when submitting invoices +with both services and goods.

+

What the module does automatically:

+
    +
  • For Outgoing Invoices (Customer Invoices):
      +
    • Merges services (PrestacionServicios) and goods (Entrega) into a +single tax breakdown
    • +
    • Consolidates multiple tax lines with the same rate (TipoImpositivo) +into one line
    • +
    • Transforms from DesgloseTipoOperacion to DesgloseFactura structure
    • +
    • Calculates and adds BaseImponibleACoste field automatically
    • +
    • Rounds BaseImponibleACoste to proper decimal precision
    • +
    +
  • +
  • For Incoming Invoices (Vendor Bills):
      +
    • Calculates and adds BaseImponibleACoste field automatically
    • +
    • Ensures proper structure for AEAT validation
    • +
    +
  • +
+

Result: SII submissions pass AEAT validation without Error 1234

+

3. Extensible Tax Agency Hooks

+

For Advanced Customizations:

+
    +
  • Provides hooks in aeat.tax.agency model to extend SII web service +configurations
  • +
  • Methods _prepare_sii_wdsl_mapping() and +_prepare_sii_port_name_mapping() can be overridden
  • +
  • Allows custom modules to add new WSDL endpoints or modify connection +parameters
  • +
  • Useful for specialized tax agency configurations or testing +environments
  • +
+

When to Use This Module:

+

Install this module if you need:

+
    +
  • Partially deductible VAT reporting (CuotaDeducible field in received +invoices)
  • +
  • VAT group in advanced mode (modalidad avanzada) with clave “06”
  • +
  • Fix for SII Error 1234 when submitting invoices with services + goods
  • +
  • Custom tax agency configurations (extensibility hooks)
  • +
+

How It Works:

+

The module works automatically after installation:

+
    +
  • No configuration required for standard features
  • +
  • Only activates clave “06” transformations when registration key = “06” +is detected
  • +
  • Doesn’t affect other invoices - backwards compatible
  • +
  • CuotaDeducible is calculated for all received invoices based on tax +configuration
  • +
  • All transformations happen transparently during SII submission
  • +
+

Technical Details:

+

Models Extended:

+
    +
  • account.move - Adds SII invoice processing for clave “06” and +CuotaDeducible
  • +
  • account.move.line - Tracks actual deductible amounts during tax +processing
  • +
  • aeat.tax.agency - Provides extensibility hooks for custom +configurations
  • +
+

Key Methods:

+
    +
  • _get_sii_in_taxes_deductible() - Calculates deductible VAT amount
  • +
  • _get_sii_out_taxes() - Transforms tax breakdown for clave “06” +outgoing invoices
  • +
  • _get_sii_invoice_dict_in() - Adds CuotaDeducible and +BaseImponibleACoste to received invoices
  • +
  • _get_sii_invoice_dict_out() - Adds BaseImponibleACoste to sent +invoices
  • +
  • _process_aeat_tax_base_info() / _process_aeat_tax_fee_info() - +Track deductible amounts
  • +
+

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.

+
+
+
+ +