mirror of
https://github.com/bringout/oca-ocb-l10n_europe.git
synced 2026-04-27 11:02:05 +02:00
Initial commit: L10N_Europe packages
This commit is contained in:
commit
9803722600
2377 changed files with 380711 additions and 0 deletions
60
odoo-bringout-oca-ocb-l10n_es_edi_sii/README.md
Normal file
60
odoo-bringout-oca-ocb-l10n_es_edi_sii/README.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# Spain - SII EDI Suministro de Libros
|
||||
|
||||
|
||||
This module sends the taxes information (mostly VAT) of the
|
||||
vendor bills and customer invoices to the SII. It is called
|
||||
Procedimiento G417 - IVA. Llevanza de libros registro. It is
|
||||
required for every company with a turnover of +6M€ and others can
|
||||
already make use of it. The invoices are automatically
|
||||
sent after validation.
|
||||
|
||||
How the information is sent to the SII depends on the
|
||||
configuration that is put in the taxes. The taxes
|
||||
that were in the chart template (l10n_es) are automatically
|
||||
configured to have the right type. It is possible however
|
||||
that extra taxes need to be created for certain exempt/no sujeta reasons.
|
||||
|
||||
You need to configure your certificate and the tax agency.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-ocb-l10n_es_edi_sii
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
This addon depends on:
|
||||
- l10n_es
|
||||
- account_edi
|
||||
|
||||
## Manifest Information
|
||||
|
||||
- **Name**: Spain - SII EDI Suministro de Libros
|
||||
- **Version**: 1.0
|
||||
- **Category**: Accounting/Localizations/EDI
|
||||
- **License**: LGPL-3
|
||||
- **Installable**: False
|
||||
|
||||
## Source
|
||||
|
||||
Based on [OCA/OCB](https://github.com/OCA/OCB) branch 16.0, addon `l10n_es_edi_sii`.
|
||||
|
||||
## License
|
||||
|
||||
This package maintains the original LGPL-3 license from the upstream Odoo project.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Overview: doc/OVERVIEW.md
|
||||
- Architecture: doc/ARCHITECTURE.md
|
||||
- Models: doc/MODELS.md
|
||||
- Controllers: doc/CONTROLLERS.md
|
||||
- Wizards: doc/WIZARDS.md
|
||||
- Install: doc/INSTALL.md
|
||||
- Usage: doc/USAGE.md
|
||||
- Configuration: doc/CONFIGURATION.md
|
||||
- Dependencies: doc/DEPENDENCIES.md
|
||||
- Troubleshooting: doc/TROUBLESHOOTING.md
|
||||
- FAQ: doc/FAQ.md
|
||||
32
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/ARCHITECTURE.md
Normal file
32
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
U[Users] -->|HTTP| V[Views and QWeb Templates]
|
||||
V --> C[Controllers]
|
||||
V --> W[Wizards – Transient Models]
|
||||
C --> M[Models and ORM]
|
||||
W --> M
|
||||
M --> R[Reports]
|
||||
DX[Data XML] --> M
|
||||
S[Security – ACLs and Groups] -. enforces .-> M
|
||||
|
||||
subgraph L10n_es_edi_sii Module - l10n_es_edi_sii
|
||||
direction LR
|
||||
M:::layer
|
||||
W:::layer
|
||||
C:::layer
|
||||
V:::layer
|
||||
R:::layer
|
||||
S:::layer
|
||||
DX:::layer
|
||||
end
|
||||
|
||||
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
|
||||
```
|
||||
|
||||
Notes
|
||||
- Views include tree/form/kanban templates and report templates.
|
||||
- Controllers provide website/portal routes when present.
|
||||
- Wizards are UI flows implemented with `models.TransientModel`.
|
||||
- Data XML loads data/demo records; Security defines groups and access.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configuration
|
||||
|
||||
Refer to Odoo settings for l10n_es_edi_sii. Configure related models, access rights, and options as needed.
|
||||
3
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/CONTROLLERS.md
Normal file
3
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/CONTROLLERS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Controllers
|
||||
|
||||
This module does not define custom HTTP controllers.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Dependencies
|
||||
|
||||
This addon depends on:
|
||||
|
||||
- [l10n_es](../../odoo-bringout-oca-ocb-l10n_es)
|
||||
- [account_edi](../../odoo-bringout-oca-ocb-account_edi)
|
||||
4
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/FAQ.md
Normal file
4
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/FAQ.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# FAQ
|
||||
|
||||
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
|
||||
- Q: How to enable? A: Start server with --addon l10n_es_edi_sii or install in UI.
|
||||
7
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/INSTALL.md
Normal file
7
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/INSTALL.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Install
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-ocb-l10n_es_edi_sii"
|
||||
# or
|
||||
uv pip install odoo-bringout-oca-ocb-l10n_es_edi_sii"
|
||||
```
|
||||
20
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/MODELS.md
Normal file
20
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/MODELS.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Models
|
||||
|
||||
Detected core models and extensions in l10n_es_edi_sii.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class account_tax
|
||||
class account_tax_template
|
||||
class l10n_es_edi_certificate
|
||||
class l10n_es_sii_account_tax_mixin
|
||||
class account_edi_format
|
||||
class account_move
|
||||
class mail_template
|
||||
class res_company
|
||||
class res_config_settings
|
||||
```
|
||||
|
||||
Notes
|
||||
- Classes show model technical names; fields omitted for brevity.
|
||||
- Items listed under _inherit are extensions of existing models.
|
||||
6
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/OVERVIEW.md
Normal file
6
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/OVERVIEW.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Overview
|
||||
|
||||
Packaged Odoo addon: l10n_es_edi_sii. Provides features documented in upstream Odoo 16 under this addon.
|
||||
|
||||
- Source: OCA/OCB 16.0, addon l10n_es_edi_sii
|
||||
- License: LGPL-3
|
||||
3
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/REPORTS.md
Normal file
3
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/REPORTS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Reports
|
||||
|
||||
This module does not define custom reports.
|
||||
41
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/SECURITY.md
Normal file
41
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/SECURITY.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Security
|
||||
|
||||
Access control and security definitions in l10n_es_edi_sii.
|
||||
|
||||
## Access Control Lists (ACLs)
|
||||
|
||||
Model access permissions defined in:
|
||||
- **[ir.model.access.csv](../l10n_es_edi_sii/security/ir.model.access.csv)**
|
||||
- 1 model access rules
|
||||
|
||||
## Record Rules
|
||||
|
||||
Row-level security rules defined in:
|
||||
|
||||
## Security Groups & Configuration
|
||||
|
||||
Security groups and permissions defined in:
|
||||
- **[l10n_es_edi_certificate.xml](../l10n_es_edi_sii/security/l10n_es_edi_certificate.xml)**
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Security Layers"
|
||||
A[Users] --> B[Groups]
|
||||
B --> C[Access Control Lists]
|
||||
C --> D[Models]
|
||||
B --> E[Record Rules]
|
||||
E --> F[Individual Records]
|
||||
end
|
||||
```
|
||||
|
||||
Security files overview:
|
||||
- **[ir.model.access.csv](../l10n_es_edi_sii/security/ir.model.access.csv)**
|
||||
- Model access permissions (CRUD rights)
|
||||
- **[l10n_es_edi_certificate.xml](../l10n_es_edi_sii/security/l10n_es_edi_certificate.xml)**
|
||||
- Security groups, categories, and XML-based rules
|
||||
|
||||
Notes
|
||||
- Access Control Lists define which groups can access which models
|
||||
- Record Rules provide row-level security (filter records by user/group)
|
||||
- Security groups organize users and define permission sets
|
||||
- All security is enforced at the ORM level by Odoo
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# Troubleshooting
|
||||
|
||||
- Ensure Python and Odoo environment matches repo guidance.
|
||||
- Check database connectivity and logs if startup fails.
|
||||
- Validate that dependent addons listed in DEPENDENCIES.md are installed.
|
||||
7
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/USAGE.md
Normal file
7
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/USAGE.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Usage
|
||||
|
||||
Start Odoo including this addon (from repo root):
|
||||
|
||||
```bash
|
||||
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon l10n_es_edi_sii
|
||||
```
|
||||
3
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/WIZARDS.md
Normal file
3
odoo-bringout-oca-ocb-l10n_es_edi_sii/doc/WIZARDS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Wizards
|
||||
|
||||
This module does not include UI wizards.
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import models
|
||||
from . import wizards
|
||||
from odoo import api, SUPERUSER_ID
|
||||
|
||||
|
||||
def _l10n_es_edi_post_init(cr, registry):
|
||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||
companies = env['res.company'].search([('partner_id.country_id.code', '=', 'ES')])
|
||||
|
||||
all_chart_templates = companies.chart_template_id
|
||||
current_chart_template = all_chart_templates
|
||||
while current_chart_template.parent_id:
|
||||
all_chart_templates |= current_chart_template.parent_id
|
||||
current_chart_template = current_chart_template.parent_id
|
||||
|
||||
if all_chart_templates:
|
||||
tax_templates = env['account.tax.template'].search([
|
||||
('chart_template_id', 'in', all_chart_templates.ids),
|
||||
'|', '|', '|',
|
||||
('l10n_es_type', '!=', False),
|
||||
('l10n_es_exempt_reason', '!=', False),
|
||||
('tax_scope', '!=', False),
|
||||
('l10n_es_bien_inversion', '!=', False),
|
||||
])
|
||||
xml_ids = tax_templates.get_external_id()
|
||||
for company in companies:
|
||||
for tax_template in tax_templates:
|
||||
module, xml_id = xml_ids.get(tax_template.id).split('.')
|
||||
tax = env.ref('%s.%s_%s' % (module, company.id, xml_id), raise_if_not_found=False)
|
||||
if tax:
|
||||
tax.write({
|
||||
'l10n_es_exempt_reason': tax_template.l10n_es_exempt_reason,
|
||||
'tax_scope': tax_template.tax_scope,
|
||||
'l10n_es_type': tax_template.l10n_es_type,
|
||||
'l10n_es_bien_inversion': tax_template.l10n_es_bien_inversion,
|
||||
})
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
# Thanks to AEOdoo and the Spanish community
|
||||
# Specially among others Ignacio Ibeas, Pedro Baeza and Landoo
|
||||
|
||||
{
|
||||
'name': "Spain - SII EDI Suministro de Libros",
|
||||
'version': '1.0',
|
||||
'category': 'Accounting/Localizations/EDI',
|
||||
'description': """
|
||||
This module sends the taxes information (mostly VAT) of the
|
||||
vendor bills and customer invoices to the SII. It is called
|
||||
Procedimiento G417 - IVA. Llevanza de libros registro. It is
|
||||
required for every company with a turnover of +6M€ and others can
|
||||
already make use of it. The invoices are automatically
|
||||
sent after validation.
|
||||
|
||||
How the information is sent to the SII depends on the
|
||||
configuration that is put in the taxes. The taxes
|
||||
that were in the chart template (l10n_es) are automatically
|
||||
configured to have the right type. It is possible however
|
||||
that extra taxes need to be created for certain exempt/no sujeta reasons.
|
||||
|
||||
You need to configure your certificate and the tax agency.
|
||||
""",
|
||||
'depends': [
|
||||
'l10n_es',
|
||||
'account_edi',
|
||||
],
|
||||
'data': [
|
||||
'data/account_tax_data.xml',
|
||||
'data/account_edi_data.xml',
|
||||
'data/res_partner_data.xml',
|
||||
|
||||
'security/ir.model.access.csv',
|
||||
'security/l10n_es_edi_certificate.xml',
|
||||
|
||||
'views/account_tax_views.xml',
|
||||
'views/l10n_es_edi_certificate_views.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/account_move_views.xml',
|
||||
],
|
||||
'demo': ['demo/demo_certificate.xml'],
|
||||
'external_dependencies': {
|
||||
'python': ['pyOpenSSL'],
|
||||
},
|
||||
'post_init_hook': '_l10n_es_edi_post_init',
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="edi_es_sii" model="account.edi.format">
|
||||
<field name="name">SII IVA Llevanza de libros registro (ES)</field>
|
||||
<field name="code">es_sii</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,446 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="l10n_es.account_tax_template_s_iva21b" model="account.tax.template">
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva21s" model="account.tax.template">
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva21isp" model="account.tax.template">
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_bc" model="account.tax.template">
|
||||
<field name="name">21% IVA soportado (bienes corrientes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_sc" model="account.tax.template">
|
||||
<field name="name">21% IVA soportado (servicios corrientes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_sp_in" model="account.tax.template">
|
||||
<field name="name">IVA 21% Adquisición de servicios intracomunitarios</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_ic_bc" model="account.tax.template">
|
||||
<field name="name">IVA 21% Adquisición Intracomunitaria. Bienes corrientes</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_ic_bi" model="account.tax.template">
|
||||
<field name="name">IVA 21% Adquisición Intracomunitaria. Bienes de inversión</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_ibc" model="account.tax.template">
|
||||
<field name="name">IVA 21% Importaciones bienes corrientes</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_ibi" model="account.tax.template">
|
||||
<field name="name">IVA 21% Importaciones bienes de inversión</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf21td" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF (Trabajadores) dinerarios</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_sp_ex" model="account.tax.template">
|
||||
<field name="name">IVA 4% Adquisición de servicios extracomunitarios</field>
|
||||
<field name="l10n_es_type">sujeto_isp</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_sp_ex" model="account.tax.template">
|
||||
<field name="name">IVA 10% Adquisición de servicios extracomunitarios</field>
|
||||
<field name="l10n_es_type">sujeto_isp</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_sp_ex" model="account.tax.template">
|
||||
<field name="name">IVA 21% Adquisición de servicios extracomunitarios</field>
|
||||
<field name="l10n_es_type">sujeto_isp</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_ic_bc" model="account.tax.template">
|
||||
<field name="name">IVA 4% Adquisición Intracomunitario. Bienes corrientes</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_ic_bi" model="account.tax.template">
|
||||
<field name="name">IVA 4% Adquisición Intracomunitario. Bienes de inversión</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_ic_bc" model="account.tax.template">
|
||||
<field name="name">IVA 10% Adquisición Intracomunitario. Bienes corrientes</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_ic_bi" model="account.tax.template">
|
||||
<field name="name">IVA 10% Adquisición Intracomunitario. Bienes de inversión</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva0_sp_i" model="account.tax.template">
|
||||
<field name="name">IVA 0% Prestación de servicios intracomunitario</field>
|
||||
<field name="l10n_es_type">no_sujeto_loc</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva_ns" model="account.tax.template">
|
||||
<field name="name">No sujeto Repercutido (Servicios)</field>
|
||||
<field name="l10n_es_type">no_sujeto</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva_ns_b" model="account.tax.template">
|
||||
<field name="name">No sujeto Repercutido (Bienes)</field>
|
||||
<field name="l10n_es_type">no_sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva_e" model="account.tax.template">
|
||||
<field name="name">IVA 0% Prestación de servicios extracomunitaria</field>
|
||||
<field name="l10n_es_type">no_sujeto_loc</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_ibc" model="account.tax.template">
|
||||
<field name="name">IVA 4% Importaciones bienes corrientes</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_ibi" model="account.tax.template">
|
||||
<field name="name">IVA 4% Importaciones bienes de inversión</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_ibc" model="account.tax.template">
|
||||
<field name="name">IVA 10% Importaciones bienes corrientes</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_ibi" model="account.tax.template">
|
||||
<field name="name">IVA 10% Importaciones bienes de inversión</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_bi" model="account.tax.template">
|
||||
<field name="name">4% IVA Soportado (bienes de inversión)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
<field name="l10n_es_bien_inversion">True</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_sc" model="account.tax.template">
|
||||
<field name="name">4% IVA soportado (servicios corrientes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_bi" model="account.tax.template">
|
||||
<field name="name">10% IVA Soportado (bienes de inversión)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
<field name="l10n_es_bien_inversion">True</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_bi" model="account.tax.template">
|
||||
<field name="name">21% IVA Soportado (bienes de inversión)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
<field name="l10n_es_bien_inversion">True</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_bc" model="account.tax.template">
|
||||
<field name="name">10% IVA soportado (bienes corrientes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_bc" model="account.tax.template">
|
||||
<field name="name">4% IVA soportado (bienes corrientes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_sc" model="account.tax.template">
|
||||
<field name="name">10% IVA soportado (servicios corrientes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva0" model="account.tax.template">
|
||||
<field name="name">IVA Exento Repercutido Sujeto</field>
|
||||
<field name="l10n_es_type">exento</field>
|
||||
<field name="l10n_es_exempt_reason">E1</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva0_ns" model="account.tax.template">
|
||||
<field name="name">IVA Exento Repercutido No Sujeto</field>
|
||||
<field name="l10n_es_type">ignore</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_req0" model="account.tax.template">
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_req0" model="account.tax.template">
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_req05" model="account.tax.template">
|
||||
<field name="name">0.50% Recargo Equivalencia Ventas</field>
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_req062" model="account.tax.template">
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_req062" model="account.tax.template">
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva4b" model="account.tax.template">
|
||||
<field name="name">IVA 4% (Bienes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva10b" model="account.tax.template">
|
||||
<field name="name">IVA 10% (Bienes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva0_nd" model="account.tax.template">
|
||||
<field name="name">21% IVA Soportado no deducible</field>
|
||||
<field name="l10n_es_type">no_deducible</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_nd" model="account.tax.template">
|
||||
<field name="name">10% IVA Soportado no deducible</field>
|
||||
<field name="l10n_es_type">no_deducible</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva5_nd" model="account.tax.template">
|
||||
<field name="name">5% IVA Soportado no deducible</field>
|
||||
<field name="l10n_es_type">no_deducible</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_nd" model="account.tax.template">
|
||||
<field name="name">4% IVA Soportado no deducible</field>
|
||||
<field name="l10n_es_type">no_deducible</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva4s" model="account.tax.template">
|
||||
<field name="name">IVA 4% (Servicios)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva10s" model="account.tax.template">
|
||||
<field name="name">IVA 10% (Servicios)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_req014" model="account.tax.template">
|
||||
<field name="name">1.4% Recargo Equivalencia Ventas</field>
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_req52" model="account.tax.template">
|
||||
<field name="name">5.2% Recargo Equivalencia Ventas</field>
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva0_bc" model="account.tax.template">
|
||||
<field name="name">IVA Soportado exento (operaciones corrientes)</field>
|
||||
<field name="l10n_es_type">sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva0_ns" model="account.tax.template">
|
||||
<field name="name">IVA Soportado no sujeto (Servicios)</field>
|
||||
<field name="l10n_es_type">no_sujeto</field>
|
||||
<field name="tax_scope">service</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva0_ns_b" model="account.tax.template">
|
||||
<field name="name">IVA Soportado no sujeto (Bienes)</field>
|
||||
<field name="l10n_es_type">no_sujeto</field>
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf9" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 9%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf18" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 18%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf19" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 19%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf19a" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta 19% (Arrendamientos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf195a" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta 19,5% (Arrendamientos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf19" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 19%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf20a" model="account.tax.template">
|
||||
<field name="name">Retenciones 20% (Arrendamientos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf18" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 18%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf19a" model="account.tax.template">
|
||||
<field name="name">Retenciones 19% (Arrendamientos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf195a" model="account.tax.template">
|
||||
<field name="name">Retenciones 19,5% (Arrendamientos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf7" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 7%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf9" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 9%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf24" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 24%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf20" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 20%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf20a" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta 20% (Arrendamientos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf24" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 24%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva12_agr" model="account.tax.template">
|
||||
<field name="name">12% IVA Soportado régimen agricultura</field>
|
||||
<field name="l10n_es_type">sujeto_agricultura</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva105_gan" model="account.tax.template">
|
||||
<field name="name">10,5% IVA Soportado régimen ganadero o pesca</field>
|
||||
<field name="l10n_es_type">sujeto_agricultura</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva0_e" model="account.tax.template">
|
||||
<field name="name">IVA 0% Exportaciones</field>
|
||||
<field name="l10n_es_type">exento</field>
|
||||
<field name="l10n_es_exempt_reason">E2</field> <!--E2 for exportation-->
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva0_ic" model="account.tax.template">
|
||||
<field name="name">IVA 0% Entregas Intracomunitarias exentas</field>
|
||||
<field name="l10n_es_type">exento</field>
|
||||
<field name="l10n_es_exempt_reason">E5</field> <!--E5 for intra-community-->
|
||||
<field name="tax_scope">consu</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_req014" model="account.tax.template">
|
||||
<field name="name">1.4% Recargo Equivalencia Compras</field>
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_req05" model="account.tax.template">
|
||||
<field name="name">0.50% Recargo Equivalencia Compras</field>
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_req52" model="account.tax.template">
|
||||
<field name="name">5.2% Recargo Equivalencia Compras</field>
|
||||
<field name="l10n_es_type">recargo</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf1" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 1%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf2" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 2%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf21" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 21%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf21a" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta 21% (Arrendamientos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf7" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 7%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpf15" model="account.tax.template">
|
||||
<field name="name">Retenciones a cuenta IRPF 15%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf1" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 1%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf15" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 15%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf21t" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF (Trabajadores)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_sp_in" model="account.tax.template">
|
||||
<field name="name">IVA 10% Adquisición de servicios intracomunitarios</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_sp_in" model="account.tax.template">
|
||||
<field name="name">IVA 4% Adquisición de servicios intracomunitarios</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf21te" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF (Trabajadores) en especie</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf20" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 20%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf21a" model="account.tax.template">
|
||||
<field name="name">Retenciones 21% (Arrendamientos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf21p" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 21%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpf2" model="account.tax.template">
|
||||
<field name="name">Retenciones IRPF 2%</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_iva0_isp" model="account.tax.template">
|
||||
<field name="name">IVA 0% Venta con Inversión del Sujeto Pasivo</field>
|
||||
<field name="l10n_es_type">sujeto_isp</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva4_isp" model="account.tax.template">
|
||||
<field name="name">IVA 4% Compra con Inversión del Sujeto Pasivo Nacional</field>
|
||||
<field name="l10n_es_type">sujeto_isp</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva10_isp" model="account.tax.template">
|
||||
<field name="name">IVA 10% Compra con Inversión del Sujeto Pasivo Nacional</field>
|
||||
<field name="l10n_es_type">sujeto_isp</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_iva21_isp" model="account.tax.template">
|
||||
<field name="name">IVA 21% Compra con Inversión del Sujeto Pasivo Nacional</field>
|
||||
<field name="l10n_es_type">sujeto_isp</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_rp19" model="account.tax.template">
|
||||
<field name="name">Retenciones 19% (préstamos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_rrD19" model="account.tax.template">
|
||||
<field name="name">Retenciones 19% (reparto de dividendos)</field>
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpfnrnue24" model="account.tax.template">
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpfnrnue24p" model="account.tax.template">
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_s_irpfnrue19" model="account.tax.template">
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
<record id="l10n_es.account_tax_template_p_irpfnrue19p" model="account.tax.template">
|
||||
<field name="l10n_es_type">retencion</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
-- disable_l10n_es_edi_integration
|
||||
UPDATE res_company
|
||||
SET l10n_es_edi_test_env = true;
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<record id="partner_simplified" model="res.partner">
|
||||
<field name="name">Simplified Invoice Partner (ES)</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Binary file not shown.
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="demo_certificate" model="l10n_es_edi.certificate">
|
||||
<field name="content" type="base64" file="l10n_es_edi_sii/demo/certificates/aeat_1234.p12"/>
|
||||
<field name="password">1234</field>
|
||||
<field name="company_id" ref="l10n_es.demo_company_es"/>
|
||||
</record>
|
||||
</odoo>
|
||||
560
odoo-bringout-oca-ocb-l10n_es_edi_sii/l10n_es_edi_sii/i18n/es.po
Normal file
560
odoo-bringout-oca-ocb-l10n_es_edi_sii/l10n_es_edi_sii/i18n/es.po
Normal file
|
|
@ -0,0 +1,560 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * l10n_es_edi_sii
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-02-13 13:24+0000\n"
|
||||
"PO-Revision-Date: 2025-02-13 13:24+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid ""
|
||||
"<span class=\"o_form_label\">Registro de Libros connection SII</span>\n"
|
||||
" <span class=\"fa fa-lg fa-building-o\" title=\"Values set here are company-specific.\" groups=\"base.group_multi_company\"/>"
|
||||
msgstr ""
|
||||
"<span class=\"o_form_label\">Connexión con el Registro de Libros mediante SII</span>\n"
|
||||
" <span class=\"fa fa-lg fa-building-o\" title=\"Los valores establecidos aquí son específicos de la compañía.\" groups=\"base.group_multi_company\"/>"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__res_company__l10n_es_edi_tax_agency__aeat
|
||||
msgid "Agencia Tributaria española"
|
||||
msgstr "Agencia Tributaria española"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e1
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e1
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e1
|
||||
msgid "Art. 20"
|
||||
msgstr "Art. 20"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e2
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e2
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e2
|
||||
msgid "Art. 21"
|
||||
msgstr "Art. 21"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e3
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e3
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e3
|
||||
msgid "Art. 22"
|
||||
msgstr "Art. 22"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e4
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e4
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e4
|
||||
msgid "Art. 23 y 24"
|
||||
msgstr "Art. 23 y 24"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e5
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e5
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e5
|
||||
msgid "Art. 25"
|
||||
msgstr "Art. 25"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax__l10n_es_bien_inversion
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax_template__l10n_es_bien_inversion
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_sii_account_tax_mixin__l10n_es_bien_inversion
|
||||
msgid "Bien de Inversion"
|
||||
msgstr "Bien de inversión"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_bank_statement_line__l10n_es_edi_csv
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_move__l10n_es_edi_csv
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_payment__l10n_es_edi_csv
|
||||
msgid "CSV return code"
|
||||
msgstr "Código de devolución CSV"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_company__l10n_es_edi_certificate_id
|
||||
msgid "Certificate (ES)"
|
||||
msgstr "Certificado (ES)"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.ui.menu,name:l10n_es_edi_sii.menu_l10n_es_edi_certificates
|
||||
msgid "Certificates (ES)"
|
||||
msgstr "Certificados (ES)"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.actions.act_window,name:l10n_es_edi_sii.l10n_es_edi_certificate_action
|
||||
msgid "Certificates for EDI invoices on Spain"
|
||||
msgstr "Certificados para las facturas EDI en España"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr "Compañías"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__company_id
|
||||
msgid "Company"
|
||||
msgstr "Compañía"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_res_config_settings
|
||||
msgid "Config Settings"
|
||||
msgstr "Ajustes de configuración"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.actions.act_window,help:l10n_es_edi_sii.l10n_es_edi_certificate_action
|
||||
msgid "Create the first certificate"
|
||||
msgstr "Crear el primer certificado"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creado por"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creado el"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__date_end
|
||||
msgid "Date End"
|
||||
msgstr "Fecha de finalización"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__date_start
|
||||
msgid "Date Start"
|
||||
msgstr "Fecha de inicio"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nombre mostrado"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_edi_format
|
||||
msgid "EDI format"
|
||||
msgstr "Formato EDI"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_mail_template
|
||||
msgid "Email Templates"
|
||||
msgstr "Plantillas de correo electrónico"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax__l10n_es_exempt_reason
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax_template__l10n_es_exempt_reason
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason
|
||||
msgid "Exempt Reason (Spain)"
|
||||
msgstr "Motivo de exención (España)"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__exento
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__exento
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__exento
|
||||
msgid "Exento"
|
||||
msgstr "Exento"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__content
|
||||
msgid "File"
|
||||
msgstr "Archivo"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__res_company__l10n_es_edi_tax_agency__bizkaia
|
||||
msgid "Hacienda Foral de Bizkaia"
|
||||
msgstr "Hacienda Foral de Bizkaia"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__res_company__l10n_es_edi_tax_agency__gipuzkoa
|
||||
msgid "Hacienda Foral de Gipuzkoa"
|
||||
msgstr "Hacienda Foral de Gipuzkoa"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__ignore
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__ignore
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__ignore
|
||||
msgid "Ignore even the base amount"
|
||||
msgstr "Ignorar incluso el importe base"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_bank_statement_line__l10n_es_edi_is_required
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_move__l10n_es_edi_is_required
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_payment__l10n_es_edi_is_required
|
||||
msgid "Is the Spanish EDI needed"
|
||||
msgstr "¿Se necesita el EDI español?"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_move
|
||||
msgid "Journal Entry"
|
||||
msgstr "Asiento contable"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_company__l10n_es_edi_certificate_ids
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_config_settings__l10n_es_edi_certificate_ids
|
||||
msgid "L10N Es Edi Certificate"
|
||||
msgstr "L10N Es Certificado EDI"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última modificación el"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última actualización por"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última actualización el"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one main tax."
|
||||
msgstr "La línea %s solo debe tener un impuesto principal."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one no sujeto (localizations) tax."
|
||||
msgstr "La línea %s solo debe tener un impuesto no sujeto (localizaciones)."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one no sujeto tax."
|
||||
msgstr "La línea %s solo debe tener un impuesto no sujeto."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one recargo tax."
|
||||
msgstr "La línea %s solo debe tener un impuesto de recargo."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one retention tax."
|
||||
msgstr "La línea %s solo debe tener un impuesto de retención."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one sujeto tax."
|
||||
msgstr "La línea %s solo debe tener un impuesto sujeto."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid "Manage certificates (SII/TicketBAI)"
|
||||
msgstr "Gestionar certificados (SII/TicketBAI)"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Networking error:\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
"Error de red:\n"
|
||||
"%s"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__no_deducible
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__no_deducible
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__no_deducible
|
||||
msgid "No Deducible"
|
||||
msgstr "No deducible"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__no_sujeto
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__no_sujeto
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__no_sujeto
|
||||
msgid "No Sujeto"
|
||||
msgstr "No sujeto"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__no_sujeto_loc
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__no_sujeto_loc
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__no_sujeto_loc
|
||||
msgid "No Sujeto por reglas de Localization"
|
||||
msgstr "No sujeto por reglas de localización"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid "No tax agency selected: SII not activated."
|
||||
msgstr "No se ha seleccionado ninguna agencia tributaria: SII no activado."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e6
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e6
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e6
|
||||
msgid "Otros"
|
||||
msgstr "Otros"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_l10n_es_edi_certificate__content
|
||||
msgid "PFX Certificate"
|
||||
msgstr "Certificado PFX"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_l10n_es_edi_certificate__password
|
||||
msgid "Passphrase for the PFX certificate"
|
||||
msgstr "Frase de contraseña para el certificado PFX"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__password
|
||||
msgid "Password"
|
||||
msgstr "Contraseña"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_l10n_es_edi_certificate
|
||||
msgid "Personal Digital Certificate"
|
||||
msgstr "Certificado personal de persona física"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Please configure the certificate for SII."
|
||||
msgstr "Configure el certificado para el SII."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Please specify a tax agency on your company for SII."
|
||||
msgstr "Especifique una agencia tributaria en su compañía para el SII"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid "Production mode: EDI data is sent to the official agency servers."
|
||||
msgstr ""
|
||||
"Modo de producción: los datos EDI se envían a los servidores de la agencia "
|
||||
"oficial."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__recargo
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__recargo
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__recargo
|
||||
msgid "Recargo de Equivalencia"
|
||||
msgstr "Recargo de equivalencia"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_bank_statement_line__l10n_es_registration_date
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_move__l10n_es_registration_date
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_payment__l10n_es_registration_date
|
||||
msgid "Registration Date"
|
||||
msgstr "Fecha de registro"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_resequence_wizard
|
||||
msgid "Remake the sequence of Journal Entries."
|
||||
msgstr "Remake the sequence of Journal Entries."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__retencion
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__retencion
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__retencion
|
||||
msgid "Retencion"
|
||||
msgstr "Retención"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_l10n_es_sii_account_tax_mixin
|
||||
msgid "SII Fields"
|
||||
msgstr "Campos SII"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.ui.menu,name:l10n_es_edi_sii.menu_l10n_es_edi_root
|
||||
msgid "Spain"
|
||||
msgstr "España"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid "Spain Localization"
|
||||
msgstr "Localización de España"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__sujeto
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__sujeto
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__sujeto
|
||||
msgid "Sujeto"
|
||||
msgstr "Sujeto"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__sujeto_agricultura
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__sujeto_agricultura
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__sujeto_agricultura
|
||||
msgid "Sujeto Agricultura"
|
||||
msgstr "Sujeto Agricultura"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__sujeto_isp
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__sujeto_isp
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__sujeto_isp
|
||||
msgid "Sujeto ISP"
|
||||
msgstr "Sujeto ISP"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_tax
|
||||
msgid "Tax"
|
||||
msgstr "Impuesto"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_company__l10n_es_edi_tax_agency
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_config_settings__l10n_es_edi_tax_agency
|
||||
msgid "Tax Agency for SII"
|
||||
msgstr "Agencia Tributaria para SII"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax__l10n_es_type
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax_template__l10n_es_type
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_sii_account_tax_mixin__l10n_es_type
|
||||
msgid "Tax Type (Spain)"
|
||||
msgstr "Tipo de impuesto (España)"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid ""
|
||||
"Tax agency selected: invoices will be sent by SII for journals where it is "
|
||||
"activated."
|
||||
msgstr ""
|
||||
"Agencia tributaria seleccionada: las facturas serán enviadas por el SII para"
|
||||
" los diarios en los que esté activado."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_tax_template
|
||||
msgid "Templates for Taxes"
|
||||
msgstr "Plantillas para impuestos"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_company__l10n_es_edi_test_env
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_config_settings__l10n_es_edi_test_env
|
||||
msgid "Test Mode"
|
||||
msgstr "Modo de prueba"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid ""
|
||||
"Test mode: EDI data is sent to separate test servers and is not considered "
|
||||
"official."
|
||||
msgstr ""
|
||||
"Modo de prueba: los datos EDI se envían a servidores de prueba "
|
||||
"independientes y no se consideran oficiales."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "The SSL certificate could not be validated."
|
||||
msgstr "No se ha podido validar el certificado SSL"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/l10n_es_edi_certificate.py:0
|
||||
#, python-format
|
||||
msgid "The certificate is expired since %s"
|
||||
msgstr "El certificado ha caducado desde %s"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_l10n_es_edi_certificate__date_end
|
||||
msgid "The date on which the certificate expires"
|
||||
msgstr "La fecha en la que el certificado caduca."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_l10n_es_edi_certificate__date_start
|
||||
msgid "The date on which the certificate starts to be valid"
|
||||
msgstr "La fecha en la que el certificado comienza a ser válido"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "The web service is not responding"
|
||||
msgstr "El servicio web no responde"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/l10n_es_edi_certificate.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"There has been a problem with the certificate, some usual problems can be:\n"
|
||||
"- The password given or the certificate are not valid.\n"
|
||||
"- The certificate content is invalid."
|
||||
msgstr ""
|
||||
"Había un problema con el certificado, algunos problemas habituales pueden ser:\n"
|
||||
"La contraseña proporcionada o el certificado no son válidos.\n"
|
||||
"El contenido del certificado no es válido"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "This was accepted with errors: "
|
||||
msgstr "Esto se ha aceptado con errores:"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_res_company__l10n_es_edi_test_env
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_res_config_settings__l10n_es_edi_test_env
|
||||
msgid "Use the test environment"
|
||||
msgstr "Utilizar el entorno de prueba"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "VAT number is missing on company %s"
|
||||
msgstr "Falta el NIF de la compañía %s"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.l10n_es_edi_certificate_form
|
||||
msgid "Validity"
|
||||
msgstr "Validez"
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"We saw that this invoice was sent correctly before, but we did not treat the"
|
||||
" response. Make sure it is not because of a wrong configuration."
|
||||
msgstr ""
|
||||
"Esta factura se ha enviada correctamente antes, pero no procesamos la "
|
||||
"respuesta. Asegúrese de que no se deba a una configuración incorrecta."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "You should put a vendor reference on this vendor bill. "
|
||||
msgstr ""
|
||||
"Debe poner una referencia del proveedor en esta factura del proveedor."
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "[%s] %s"
|
||||
msgstr "[%s] %s"
|
||||
|
|
@ -0,0 +1,543 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * l10n_es_edi_sii
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-05-20 09:26+0000\n"
|
||||
"PO-Revision-Date: 2025-05-20 09:26+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_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid ""
|
||||
"<span class=\"o_form_label\">Registro de Libros connection SII</span>\n"
|
||||
" <span class=\"fa fa-lg fa-building-o\" title=\"Values set here are company-specific.\" groups=\"base.group_multi_company\"/>"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__res_company__l10n_es_edi_tax_agency__aeat
|
||||
msgid "Agencia Tributaria española"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e1
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e1
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e1
|
||||
msgid "Art. 20"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e2
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e2
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e2
|
||||
msgid "Art. 21"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e3
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e3
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e3
|
||||
msgid "Art. 22"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e4
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e4
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e4
|
||||
msgid "Art. 23 y 24"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e5
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e5
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e5
|
||||
msgid "Art. 25"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax__l10n_es_bien_inversion
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax_template__l10n_es_bien_inversion
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_sii_account_tax_mixin__l10n_es_bien_inversion
|
||||
msgid "Bien de Inversion"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_bank_statement_line__l10n_es_edi_csv
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_move__l10n_es_edi_csv
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_payment__l10n_es_edi_csv
|
||||
msgid "CSV return code"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_company__l10n_es_edi_certificate_id
|
||||
msgid "Certificate (ES)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.ui.menu,name:l10n_es_edi_sii.menu_l10n_es_edi_certificates
|
||||
msgid "Certificates (ES)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.actions.act_window,name:l10n_es_edi_sii.l10n_es_edi_certificate_action
|
||||
msgid "Certificates for EDI invoices on Spain"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_res_company
|
||||
msgid "Companies"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__company_id
|
||||
msgid "Company"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_res_config_settings
|
||||
msgid "Config Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.actions.act_window,help:l10n_es_edi_sii.l10n_es_edi_certificate_action
|
||||
msgid "Create the first certificate"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__date_end
|
||||
msgid "Date End"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__date_start
|
||||
msgid "Date Start"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_edi_format
|
||||
msgid "EDI format"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_mail_template
|
||||
msgid "Email Templates"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax__l10n_es_exempt_reason
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax_template__l10n_es_exempt_reason
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason
|
||||
msgid "Exempt Reason (Spain)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__exento
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__exento
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__exento
|
||||
msgid "Exento"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__content
|
||||
msgid "File"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__res_company__l10n_es_edi_tax_agency__bizkaia
|
||||
msgid "Hacienda Foral de Bizkaia"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__res_company__l10n_es_edi_tax_agency__gipuzkoa
|
||||
msgid "Hacienda Foral de Gipuzkoa"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__ignore
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__ignore
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__ignore
|
||||
msgid "Ignore even the base amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_bank_statement_line__l10n_es_edi_is_required
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_move__l10n_es_edi_is_required
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_payment__l10n_es_edi_is_required
|
||||
msgid "Is the Spanish EDI needed"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_move
|
||||
msgid "Journal Entry"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_company__l10n_es_edi_certificate_ids
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_config_settings__l10n_es_edi_certificate_ids
|
||||
msgid "L10N Es Edi Certificate"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one main tax."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one no sujeto (localizations) tax."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one no sujeto tax."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one recargo tax."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one retention tax."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Line %s should only have one sujeto tax."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid "Manage certificates (SII/TicketBAI)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Networking error:\n"
|
||||
"%s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__no_deducible
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__no_deducible
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__no_deducible
|
||||
msgid "No Deducible"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__no_sujeto
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__no_sujeto
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__no_sujeto
|
||||
msgid "No Sujeto"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__no_sujeto_loc
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__no_sujeto_loc
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__no_sujeto_loc
|
||||
msgid "No Sujeto por reglas de Localization"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid "No tax agency selected: SII not activated."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_exempt_reason__e6
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_exempt_reason__e6
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_exempt_reason__e6
|
||||
msgid "Otros"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_l10n_es_edi_certificate__content
|
||||
msgid "PFX Certificate"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_l10n_es_edi_certificate__password
|
||||
msgid "Passphrase for the PFX certificate"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_edi_certificate__password
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_l10n_es_edi_certificate
|
||||
msgid "Personal Digital Certificate"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Please configure the certificate for SII."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "Please specify a tax agency on your company for SII."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid "Production mode: EDI data is sent to the official agency servers."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__recargo
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__recargo
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__recargo
|
||||
msgid "Recargo de Equivalencia"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_bank_statement_line__l10n_es_registration_date
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_move__l10n_es_registration_date
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_payment__l10n_es_registration_date
|
||||
msgid "Registration Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_resequence_wizard
|
||||
msgid "Remake the sequence of Journal Entries."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__retencion
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__retencion
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__retencion
|
||||
msgid "Retencion"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_l10n_es_sii_account_tax_mixin
|
||||
msgid "SII Fields"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.ui.menu,name:l10n_es_edi_sii.menu_l10n_es_edi_root
|
||||
msgid "Spain"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid "Spain Localization"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__sujeto
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__sujeto
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__sujeto
|
||||
msgid "Sujeto"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__sujeto_agricultura
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__sujeto_agricultura
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__sujeto_agricultura
|
||||
msgid "Sujeto Agricultura"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax__l10n_es_type__sujeto_isp
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__account_tax_template__l10n_es_type__sujeto_isp
|
||||
#: model:ir.model.fields.selection,name:l10n_es_edi_sii.selection__l10n_es_sii_account_tax_mixin__l10n_es_type__sujeto_isp
|
||||
msgid "Sujeto ISP"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_tax
|
||||
msgid "Tax"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_company__l10n_es_edi_tax_agency
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_config_settings__l10n_es_edi_tax_agency
|
||||
msgid "Tax Agency for SII"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax__l10n_es_type
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_account_tax_template__l10n_es_type
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_l10n_es_sii_account_tax_mixin__l10n_es_type
|
||||
msgid "Tax Type (Spain)"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid ""
|
||||
"Tax agency selected: invoices will be sent by SII for journals where it is "
|
||||
"activated."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model,name:l10n_es_edi_sii.model_account_tax_template
|
||||
msgid "Templates for Taxes"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_company__l10n_es_edi_test_env
|
||||
#: model:ir.model.fields,field_description:l10n_es_edi_sii.field_res_config_settings__l10n_es_edi_test_env
|
||||
msgid "Test Mode"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.res_config_settings_view_form
|
||||
msgid ""
|
||||
"Test mode: EDI data is sent to separate test servers and is not considered "
|
||||
"official."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "The SSL certificate could not be validated."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/l10n_es_edi_certificate.py:0
|
||||
#, python-format
|
||||
msgid "The certificate is expired since %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_l10n_es_edi_certificate__date_end
|
||||
msgid "The date on which the certificate expires"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_l10n_es_edi_certificate__date_start
|
||||
msgid "The date on which the certificate starts to be valid"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "The web service is not responding"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/l10n_es_edi_certificate.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"There has been a problem with the certificate, some usual problems can be:\n"
|
||||
"- The password given or the certificate are not valid.\n"
|
||||
"- The certificate content is invalid."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "This was accepted with errors: "
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_res_company__l10n_es_edi_test_env
|
||||
#: model:ir.model.fields,help:l10n_es_edi_sii.field_res_config_settings__l10n_es_edi_test_env
|
||||
msgid "Use the test environment"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "VAT number is missing on company %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#: model_terms:ir.ui.view,arch_db:l10n_es_edi_sii.l10n_es_edi_certificate_form
|
||||
msgid "Validity"
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"We saw that this invoice was sent correctly before, but we did not treat the"
|
||||
" response. Make sure it is not because of a wrong configuration."
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "You should put a vendor reference on this vendor bill. "
|
||||
msgstr ""
|
||||
|
||||
#. module: l10n_es_edi_sii
|
||||
#. odoo-python
|
||||
#: code:addons/l10n_es_edi_sii/models/account_edi_format.py:0
|
||||
#, python-format
|
||||
msgid "[%s] %s"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import account_edi_format
|
||||
from . import account_move
|
||||
from . import account_tax
|
||||
from . import l10n_es_edi_certificate
|
||||
from . import mail_template
|
||||
from . import res_company
|
||||
from . import res_config_settings
|
||||
|
|
@ -0,0 +1,738 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from collections import defaultdict
|
||||
from urllib3.util.ssl_ import create_urllib3_context, DEFAULT_CIPHERS
|
||||
from urllib3.contrib.pyopenssl import inject_into_urllib3
|
||||
from OpenSSL.crypto import load_certificate, load_privatekey, FILETYPE_PEM
|
||||
|
||||
from odoo import fields, models, _
|
||||
from odoo.tools import html_escape, zeep
|
||||
|
||||
import math
|
||||
import json
|
||||
import requests
|
||||
|
||||
|
||||
# Custom patches to perform the WSDL requests.
|
||||
EUSKADI_CIPHERS = f"{DEFAULT_CIPHERS}:!DH"
|
||||
|
||||
|
||||
class PatchedHTTPAdapter(requests.adapters.HTTPAdapter):
|
||||
""" An adapter to block DH ciphers which may not work for the tax agencies called"""
|
||||
|
||||
def init_poolmanager(self, *args, **kwargs):
|
||||
# OVERRIDE
|
||||
inject_into_urllib3()
|
||||
kwargs['ssl_context'] = create_urllib3_context(ciphers=EUSKADI_CIPHERS)
|
||||
return super().init_poolmanager(*args, **kwargs)
|
||||
|
||||
def cert_verify(self, conn, url, verify, cert):
|
||||
# OVERRIDE
|
||||
# The last parameter is only used by the super method to check if the file exists.
|
||||
# In our case, cert is an odoo record 'l10n_es_edi.certificate' so not a path to a file.
|
||||
# By putting 'None' as last parameter, we ensure the check about TLS configuration is
|
||||
# still made without checking temporary files exist.
|
||||
super().cert_verify(conn, url, verify, None)
|
||||
conn.cert_file = cert
|
||||
conn.key_file = None
|
||||
|
||||
def get_connection(self, url, proxies=None):
|
||||
# OVERRIDE
|
||||
# Patch the OpenSSLContext to decode the certificate in-memory.
|
||||
conn = super().get_connection(url, proxies=proxies)
|
||||
context = conn.conn_kw['ssl_context']
|
||||
|
||||
def patched_load_cert_chain(l10n_es_odoo_certificate, keyfile=None, password=None):
|
||||
cert_file, key_file, _certificate = l10n_es_odoo_certificate.sudo()._decode_certificate()
|
||||
cert_obj = load_certificate(FILETYPE_PEM, cert_file)
|
||||
pkey_obj = load_privatekey(FILETYPE_PEM, key_file)
|
||||
|
||||
context._ctx.use_certificate(cert_obj)
|
||||
context._ctx.use_privatekey(pkey_obj)
|
||||
|
||||
context.load_cert_chain = patched_load_cert_chain
|
||||
|
||||
return conn
|
||||
|
||||
|
||||
class AccountEdiFormat(models.Model):
|
||||
_inherit = 'account.edi.format'
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# ES EDI
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def _l10n_es_edi_get_invoices_tax_details_info(self, invoice, filter_invl_to_apply=None):
|
||||
|
||||
def grouping_key_generator(base_line, tax_values):
|
||||
tax = tax_values['tax_repartition_line'].tax_id
|
||||
return {
|
||||
'applied_tax_amount': tax.amount,
|
||||
'l10n_es_type': tax.l10n_es_type,
|
||||
'l10n_es_exempt_reason': tax.l10n_es_exempt_reason if tax.l10n_es_type == 'exento' else False,
|
||||
'l10n_es_bien_inversion': tax.l10n_es_bien_inversion,
|
||||
}
|
||||
|
||||
def filter_to_apply(base_line, tax_values):
|
||||
# For intra-community, we do not take into account the negative repartition line
|
||||
return tax_values['tax_repartition_line'].factor_percent > 0.0
|
||||
|
||||
def full_filter_invl_to_apply(invoice_line):
|
||||
if 'ignore' in invoice_line.tax_ids.flatten_taxes_hierarchy().mapped('l10n_es_type'):
|
||||
return False
|
||||
return filter_invl_to_apply(invoice_line) if filter_invl_to_apply else True
|
||||
|
||||
tax_details = invoice._prepare_edi_tax_details(
|
||||
grouping_key_generator=grouping_key_generator,
|
||||
filter_invl_to_apply=full_filter_invl_to_apply,
|
||||
filter_to_apply=filter_to_apply,
|
||||
)
|
||||
sign = -1 if invoice.move_type in ('out_refund', 'in_refund') else 1
|
||||
|
||||
tax_details_info = defaultdict(dict)
|
||||
|
||||
# Detect for which is the main tax for 'recargo'. Since only a single combination tax + recargo is allowed
|
||||
# on the same invoice, this can be deduced globally.
|
||||
|
||||
recargo_tax_details = {} # Mapping between main tax and recargo tax details
|
||||
invoice_lines = invoice.invoice_line_ids.filtered(lambda x: x.display_type not in ('line_note', 'line_section'))
|
||||
if filter_invl_to_apply:
|
||||
invoice_lines = invoice_lines.filtered(filter_invl_to_apply)
|
||||
for line in invoice_lines:
|
||||
taxes = line.tax_ids.flatten_taxes_hierarchy()
|
||||
recargo_tax = [t for t in taxes if t.l10n_es_type == 'recargo']
|
||||
if recargo_tax and taxes:
|
||||
recargo_main_tax = taxes.filtered(lambda x: x.l10n_es_type in ('sujeto', 'sujeto_isp'))[:1]
|
||||
if not recargo_tax_details.get(recargo_main_tax):
|
||||
recargo_tax_details[recargo_main_tax] = [
|
||||
x for x in tax_details['tax_details'].values()
|
||||
if x['group_tax_details'][0]['tax_repartition_line'].tax_id == recargo_tax[0]
|
||||
][0]
|
||||
|
||||
tax_amount_deductible = 0.0
|
||||
tax_amount_retention = 0.0
|
||||
base_amount_not_subject = 0.0
|
||||
base_amount_not_subject_loc = 0.0
|
||||
has_not_subject = False
|
||||
has_not_subject_loc = False
|
||||
tax_subject_info_list = []
|
||||
tax_subject_isp_info_list = []
|
||||
for tax_values in tax_details['tax_details'].values():
|
||||
|
||||
if invoice.is_sale_document():
|
||||
# Customer invoices
|
||||
|
||||
if tax_values['l10n_es_type'] in ('sujeto', 'sujeto_isp'):
|
||||
tax_amount_deductible += tax_values['tax_amount']
|
||||
|
||||
base_amount = sign * tax_values['base_amount']
|
||||
tax_info = {
|
||||
'TipoImpositivo': tax_values['applied_tax_amount'],
|
||||
'BaseImponible': round(base_amount, 2),
|
||||
'CuotaRepercutida': round(math.copysign(tax_values['tax_amount'], base_amount), 2),
|
||||
}
|
||||
|
||||
recargo = recargo_tax_details.get(tax_values['group_tax_details'][0]['tax_repartition_line'].tax_id)
|
||||
if recargo:
|
||||
tax_info['CuotaRecargoEquivalencia'] = round(sign * recargo['tax_amount'], 2)
|
||||
tax_info['TipoRecargoEquivalencia'] = recargo['applied_tax_amount']
|
||||
|
||||
if tax_values['l10n_es_type'] == 'sujeto':
|
||||
tax_subject_info_list.append(tax_info)
|
||||
else:
|
||||
tax_subject_isp_info_list.append(tax_info)
|
||||
|
||||
elif tax_values['l10n_es_type'] == 'exento':
|
||||
tax_details_info['Sujeta'].setdefault('Exenta', {'DetalleExenta': []})
|
||||
tax_details_info['Sujeta']['Exenta']['DetalleExenta'].append({
|
||||
'BaseImponible': round(sign * tax_values['base_amount'], 2),
|
||||
'CausaExencion': tax_values['l10n_es_exempt_reason'],
|
||||
})
|
||||
elif tax_values['l10n_es_type'] == 'retencion':
|
||||
tax_amount_retention += tax_values['tax_amount']
|
||||
elif tax_values['l10n_es_type'] == 'no_sujeto':
|
||||
has_not_subject = True
|
||||
base_amount_not_subject += tax_values['base_amount']
|
||||
elif tax_values['l10n_es_type'] == 'no_sujeto_loc':
|
||||
has_not_subject_loc = True
|
||||
base_amount_not_subject_loc += tax_values['base_amount']
|
||||
elif tax_values['l10n_es_type'] == 'ignore':
|
||||
continue
|
||||
|
||||
else:
|
||||
# Vendor bills
|
||||
if tax_values['l10n_es_type'] in ('sujeto', 'sujeto_isp', 'no_sujeto', 'no_sujeto_loc'):
|
||||
tax_amount_deductible += tax_values['tax_amount']
|
||||
elif tax_values['l10n_es_type'] == 'retencion':
|
||||
tax_amount_retention += tax_values['tax_amount']
|
||||
elif tax_values['l10n_es_type'] == 'no_sujeto':
|
||||
has_not_subject = True
|
||||
base_amount_not_subject += tax_values['base_amount']
|
||||
elif tax_values['l10n_es_type'] == 'no_sujeto_loc':
|
||||
has_not_subject_loc = True
|
||||
base_amount_not_subject_loc += tax_values['base_amount']
|
||||
elif tax_values['l10n_es_type'] == 'ignore':
|
||||
continue
|
||||
|
||||
if tax_values['l10n_es_type'] not in ['retencion', 'recargo']: # = in sujeto/sujeto_isp/no_deducible
|
||||
base_amount = sign * tax_values['base_amount']
|
||||
tax_details_info.setdefault('DetalleIVA', [])
|
||||
tax_info = {
|
||||
'BaseImponible': round(base_amount, 2),
|
||||
}
|
||||
if tax_values['l10n_es_type'] == 'sujeto_agricultura':
|
||||
tax_info.update({
|
||||
'PorcentCompensacionREAGYP': tax_values['applied_tax_amount'],
|
||||
'ImporteCompensacionREAGYP': round(math.copysign(tax_values['tax_amount'], base_amount), 2),
|
||||
})
|
||||
elif tax_values['applied_tax_amount'] > 0.0:
|
||||
tax_info.update({
|
||||
'TipoImpositivo': tax_values['applied_tax_amount'],
|
||||
'CuotaSoportada': round(math.copysign(tax_values['tax_amount'], base_amount), 2),
|
||||
})
|
||||
if tax_values['l10n_es_bien_inversion']:
|
||||
tax_info['BienInversion'] = 'S'
|
||||
recargo = recargo_tax_details.get(tax_values['group_tax_details'][0]['tax_repartition_line'].tax_id)
|
||||
if recargo:
|
||||
tax_info['CuotaRecargoEquivalencia'] = round(sign * recargo['tax_amount'], 2)
|
||||
tax_info['TipoRecargoEquivalencia'] = recargo['applied_tax_amount']
|
||||
tax_details_info['DetalleIVA'].append(tax_info)
|
||||
|
||||
if tax_subject_isp_info_list and not tax_subject_info_list: # Only for sale_invoices
|
||||
tax_details_info['Sujeta']['NoExenta'] = {'TipoNoExenta': 'S2'}
|
||||
elif not tax_subject_isp_info_list and tax_subject_info_list:
|
||||
tax_details_info['Sujeta']['NoExenta'] = {'TipoNoExenta': 'S1'}
|
||||
elif tax_subject_isp_info_list and tax_subject_info_list:
|
||||
tax_details_info['Sujeta']['NoExenta'] = {'TipoNoExenta': 'S3'}
|
||||
|
||||
if tax_subject_info_list:
|
||||
tax_details_info['Sujeta']['NoExenta'].setdefault('DesgloseIVA', {})
|
||||
tax_details_info['Sujeta']['NoExenta']['DesgloseIVA'].setdefault('DetalleIVA', [])
|
||||
tax_details_info['Sujeta']['NoExenta']['DesgloseIVA']['DetalleIVA'] += tax_subject_info_list
|
||||
if tax_subject_isp_info_list:
|
||||
tax_details_info['Sujeta']['NoExenta'].setdefault('DesgloseIVA', {})
|
||||
tax_details_info['Sujeta']['NoExenta']['DesgloseIVA'].setdefault('DetalleIVA', [])
|
||||
tax_details_info['Sujeta']['NoExenta']['DesgloseIVA']['DetalleIVA'] += tax_subject_isp_info_list
|
||||
|
||||
if has_not_subject and invoice.is_sale_document():
|
||||
tax_details_info['NoSujeta']['ImportePorArticulos7_14_Otros'] = round(sign * base_amount_not_subject, 2)
|
||||
if has_not_subject_loc and invoice.is_sale_document():
|
||||
tax_details_info['NoSujeta']['ImporteTAIReglasLocalizacion'] = round(sign * base_amount_not_subject_loc, 2)
|
||||
|
||||
return {
|
||||
'tax_details_info': tax_details_info,
|
||||
'tax_details': tax_details,
|
||||
'tax_amount_deductible': tax_amount_deductible,
|
||||
'tax_amount_retention': tax_amount_retention,
|
||||
'base_amount_not_subject': base_amount_not_subject,
|
||||
'S1_list': tax_subject_info_list, #TBAI has separate sections for S1 and S2
|
||||
'S2_list': tax_subject_isp_info_list, #TBAI has separate sections for S1 and S2
|
||||
}
|
||||
|
||||
def _l10n_es_edi_get_partner_info(self, partner):
|
||||
eu_country_codes = set(self.env.ref('base.europe').country_ids.mapped('code'))
|
||||
|
||||
partner_info = {}
|
||||
IDOtro_ID = partner.vat or 'NO_DISPONIBLE'
|
||||
|
||||
if (not partner.country_id or partner.country_id.code == 'ES') and partner.vat:
|
||||
# ES partner with VAT.
|
||||
partner_info['NIF'] = partner.vat[2:] if partner.vat.startswith('ES') else partner.vat
|
||||
if self.env.context.get('error_1117'):
|
||||
partner_info['IDOtro'] = {'IDType': '07', 'ID': IDOtro_ID}
|
||||
|
||||
elif partner.country_id.code in eu_country_codes and partner.vat:
|
||||
# European partner.
|
||||
partner_info['IDOtro'] = {'IDType': '02', 'ID': IDOtro_ID}
|
||||
else:
|
||||
partner_info['IDOtro'] = {'ID': IDOtro_ID}
|
||||
if partner.vat:
|
||||
partner_info['IDOtro']['IDType'] = '04'
|
||||
else:
|
||||
partner_info['IDOtro']['IDType'] = '06'
|
||||
if partner.country_id:
|
||||
partner_info['IDOtro']['CodigoPais'] = partner.country_id.code
|
||||
return partner_info
|
||||
|
||||
def _l10n_es_edi_get_invoices_info(self, invoices):
|
||||
eu_country_codes = set(self.env.ref('base.europe').country_ids.mapped('code'))
|
||||
|
||||
simplified_partner = self.env.ref("l10n_es_edi_sii.partner_simplified")
|
||||
|
||||
info_list = []
|
||||
for invoice in invoices:
|
||||
com_partner = invoice.commercial_partner_id
|
||||
is_simplified = invoice.partner_id == simplified_partner
|
||||
|
||||
info = {
|
||||
'PeriodoLiquidacion': {
|
||||
'Ejercicio': str(invoice.date.year),
|
||||
'Periodo': str(invoice.date.month).zfill(2),
|
||||
},
|
||||
'IDFactura': {
|
||||
'FechaExpedicionFacturaEmisor': invoice.invoice_date.strftime('%d-%m-%Y'),
|
||||
},
|
||||
}
|
||||
|
||||
if invoice.is_sale_document():
|
||||
invoice_node = info['FacturaExpedida'] = {}
|
||||
else:
|
||||
invoice_node = info['FacturaRecibida'] = {}
|
||||
|
||||
# === Partner ===
|
||||
|
||||
partner_info = self._l10n_es_edi_get_partner_info(com_partner)
|
||||
|
||||
# === Invoice ===
|
||||
|
||||
invoice_node['DescripcionOperacion'] = invoice.invoice_origin[:500] if invoice.invoice_origin else 'manual'
|
||||
reagyp = invoice.invoice_line_ids.tax_ids.filtered(lambda t: t.l10n_es_type == 'sujeto_agricultura')
|
||||
if invoice.is_sale_document():
|
||||
nif = invoice.company_id.vat[2:] if invoice.company_id.vat.startswith('ES') else invoice.company_id.vat
|
||||
info['IDFactura']['IDEmisorFactura'] = {'NIF': nif}
|
||||
info['IDFactura']['NumSerieFacturaEmisor'] = invoice.name[:60]
|
||||
if not is_simplified:
|
||||
invoice_node['Contraparte'] = {
|
||||
**partner_info,
|
||||
'NombreRazon': com_partner.name[:120],
|
||||
}
|
||||
export_exempts = invoice.invoice_line_ids.tax_ids.filtered(lambda t: t.l10n_es_exempt_reason == 'E2')
|
||||
# If an invoice line contains an OSS tax, the invoice is considered as an OSS operation
|
||||
is_oss = self._has_oss_taxes(invoice)
|
||||
|
||||
if is_oss:
|
||||
invoice_node['ClaveRegimenEspecialOTrascendencia'] = '17'
|
||||
elif export_exempts:
|
||||
invoice_node['ClaveRegimenEspecialOTrascendencia'] = '02'
|
||||
else:
|
||||
invoice_node['ClaveRegimenEspecialOTrascendencia'] = '01'
|
||||
else:
|
||||
info['IDFactura']['IDEmisorFactura'] = partner_info
|
||||
# In case of cancel
|
||||
info["IDFactura"]["IDEmisorFactura"].update(
|
||||
{"NombreRazon": com_partner.name[0:120]}
|
||||
)
|
||||
info["IDFactura"]["NumSerieFacturaEmisor"] = (invoice.ref or "")[:60]
|
||||
if not is_simplified:
|
||||
invoice_node['Contraparte'] = {
|
||||
**partner_info,
|
||||
'NombreRazon': com_partner.name[:120],
|
||||
}
|
||||
|
||||
if invoice.l10n_es_registration_date:
|
||||
invoice_node['FechaRegContable'] = invoice.l10n_es_registration_date.strftime('%d-%m-%Y')
|
||||
else:
|
||||
invoice_node['FechaRegContable'] = fields.Date.context_today(self).strftime('%d-%m-%Y')
|
||||
|
||||
mod_303_10 = self.env.ref('l10n_es.mod_303_10')
|
||||
mod_303_11 = self.env.ref('l10n_es.mod_303_11')
|
||||
tax_tags = invoice.invoice_line_ids.tax_ids.invoice_repartition_line_ids.tag_ids
|
||||
intracom = bool(tax_tags & (mod_303_10 + mod_303_11))
|
||||
if intracom:
|
||||
invoice_node['ClaveRegimenEspecialOTrascendencia'] = '09'
|
||||
elif reagyp:
|
||||
invoice_node['ClaveRegimenEspecialOTrascendencia'] = '02'
|
||||
else:
|
||||
invoice_node['ClaveRegimenEspecialOTrascendencia'] = '01'
|
||||
|
||||
if invoice.move_type == 'out_invoice':
|
||||
invoice_node['TipoFactura'] = 'F2' if is_simplified else 'F1'
|
||||
elif invoice.move_type == 'out_refund':
|
||||
invoice_node['TipoFactura'] = 'R5' if is_simplified else 'R1'
|
||||
invoice_node['TipoRectificativa'] = 'I'
|
||||
elif invoice.move_type == 'in_invoice':
|
||||
if reagyp:
|
||||
invoice_node['TipoFactura'] = 'F6'
|
||||
else:
|
||||
invoice_node['TipoFactura'] = 'F1'
|
||||
elif invoice.move_type == 'in_refund':
|
||||
invoice_node['TipoFactura'] = 'R4'
|
||||
invoice_node['TipoRectificativa'] = 'I'
|
||||
|
||||
# === Taxes ===
|
||||
|
||||
sign = -1 if invoice.move_type in ('out_refund', 'in_refund') else 1
|
||||
|
||||
if invoice.is_sale_document():
|
||||
# Customer invoices
|
||||
|
||||
if (com_partner.country_id.code in ('ES', False) and not (com_partner.vat or '').startswith("ESN")) or is_simplified:
|
||||
tax_details_info_vals = self._l10n_es_edi_get_invoices_tax_details_info(invoice)
|
||||
invoice_node['TipoDesglose'] = {'DesgloseFactura': tax_details_info_vals['tax_details_info']}
|
||||
|
||||
invoice_node['ImporteTotal'] = round(sign * (
|
||||
tax_details_info_vals['tax_details']['base_amount']
|
||||
+ tax_details_info_vals['tax_details']['tax_amount']
|
||||
- tax_details_info_vals['tax_amount_retention']
|
||||
), 2)
|
||||
else:
|
||||
tax_details_info_service_vals = self._l10n_es_edi_get_invoices_tax_details_info(
|
||||
invoice,
|
||||
filter_invl_to_apply=lambda x: any(t.tax_scope == 'service' for t in x.tax_ids)
|
||||
)
|
||||
tax_details_info_consu_vals = self._l10n_es_edi_get_invoices_tax_details_info(
|
||||
invoice,
|
||||
filter_invl_to_apply=lambda x: any(t.tax_scope == 'consu' for t in x.tax_ids)
|
||||
)
|
||||
|
||||
if tax_details_info_service_vals['tax_details_info']:
|
||||
invoice_node.setdefault('TipoDesglose', {})
|
||||
invoice_node['TipoDesglose'].setdefault('DesgloseTipoOperacion', {})
|
||||
invoice_node['TipoDesglose']['DesgloseTipoOperacion']['PrestacionServicios'] = tax_details_info_service_vals['tax_details_info']
|
||||
if tax_details_info_consu_vals['tax_details_info']:
|
||||
invoice_node.setdefault('TipoDesglose', {})
|
||||
invoice_node['TipoDesglose'].setdefault('DesgloseTipoOperacion', {})
|
||||
invoice_node['TipoDesglose']['DesgloseTipoOperacion']['Entrega'] = tax_details_info_consu_vals['tax_details_info']
|
||||
|
||||
invoice_node['ImporteTotal'] = round(sign * (
|
||||
tax_details_info_service_vals['tax_details']['base_amount']
|
||||
+ tax_details_info_service_vals['tax_details']['tax_amount']
|
||||
- tax_details_info_service_vals['tax_amount_retention']
|
||||
+ tax_details_info_consu_vals['tax_details']['base_amount']
|
||||
+ tax_details_info_consu_vals['tax_details']['tax_amount']
|
||||
- tax_details_info_consu_vals['tax_amount_retention']
|
||||
), 2)
|
||||
|
||||
else:
|
||||
# Vendor bills
|
||||
|
||||
tax_details_info_isp_vals = self._l10n_es_edi_get_invoices_tax_details_info(
|
||||
invoice,
|
||||
filter_invl_to_apply=lambda x: any(t for t in x.tax_ids if t.l10n_es_type == 'sujeto_isp'),
|
||||
)
|
||||
tax_details_info_other_vals = self._l10n_es_edi_get_invoices_tax_details_info(
|
||||
invoice,
|
||||
filter_invl_to_apply=lambda x: not any(t for t in x.tax_ids if t.l10n_es_type == 'sujeto_isp'),
|
||||
)
|
||||
|
||||
invoice_node['DesgloseFactura'] = {}
|
||||
if tax_details_info_isp_vals['tax_details_info']:
|
||||
invoice_node['DesgloseFactura']['InversionSujetoPasivo'] = tax_details_info_isp_vals['tax_details_info']
|
||||
if tax_details_info_other_vals['tax_details_info']:
|
||||
invoice_node['DesgloseFactura']['DesgloseIVA'] = tax_details_info_other_vals['tax_details_info']
|
||||
|
||||
if any(t.l10n_es_type == 'ignore' for t in invoice.invoice_line_ids.tax_ids):
|
||||
invoice_node['ImporteTotal'] = round(sign * (
|
||||
tax_details_info_isp_vals['tax_details']['base_amount']
|
||||
+ tax_details_info_isp_vals['tax_details']['tax_amount']
|
||||
+ tax_details_info_other_vals['tax_details']['base_amount']
|
||||
+ tax_details_info_other_vals['tax_details']['tax_amount']
|
||||
), 2)
|
||||
else: # Intra-community -100 repartition line needs to be taken into account
|
||||
invoice_node['ImporteTotal'] = round(-invoice.amount_total_signed
|
||||
- sign * tax_details_info_isp_vals['tax_amount_retention']
|
||||
- sign * tax_details_info_other_vals['tax_amount_retention'], 2)
|
||||
|
||||
invoice_node['CuotaDeducible'] = round(sign * (
|
||||
tax_details_info_isp_vals['tax_amount_deductible']
|
||||
+ tax_details_info_other_vals['tax_amount_deductible']
|
||||
), 2)
|
||||
|
||||
info_list.append(info)
|
||||
return info_list
|
||||
|
||||
def _l10n_es_edi_web_service_aeat_vals(self, invoices):
|
||||
if invoices[0].is_sale_document():
|
||||
return {
|
||||
'url': 'https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii_1_1/fact/ws/SuministroFactEmitidas.wsdl',
|
||||
'test_url': 'https://prewww1.aeat.es/wlpl/SSII-FACT/ws/fe/SiiFactFEV1SOAP',
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'url': 'https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii_1_1/fact/ws/SuministroFactRecibidas.wsdl',
|
||||
'test_url': 'https://prewww1.aeat.es/wlpl/SSII-FACT/ws/fr/SiiFactFRV1SOAP',
|
||||
}
|
||||
|
||||
def _l10n_es_edi_web_service_bizkaia_vals(self, invoices):
|
||||
if invoices[0].is_sale_document():
|
||||
return {
|
||||
'url': 'https://www.bizkaia.eus/ogasuna/sii/documentos/SuministroFactEmitidas.wsdl',
|
||||
'test_url': 'https://pruapps.bizkaia.eus/SSII-FACT/ws/fe/SiiFactFEV1SOAP',
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'url': 'https://www.bizkaia.eus/ogasuna/sii/documentos/SuministroFactRecibidas.wsdl',
|
||||
'test_url': 'https://pruapps.bizkaia.eus/SSII-FACT/ws/fr/SiiFactFRV1SOAP',
|
||||
}
|
||||
|
||||
def _l10n_es_edi_web_service_gipuzkoa_vals(self, invoices):
|
||||
if invoices[0].is_sale_document():
|
||||
return {
|
||||
'url': 'https://egoitza.gipuzkoa.eus/ogasuna/sii/ficheros/v1.1/SuministroFactEmitidas.wsdl',
|
||||
'test_url': 'https://sii-prep.egoitza.gipuzkoa.eus/JBS/HACI/SSII-FACT/ws/fe/SiiFactFEV1SOAP',
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'url': 'https://egoitza.gipuzkoa.eus/ogasuna/sii/ficheros/v1.1/SuministroFactRecibidas.wsdl',
|
||||
'test_url': 'https://sii-prep.egoitza.gipuzkoa.eus/JBS/HACI/SSII-FACT/ws/fr/SiiFactFRV1SOAP',
|
||||
}
|
||||
|
||||
def _l10n_es_edi_call_web_service_sign(self, invoices, info_list):
|
||||
return self._l10n_es_edi_call_web_service_sign_common(invoices, info_list)
|
||||
|
||||
def _l10n_es_edi_call_web_service_sign_common(self, invoices, info_list, cancel=False):
|
||||
company = invoices.company_id
|
||||
|
||||
# All are sharing the same value.
|
||||
csv_number = invoices.mapped('l10n_es_edi_csv')[0]
|
||||
|
||||
# Set registration date
|
||||
invoices.filtered(lambda inv: not inv.l10n_es_registration_date).write({
|
||||
'l10n_es_registration_date': fields.Date.context_today(self),
|
||||
})
|
||||
|
||||
# === Call the web service ===
|
||||
|
||||
# Get connection data.
|
||||
l10n_es_edi_tax_agency = company.mapped('l10n_es_edi_tax_agency')[0]
|
||||
connection_vals = getattr(self, f'_l10n_es_edi_web_service_{l10n_es_edi_tax_agency}_vals')(invoices)
|
||||
|
||||
header = {
|
||||
'IDVersionSii': '1.1',
|
||||
'Titular': {
|
||||
'NombreRazon': company.name[:120],
|
||||
'NIF': company.vat[2:] if company.vat.startswith('ES') else company.vat,
|
||||
},
|
||||
'TipoComunicacion': 'A1' if csv_number else 'A0',
|
||||
}
|
||||
|
||||
session = requests.Session()
|
||||
session.cert = company.l10n_es_edi_certificate_id
|
||||
session.mount('https://', PatchedHTTPAdapter())
|
||||
|
||||
client = zeep.Client(connection_vals['url'], operation_timeout=60, timeout=60, session=session)
|
||||
|
||||
if invoices[0].is_sale_document():
|
||||
service_name = 'SuministroFactEmitidas'
|
||||
else:
|
||||
service_name = 'SuministroFactRecibidas'
|
||||
if company.l10n_es_edi_test_env and not connection_vals.get('test_url'):
|
||||
service_name += 'Pruebas'
|
||||
|
||||
# Establish the connection.
|
||||
serv = client.bind('siiService', service_name)
|
||||
if company.l10n_es_edi_test_env and connection_vals.get('test_url'):
|
||||
serv._binding_options['address'] = connection_vals['test_url']
|
||||
|
||||
error_msg = None
|
||||
try:
|
||||
if cancel:
|
||||
if invoices[0].is_sale_document():
|
||||
res = serv.AnulacionLRFacturasEmitidas(header, info_list)
|
||||
else:
|
||||
res = serv.AnulacionLRFacturasRecibidas(header, info_list)
|
||||
else:
|
||||
if invoices[0].is_sale_document():
|
||||
res = serv.SuministroLRFacturasEmitidas(header, info_list)
|
||||
else:
|
||||
res = serv.SuministroLRFacturasRecibidas(header, info_list)
|
||||
except requests.exceptions.SSLError as error:
|
||||
error_msg = _("The SSL certificate could not be validated.")
|
||||
except (zeep.exceptions.Error, requests.exceptions.ConnectionError) as error:
|
||||
error_msg = _("Networking error:\n%s", error)
|
||||
except Exception as error:
|
||||
error_msg = str(error)
|
||||
|
||||
if error_msg:
|
||||
return {inv: {
|
||||
'error': error_msg,
|
||||
'blocking_level': 'warning',
|
||||
} for inv in invoices}
|
||||
|
||||
# Process response.
|
||||
|
||||
if not res or not res.RespuestaLinea:
|
||||
return {inv: {
|
||||
'error': _("The web service is not responding"),
|
||||
'blocking_level': 'warning',
|
||||
} for inv in invoices}
|
||||
|
||||
resp_state = res["EstadoEnvio"]
|
||||
l10n_es_edi_csv = res['CSV']
|
||||
|
||||
if resp_state == 'Correcto':
|
||||
invoices.write({'l10n_es_edi_csv': l10n_es_edi_csv})
|
||||
return {inv: {'success': True} for inv in invoices}
|
||||
|
||||
results = {}
|
||||
for respl in res.RespuestaLinea:
|
||||
invoice_number = respl.IDFactura.NumSerieFacturaEmisor
|
||||
|
||||
# Retrieve the corresponding invoice.
|
||||
# Note: ref can be the same for different partners but there is no enough information on the response
|
||||
# to match the partner.
|
||||
|
||||
# Note: Invoices are batched per move_type.
|
||||
if invoices[0].is_sale_document():
|
||||
inv = invoices.filtered(lambda x: x.name[:60] == invoice_number)
|
||||
else:
|
||||
# 'ref' can be the same for different partners.
|
||||
candidates = invoices.filtered(lambda x: x.ref[:60] == invoice_number)
|
||||
if len(candidates) >= 1:
|
||||
respl_partner_info = respl.IDFactura.IDEmisorFactura
|
||||
inv = None
|
||||
for candidate in candidates:
|
||||
partner_info = self._l10n_es_edi_get_partner_info(candidate.commercial_partner_id)
|
||||
if partner_info.get('NIF') and partner_info['NIF'] == respl_partner_info.NIF:
|
||||
inv = candidate
|
||||
break
|
||||
if (
|
||||
partner_info.get('IDOtro')
|
||||
and respl_partner_info['IDOtro']
|
||||
and all(respl_partner_info['IDOtro'][k] == v for k, v in partner_info['IDOtro'].items())
|
||||
):
|
||||
inv = candidate
|
||||
break
|
||||
|
||||
if not inv:
|
||||
# This case shouldn't happen and means there is something wrong in this code. However, we can't
|
||||
# raise anything since the document has already been approved by the government. The result
|
||||
# will only be a badly logged message into the chatter so, not a big deal.
|
||||
inv = candidates[0]
|
||||
else:
|
||||
inv = candidates
|
||||
|
||||
resp_line_state = respl.EstadoRegistro
|
||||
respl_dict = dict(respl)
|
||||
if resp_line_state in ('Correcto', 'AceptadoConErrores'):
|
||||
inv.l10n_es_edi_csv = l10n_es_edi_csv
|
||||
results[inv] = {'success': True}
|
||||
if resp_line_state == 'AceptadoConErrores':
|
||||
inv.message_post(body=_("This was accepted with errors: ") + html_escape(respl.DescripcionErrorRegistro))
|
||||
elif (
|
||||
(respl_dict.get('RegistroDuplicado') and respl.RegistroDuplicado.EstadoRegistro == 'Correcta')
|
||||
or
|
||||
(cancel and respl_dict.get('CodigoErrorRegistro') == 3001)
|
||||
):
|
||||
results[inv] = {'success': True}
|
||||
inv.message_post(body=_("We saw that this invoice was sent correctly before, but we did not treat "
|
||||
"the response. Make sure it is not because of a wrong configuration."))
|
||||
|
||||
elif respl.CodigoErrorRegistro == 1117 and not self.env.context.get('error_1117'):
|
||||
return self.with_context(error_1117=True)._l10n_es_edi_sii_post_invoices(invoices)
|
||||
|
||||
|
||||
else:
|
||||
results[inv] = {
|
||||
'error': _("[%s] %s", respl.CodigoErrorRegistro, respl.DescripcionErrorRegistro),
|
||||
'blocking_level': 'error',
|
||||
}
|
||||
|
||||
return results
|
||||
|
||||
def _has_oss_taxes(self, invoice):
|
||||
oss_tag = self.env.ref('l10n_eu_oss.tag_oss', raise_if_not_found=False)
|
||||
lines = invoice.invoice_line_ids.filtered(lambda line: line.display_type not in ('line_section', 'line_note'))
|
||||
tags = (lines.tax_ids.invoice_repartition_line_ids | lines.tax_ids.refund_repartition_line_ids).tag_ids
|
||||
return bool(oss_tag and oss_tag in tags)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# EDI OVERRIDDEN METHODS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def _l10n_es_edi_sii_xml_invoice_content(self, invoice):
|
||||
return json.dumps(self._l10n_es_edi_get_invoices_info(invoice)).encode()
|
||||
|
||||
def _get_move_applicability(self, move):
|
||||
# EXTENDS account_edi
|
||||
self.ensure_one()
|
||||
if self.code != 'es_sii':
|
||||
return super()._get_move_applicability(move)
|
||||
|
||||
if move.l10n_es_edi_is_required:
|
||||
return {
|
||||
'post': self._l10n_es_edi_sii_post_invoices,
|
||||
'post_batching': lambda invoice: (invoice.move_type, invoice.l10n_es_edi_csv),
|
||||
'edi_content': self._l10n_es_edi_sii_xml_invoice_content,
|
||||
'cancel': self._l10n_es_edi_sii_cancel_invoices,
|
||||
}
|
||||
|
||||
def _needs_web_services(self):
|
||||
# OVERRIDE
|
||||
return self.code == 'es_sii' or super()._needs_web_services()
|
||||
|
||||
def _check_move_configuration(self, move):
|
||||
# OVERRIDE
|
||||
res = super()._check_move_configuration(move)
|
||||
if self.code != 'es_sii':
|
||||
return res
|
||||
|
||||
if not move.company_id.vat:
|
||||
res.append(_("VAT number is missing on company %s", move.company_id.display_name))
|
||||
for line in move.invoice_line_ids.filtered(lambda line: line.display_type not in ('line_note', 'line_section')):
|
||||
taxes = line.tax_ids.flatten_taxes_hierarchy()
|
||||
recargo_count = taxes.mapped('l10n_es_type').count('recargo')
|
||||
retention_count = taxes.mapped('l10n_es_type').count('retencion')
|
||||
sujeto_count = taxes.mapped('l10n_es_type').count('sujeto')
|
||||
no_sujeto_count = taxes.mapped('l10n_es_type').count('no_sujeto')
|
||||
no_sujeto_loc_count = taxes.mapped('l10n_es_type').count('no_sujeto_loc')
|
||||
if retention_count > 1:
|
||||
res.append(_("Line %s should only have one retention tax.", line.display_name))
|
||||
if recargo_count > 1:
|
||||
res.append(_("Line %s should only have one recargo tax.", line.display_name))
|
||||
if sujeto_count > 1:
|
||||
res.append(_("Line %s should only have one sujeto tax.", line.display_name))
|
||||
if no_sujeto_count > 1:
|
||||
res.append(_("Line %s should only have one no sujeto tax.", line.display_name))
|
||||
if no_sujeto_loc_count > 1:
|
||||
res.append(_("Line %s should only have one no sujeto (localizations) tax.", line.display_name))
|
||||
if sujeto_count + no_sujeto_loc_count + no_sujeto_count > 1:
|
||||
res.append(_("Line %s should only have one main tax.", line.display_name))
|
||||
if move.move_type in ('in_invoice', 'in_refund'):
|
||||
if not move.ref:
|
||||
res.append(_("You should put a vendor reference on this vendor bill. "))
|
||||
return res
|
||||
|
||||
def _is_compatible_with_journal(self, journal):
|
||||
# OVERRIDE
|
||||
if self.code != 'es_sii':
|
||||
return super()._is_compatible_with_journal(journal)
|
||||
|
||||
return journal.country_code == 'ES'
|
||||
|
||||
def _l10n_es_edi_sii_send(self, invoices, cancel=False):
|
||||
# Ensure a certificate is available.
|
||||
certificate = invoices.company_id.l10n_es_edi_certificate_id
|
||||
if not certificate:
|
||||
return {inv: {
|
||||
'error': _("Please configure the certificate for SII."),
|
||||
'blocking_level': 'error',
|
||||
} for inv in invoices}
|
||||
|
||||
# Ensure a tax agency is available.
|
||||
l10n_es_edi_tax_agency = invoices.company_id.mapped('l10n_es_edi_tax_agency')[0]
|
||||
if not l10n_es_edi_tax_agency:
|
||||
return {inv: {
|
||||
'error': _("Please specify a tax agency on your company for SII."),
|
||||
'blocking_level': 'error',
|
||||
} for inv in invoices}
|
||||
|
||||
# Generate the JSON.
|
||||
info_list = self._l10n_es_edi_get_invoices_info(invoices)
|
||||
|
||||
# Call the web service.
|
||||
if not cancel: #retrocompatibility and mocks in tests
|
||||
res = self._l10n_es_edi_call_web_service_sign(invoices, info_list)
|
||||
else:
|
||||
res = self._l10n_es_edi_call_web_service_sign_common(invoices, info_list, cancel=True)
|
||||
|
||||
for inv in invoices:
|
||||
if res.get(inv, {}).get('success'):
|
||||
attachment = self.env['ir.attachment'].create({
|
||||
'type': 'binary',
|
||||
'name': 'jsondump.json',
|
||||
'raw': json.dumps(info_list),
|
||||
'mimetype': 'application/json',
|
||||
'res_model': inv._name,
|
||||
'res_id': inv.id,
|
||||
})
|
||||
res[inv]['attachment'] = attachment
|
||||
if cancel:
|
||||
inv.l10n_es_edi_csv = False
|
||||
return res
|
||||
|
||||
def _l10n_es_edi_sii_post_invoices(self, invoices):
|
||||
return self._l10n_es_edi_sii_send(invoices)
|
||||
|
||||
def _l10n_es_edi_sii_cancel_invoices(self, invoices):
|
||||
return self._l10n_es_edi_sii_send(invoices, cancel=True)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
l10n_es_edi_is_required = fields.Boolean(
|
||||
string="Is the Spanish EDI needed",
|
||||
compute='_compute_l10n_es_edi_is_required'
|
||||
)
|
||||
l10n_es_edi_csv = fields.Char(string="CSV return code", copy=False, tracking=True)
|
||||
# Technical field to keep the date the invoice was sent the first time as
|
||||
# the date the invoice was registered into the system.
|
||||
l10n_es_registration_date = fields.Date(
|
||||
string="Registration Date", copy=False,
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# COMPUTE METHODS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@api.depends('move_type', 'company_id')
|
||||
def _compute_l10n_es_edi_is_required(self):
|
||||
for move in self:
|
||||
move.l10n_es_edi_is_required = move.is_invoice() \
|
||||
and move.country_code == 'ES' \
|
||||
and move.company_id.l10n_es_edi_tax_agency
|
||||
|
||||
def _check_edi_documents_for_reset_to_draft(self):
|
||||
docs = self.edi_document_ids.filtered(lambda d: d.edi_format_id._needs_web_services())
|
||||
if len(docs) == 1 and docs.edi_format_id.code == 'es_sii' and docs.state != 'to_cancel':
|
||||
return True
|
||||
return super()._check_edi_documents_for_reset_to_draft()
|
||||
|
||||
def _edi_allow_button_draft(self):
|
||||
docs = self.edi_document_ids.filtered(lambda d: d.edi_format_id._needs_web_services())
|
||||
if len(docs) == 1 and docs.edi_format_id.code == 'es_sii' and docs.state != 'to_cancel':
|
||||
return True
|
||||
return super()._edi_allow_button_draft()
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class SIIAccountTaxMixin(models.AbstractModel):
|
||||
_name = 'l10n_es.sii.account.tax.mixin'
|
||||
_description = 'SII Fields'
|
||||
|
||||
l10n_es_exempt_reason = fields.Selection(
|
||||
selection=[
|
||||
('E1', 'Art. 20'),
|
||||
('E2', 'Art. 21'),
|
||||
('E3', 'Art. 22'),
|
||||
('E4', 'Art. 23 y 24'),
|
||||
('E5', 'Art. 25'),
|
||||
('E6', 'Otros'),
|
||||
],
|
||||
string="Exempt Reason (Spain)",
|
||||
)
|
||||
l10n_es_type = fields.Selection(
|
||||
selection=[
|
||||
('exento', 'Exento'),
|
||||
('sujeto', 'Sujeto'),
|
||||
('sujeto_agricultura', 'Sujeto Agricultura'),
|
||||
('sujeto_isp', 'Sujeto ISP'),
|
||||
('no_sujeto', 'No Sujeto'),
|
||||
('no_sujeto_loc', 'No Sujeto por reglas de Localization'),
|
||||
('no_deducible', 'No Deducible'),
|
||||
('retencion', 'Retencion'),
|
||||
('recargo', 'Recargo de Equivalencia'),
|
||||
('ignore', 'Ignore even the base amount'),
|
||||
],
|
||||
string="Tax Type (Spain)", default='sujeto'
|
||||
)
|
||||
l10n_es_bien_inversion = fields.Boolean('Bien de Inversion', default=False)
|
||||
|
||||
|
||||
class AccountTax(models.Model):
|
||||
_inherit = ['account.tax', 'l10n_es.sii.account.tax.mixin']
|
||||
_name = 'account.tax'
|
||||
|
||||
|
||||
class AccountTaxTemplate(models.Model):
|
||||
_inherit = ['account.tax.template', 'l10n_es.sii.account.tax.mixin']
|
||||
_name = 'account.tax.template'
|
||||
|
||||
def _get_tax_vals(self, company, tax_template_to_tax):
|
||||
# OVERRIDE
|
||||
# Copy values from 'account.tax.template' to vals will be used to create a new 'account.tax'.
|
||||
vals = super()._get_tax_vals(company, tax_template_to_tax)
|
||||
vals['l10n_es_exempt_reason'] = self.l10n_es_exempt_reason
|
||||
vals['l10n_es_type'] = self.l10n_es_type
|
||||
vals['l10n_es_bien_inversion'] = self.l10n_es_bien_inversion
|
||||
return vals
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from base64 import b64decode
|
||||
from pytz import timezone
|
||||
from datetime import datetime
|
||||
from cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat
|
||||
|
||||
|
||||
from odoo import _, api, fields, models, tools
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.account.tools.certificate import load_key_and_certificates
|
||||
|
||||
|
||||
class Certificate(models.Model):
|
||||
_name = 'l10n_es_edi.certificate'
|
||||
_description = 'Personal Digital Certificate'
|
||||
_order = 'date_start desc, id desc'
|
||||
_rec_name = 'date_start'
|
||||
|
||||
content = fields.Binary(string="File", required=True, help="PFX Certificate")
|
||||
password = fields.Char(help="Passphrase for the PFX certificate", groups="base.group_system")
|
||||
date_start = fields.Datetime(readonly=True, help="The date on which the certificate starts to be valid")
|
||||
date_end = fields.Datetime(readonly=True, help="The date on which the certificate expires")
|
||||
company_id = fields.Many2one(comodel_name='res.company', required=True, default=lambda self: self.env.company)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# HELPERS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def _get_es_current_datetime(self):
|
||||
"""Get the current datetime with the Peruvian timezone. """
|
||||
return datetime.now(timezone('Europe/Madrid'))
|
||||
|
||||
@tools.ormcache('self.content', 'self.password')
|
||||
def _decode_certificate(self):
|
||||
"""Return the content (DER encoded) and the certificate decrypted based in the point 3.1 from the RS 097-2012
|
||||
http://www.vauxoo.com/r/manualdeautorizacion#page=21
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
if not self.password:
|
||||
return None, None, None
|
||||
|
||||
private_key, certificate = load_key_and_certificates(
|
||||
b64decode(self.content),
|
||||
self.password.encode(),
|
||||
)
|
||||
|
||||
pem_certificate = certificate.public_bytes(Encoding.PEM)
|
||||
pem_private_key = private_key.private_bytes(
|
||||
Encoding.PEM,
|
||||
format=PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=NoEncryption(),
|
||||
)
|
||||
return pem_certificate, pem_private_key, certificate
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# LOW-LEVEL METHODS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
certificates = super().create(vals_list)
|
||||
|
||||
spain_tz = timezone('Europe/Madrid')
|
||||
spain_dt = self._get_es_current_datetime()
|
||||
for certificate in certificates:
|
||||
try:
|
||||
_pem_certificate, _pem_private_key, certif = certificate._decode_certificate()
|
||||
cert_date_start = spain_tz.localize(certif.not_valid_before)
|
||||
cert_date_end = spain_tz.localize(certif.not_valid_after)
|
||||
except Exception:
|
||||
raise ValidationError(_(
|
||||
"There has been a problem with the certificate, some usual problems can be:\n"
|
||||
"- The password given or the certificate are not valid.\n"
|
||||
"- The certificate content is invalid."
|
||||
))
|
||||
# Assign extracted values from the certificate
|
||||
certificate.write({
|
||||
'date_start': fields.Datetime.to_string(cert_date_start),
|
||||
'date_end': fields.Datetime.to_string(cert_date_end),
|
||||
})
|
||||
if spain_dt > cert_date_end:
|
||||
raise ValidationError(_("The certificate is expired since %s", certificate.date_end))
|
||||
return certificates
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
from odoo import models
|
||||
|
||||
|
||||
class MailTemplate(models.Model):
|
||||
_inherit = "mail.template"
|
||||
|
||||
def _get_edi_attachments(self, document):
|
||||
# When an invoice is signed, an electronic document is created (i.e. jsondump.json)
|
||||
# Prevent this document to be added in "SEND & PRINT" wizard
|
||||
if document.name == 'jsondump.json' and document.edi_format_id.code == 'es_sii':
|
||||
return {}
|
||||
return super()._get_edi_attachments(document)
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
l10n_es_edi_certificate_id = fields.Many2one(
|
||||
string="Certificate (ES)",
|
||||
store=True,
|
||||
readonly=False,
|
||||
comodel_name='l10n_es_edi.certificate',
|
||||
compute="_compute_l10n_es_edi_certificate",
|
||||
)
|
||||
l10n_es_edi_certificate_ids = fields.One2many(
|
||||
comodel_name='l10n_es_edi.certificate',
|
||||
inverse_name='company_id',
|
||||
)
|
||||
l10n_es_edi_tax_agency = fields.Selection(
|
||||
string="Tax Agency for SII",
|
||||
selection=[
|
||||
('aeat', "Agencia Tributaria española"),
|
||||
('gipuzkoa', "Hacienda Foral de Gipuzkoa"),
|
||||
('bizkaia', "Hacienda Foral de Bizkaia"),
|
||||
],
|
||||
default=False,
|
||||
)
|
||||
l10n_es_edi_test_env = fields.Boolean(
|
||||
string="Test Mode",
|
||||
help="Use the test environment",
|
||||
default=True,
|
||||
)
|
||||
|
||||
@api.depends('country_id', 'l10n_es_edi_certificate_ids')
|
||||
def _compute_l10n_es_edi_certificate(self):
|
||||
for company in self:
|
||||
if company.country_code == 'ES':
|
||||
company.l10n_es_edi_certificate_id = self.env['l10n_es_edi.certificate'].search(
|
||||
[('company_id', '=', company.id)],
|
||||
order='date_end desc',
|
||||
limit=1,
|
||||
)
|
||||
else:
|
||||
company.l10n_es_edi_certificate_id = False
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
l10n_es_edi_certificate_ids = fields.One2many(related='company_id.l10n_es_edi_certificate_ids', readonly=False)
|
||||
l10n_es_edi_tax_agency = fields.Selection(related='company_id.l10n_es_edi_tax_agency', readonly=False)
|
||||
l10n_es_edi_test_env = fields.Boolean(related='company_id.l10n_es_edi_test_env', readonly=False)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_l10n_es_edi_certificate,access_l10n_es_edi_certificate,model_l10n_es_edi_certificate,base.group_system,1,1,1,1
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo noupdate="1">
|
||||
<!-- Allow access to certificates of current company/companies -->
|
||||
<record id="l10n_ec_digital_certificate" model="ir.rule">
|
||||
<field name="name">Spanish Digital Certificate</field>
|
||||
<field name="model_id" ref="l10n_es_edi_sii.model_l10n_es_edi_certificate"/>
|
||||
<field name="domain_force">[('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# coding: utf-8
|
||||
|
||||
from . import test_edi_xml
|
||||
from . import test_edi_web_services
|
||||
from . import test_resequence
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
# coding: utf-8
|
||||
import base64
|
||||
from pytz import timezone
|
||||
from datetime import datetime
|
||||
|
||||
from odoo.tools import misc
|
||||
from odoo.addons.account_edi.tests.common import AccountEdiTestCommon
|
||||
|
||||
|
||||
def mocked_l10n_es_edi_call_web_service_sign(edi_format, invoices, info_list):
|
||||
return {inv: {"success": True} for inv in invoices}
|
||||
|
||||
|
||||
class TestEsEdiCommon(AccountEdiTestCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref='l10n_es.account_chart_template_full', edi_format_ref='l10n_es_edi_sii.edi_es_sii'):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref, edi_format_ref=edi_format_ref)
|
||||
|
||||
cls.frozen_today = datetime(year=2019, month=1, day=1, hour=0, minute=0, second=0, tzinfo=timezone('utc'))
|
||||
|
||||
# Allow to see the full result of AssertionError.
|
||||
cls.maxDiff = None
|
||||
|
||||
# ==== Config ====
|
||||
|
||||
cls.certificate = cls.env['l10n_es_edi.certificate'].create({
|
||||
'content': base64.encodebytes(
|
||||
misc.file_open("l10n_es_edi_sii/demo/certificates/aeat_1234.p12", 'rb').read()),
|
||||
'password': '1234',
|
||||
})
|
||||
|
||||
cls.company_data['company'].write({
|
||||
'country_id': cls.env.ref('base.es').id,
|
||||
'state_id': cls.env.ref('base.state_es_z').id,
|
||||
'l10n_es_edi_certificate_id': cls.certificate.id,
|
||||
'vat': 'ES59962470K',
|
||||
'l10n_es_edi_test_env': True,
|
||||
'l10n_es_edi_tax_agency': 'bizkaia',
|
||||
})
|
||||
|
||||
# To be sure it is put by default on purchase journals as well (tbai module)
|
||||
cls.company_data['default_journal_purchase'].write({
|
||||
'edi_format_ids': [(6, 0, cls.edi_format.ids)],
|
||||
})
|
||||
# ==== Business ====
|
||||
|
||||
cls.partner_a.write({
|
||||
'vat': 'BE0477472701',
|
||||
'country_id': cls.env.ref('base.be').id,
|
||||
})
|
||||
|
||||
cls.partner_b.write({
|
||||
'vat': 'ESF35999705',
|
||||
})
|
||||
|
||||
cls.product_t = cls.env["product.product"].create(
|
||||
{"name": "Test product"})
|
||||
cls.partner_t = cls.env["res.partner"].create({"name": "Test partner", "vat": "ESF35999705"})
|
||||
|
||||
@classmethod
|
||||
def _get_tax_by_xml_id(cls, trailing_xml_id):
|
||||
""" Helper to retrieve a tax easily.
|
||||
|
||||
:param trailing_xml_id: The trailing tax's xml id.
|
||||
:return: An account.tax record
|
||||
"""
|
||||
return cls.env.ref(f'l10n_es.{cls.env.company.id}_account_tax_template_{trailing_xml_id}')
|
||||
|
||||
@classmethod
|
||||
def create_invoice(cls, **kwargs):
|
||||
return cls.env['account.move'].with_context(edi_test_mode=True).create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'invoice_date': '2019-01-01',
|
||||
'date': '2019-01-01',
|
||||
**kwargs,
|
||||
'invoice_line_ids': [(0, 0, {
|
||||
'product_id': cls.product_a.id,
|
||||
'price_unit': 1000.0,
|
||||
**line_vals,
|
||||
}) for line_vals in kwargs.get('invoice_line_ids', [])],
|
||||
})
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime
|
||||
|
||||
from odoo.tests import tagged
|
||||
from odoo import fields
|
||||
from .common import TestEsEdiCommon
|
||||
|
||||
|
||||
@tagged('external_l10n', 'post_install', '-at_install', '-standard', 'external')
|
||||
class TestEdiWebServices(TestEsEdiCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref='l10n_es.account_chart_template_full', edi_format_ref='l10n_es_edi_sii.edi_es_sii'):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref, edi_format_ref=edi_format_ref)
|
||||
|
||||
# Invoice name are tracked by the web-services so this constant tries to get a new unique invoice name at each
|
||||
# execution.
|
||||
cls.today = datetime.now()
|
||||
cls.time_name = cls.today.strftime('%H%M%S')
|
||||
|
||||
cls.out_invoice = cls.env['account.move'].create({
|
||||
'name': f'INV{cls.time_name}',
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'invoice_line_ids': [(0, 0, {
|
||||
'product_id': cls.product_a.id,
|
||||
'price_unit': 1000.0,
|
||||
'quantity': 5,
|
||||
'discount': 20.0,
|
||||
'tax_ids': [(6, 0, cls._get_tax_by_xml_id('s_iva21b').ids)],
|
||||
})],
|
||||
})
|
||||
cls.out_invoice.action_post()
|
||||
|
||||
cls.in_invoice = cls.env['account.move'].create({
|
||||
'name': f'BILL{cls.time_name}',
|
||||
'ref': f'REFBILL{cls.time_name}',
|
||||
'move_type': 'in_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'invoice_date': fields.Date.to_string(cls.today.date()),
|
||||
'invoice_line_ids': [(0, 0, {
|
||||
'product_id': cls.product_a.id,
|
||||
'price_unit': 1000.0,
|
||||
'quantity': 5,
|
||||
'discount': 20.0,
|
||||
'tax_ids': [(6, 0, cls._get_tax_by_xml_id('p_iva10_bc').ids)],
|
||||
})],
|
||||
})
|
||||
cls.in_invoice.action_post()
|
||||
|
||||
cls.moves = cls.out_invoice + cls.in_invoice
|
||||
|
||||
def test_edi_gipuzkoa(self):
|
||||
self.env.company.l10n_es_edi_tax_agency = 'gipuzkoa'
|
||||
|
||||
self.moves.action_process_edi_web_services(with_commit=False)
|
||||
generated_files = self._process_documents_web_services(self.moves, {'es_sii'})
|
||||
self.assertTrue(generated_files)
|
||||
self.assertRecordValues(self.out_invoice, [{'edi_state': 'sent'}])
|
||||
self.assertRecordValues(self.in_invoice, [{'edi_state': 'sent'}])
|
||||
|
||||
def test_edi_bizkaia(self):
|
||||
self.env.company.l10n_es_edi_tax_agency = 'bizkaia'
|
||||
|
||||
self.moves.action_process_edi_web_services(with_commit=False)
|
||||
generated_files = self._process_documents_web_services(self.moves, {'es_sii'})
|
||||
self.assertTrue(generated_files)
|
||||
self.assertRecordValues(self.out_invoice, [{'edi_state': 'sent'}])
|
||||
self.assertRecordValues(self.in_invoice, [{'edi_state': 'sent'}])
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,136 @@
|
|||
from datetime import date
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests import Form, tagged
|
||||
|
||||
from .common import TestEsEdiCommon, mocked_l10n_es_edi_call_web_service_sign
|
||||
|
||||
|
||||
@tagged("post_install_l10n", "post_install", "-at_install")
|
||||
class TestResequenceSII(TestEsEdiCommon):
|
||||
@classmethod
|
||||
def setUpClass(
|
||||
cls,
|
||||
chart_template_ref="l10n_es.account_chart_template_full",
|
||||
edi_format_ref="l10n_es_edi_sii.edi_es_sii",
|
||||
):
|
||||
cls.startClassPatcher(freeze_time("2019-06-01", tick=True))
|
||||
super().setUpClass(
|
||||
chart_template_ref=chart_template_ref, edi_format_ref=edi_format_ref
|
||||
)
|
||||
cls.classPatch(
|
||||
cls.registry["account.edi.format"],
|
||||
"_l10n_es_edi_call_web_service_sign",
|
||||
mocked_l10n_es_edi_call_web_service_sign,
|
||||
)
|
||||
# Create 2 customer and 2 vendor invoices, in wrong date order
|
||||
cls.customer_invoice_2 = cls.create_invoice(
|
||||
invoice_date="2019-05-15", date="2019-05-15", invoice_line_ids=[{}]
|
||||
)
|
||||
cls.customer_invoice_1 = cls.create_invoice(
|
||||
invoice_date="2019-05-01", date="2019-05-01", invoice_line_ids=[{}]
|
||||
)
|
||||
cls.vendor_invoice_2 = cls.create_invoice(
|
||||
invoice_date="2019-04-15",
|
||||
date="2019-04-15",
|
||||
move_type="in_invoice",
|
||||
ref="vendor/1",
|
||||
invoice_line_ids=[{}],
|
||||
)
|
||||
cls.vendor_invoice_1 = cls.create_invoice(
|
||||
invoice_date="2019-04-01",
|
||||
date="2019-04-01",
|
||||
move_type="in_invoice",
|
||||
ref="vendor/2",
|
||||
invoice_line_ids=[{}],
|
||||
)
|
||||
# Post them, in wrong date order
|
||||
cls.customer_invoice_2.action_post()
|
||||
cls.customer_invoice_1.action_post()
|
||||
cls.vendor_invoice_2.action_post()
|
||||
cls.vendor_invoice_1.action_post()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# Send to SII
|
||||
all_invoices = (
|
||||
self.customer_invoice_1
|
||||
+ self.customer_invoice_2
|
||||
+ self.vendor_invoice_1
|
||||
+ self.vendor_invoice_2
|
||||
)
|
||||
self.generated_files = self._process_documents_web_services(
|
||||
all_invoices, {self.edi_format.code}
|
||||
)
|
||||
self.assertRecordValues(
|
||||
all_invoices,
|
||||
[
|
||||
{
|
||||
"invoice_date": date(2019, 5, 1),
|
||||
"date": date(2019, 5, 1),
|
||||
"name": "INV/2019/00002",
|
||||
},
|
||||
{
|
||||
"invoice_date": date(2019, 5, 15),
|
||||
"date": date(2019, 5, 15),
|
||||
"name": "INV/2019/00001",
|
||||
},
|
||||
{
|
||||
"invoice_date": date(2019, 4, 1),
|
||||
"date": date(2019, 4, 1),
|
||||
"name": "BILL/2019/04/0002",
|
||||
},
|
||||
{
|
||||
"invoice_date": date(2019, 4, 15),
|
||||
"date": date(2019, 4, 15),
|
||||
"name": "BILL/2019/04/0001",
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
def test_customer_fails(self):
|
||||
"""Check we cannot resequence customer invoices."""
|
||||
invoices = self.customer_invoice_1 + self.customer_invoice_2
|
||||
wiz_f = Form(
|
||||
self.env["account.resequence.wizard"].with_context(
|
||||
active_model="account.move",
|
||||
active_ids=invoices.ids,
|
||||
)
|
||||
)
|
||||
wiz_f.ordering = "date"
|
||||
wiz = wiz_f.save()
|
||||
with self.assertRaises(
|
||||
UserError,
|
||||
msg="The following documents have already been sent and cannot be resequenced: INV/2019/00001, INV/2019/00002",
|
||||
):
|
||||
wiz.resequence()
|
||||
|
||||
def test_vendor_works(self):
|
||||
"""Check we can resequence vendor bills."""
|
||||
invoices = self.vendor_invoice_1 + self.vendor_invoice_2
|
||||
wiz_f = Form(
|
||||
self.env["account.resequence.wizard"].with_context(
|
||||
active_model="account.move",
|
||||
active_ids=invoices.ids,
|
||||
)
|
||||
)
|
||||
wiz_f.ordering = "date"
|
||||
wiz = wiz_f.save()
|
||||
wiz.resequence()
|
||||
self.assertRecordValues(
|
||||
invoices,
|
||||
[
|
||||
{
|
||||
"invoice_date": date(2019, 4, 1),
|
||||
"date": date(2019, 4, 1),
|
||||
"name": "BILL/2019/04/0001",
|
||||
},
|
||||
{
|
||||
"invoice_date": date(2019, 4, 15),
|
||||
"date": date(2019, 4, 15),
|
||||
"name": "BILL/2019/04/0002",
|
||||
},
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="view_move_form_inherit_l10n_es_edi" model="ir.ui.view">
|
||||
<field name="name">account.move.form.inherit.l10n_es_edi</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_move_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@id='other_tab_group']//group[@name='accounting_info_group']" position="inside">
|
||||
<field name="l10n_es_registration_date" attrs="{'readonly': [('state', '=', 'posted')], 'invisible': [('country_code', '!=', 'ES')]}"/>
|
||||
<field name="l10n_es_edi_csv" invisible="1"/>
|
||||
</xpath>
|
||||
<field name="ref" position="attributes">
|
||||
<attribute name="attrs">{'readonly': [('l10n_es_edi_csv', '!=', False)]}</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="account_tax_form_inherit_l10n_es_edi" model="ir.ui.view">
|
||||
<field name="name">account.tax.form.inherit.l10n_es_edi</field>
|
||||
<field name="model">account.tax</field>
|
||||
<field name="inherit_id" ref="account.view_tax_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='tax_scope']" position="after">
|
||||
<field name="l10n_es_type"
|
||||
attrs="{'invisible': [('country_code', '!=', 'ES')]}"/>
|
||||
<field name="l10n_es_exempt_reason"
|
||||
attrs="{'invisible': [('country_code', '!=', 'ES'), ('l10n_es_type', '!=', 'exento')], 'required': [('l10n_es_type', '=', 'exento'), ('type_tax_use', '=', 'sale')]}"/>
|
||||
<field name="l10n_es_bien_inversion"
|
||||
attrs="{'invisible': [('country_code', '!=', 'ES'), ('l10n_es_type', '!=', 'exento')], 'required': [('l10n_es_type', '=', 'exento'), ('type_tax_use', '=', 'sale')]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="l10n_es_edi_certificate_form" model="ir.ui.view">
|
||||
<field name="name">l10n_es_edi.certificate.form</field>
|
||||
<field name="model">l10n_es_edi.certificate</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="content"/>
|
||||
<field name="password" password="True"/>
|
||||
<label for="date_start" string="Validity"/>
|
||||
<div>
|
||||
<field name="date_start"/> -
|
||||
<field name="date_end"/>
|
||||
</div>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="l10n_es_edi_certificate_tree" model="ir.ui.view">
|
||||
<field name="name">l10n_es_edi.certificate.tree</field>
|
||||
<field name="model">l10n_es_edi.certificate</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="l10n_es_edi_certificate_action" model="ir.actions.act_window">
|
||||
<field name="name">Certificates for EDI invoices on Spain</field>
|
||||
<field name="res_model">l10n_es_edi.certificate</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">Create the first certificate</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_l10n_es_edi_root"
|
||||
name="Spain"
|
||||
sequence="110"
|
||||
groups="account.group_account_manager"
|
||||
parent="account.menu_finance_configuration">
|
||||
<menuitem id="menu_l10n_es_edi_certificates"
|
||||
name="Certificates (ES)"
|
||||
action="l10n_es_edi_certificate_action"
|
||||
sequence="100"
|
||||
groups="account.group_account_manager"/>
|
||||
</menuitem>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.l10n.es</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@data-key='account']/div" position="after">
|
||||
<h2 attrs="{'invisible': [('country_code', '!=', 'ES')]}">Spain Localization</h2>
|
||||
<div class="row mt16 o_settings_container"
|
||||
name="spain_localization"
|
||||
attrs="{'invisible': [('country_code', '!=', 'ES')]}">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
|
||||
<!-- Invisible fields -->
|
||||
<field name="l10n_es_edi_certificate_ids" invisible="1"/>
|
||||
|
||||
<div class="o_setting_left_pane"/>
|
||||
|
||||
<div class="o_setting_right_pane">
|
||||
<span class="o_form_label">Registro de Libros connection SII</span>
|
||||
<span class="fa fa-lg fa-building-o"
|
||||
title="Values set here are company-specific."
|
||||
groups="base.group_multi_company"/>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<label for="l10n_es_edi_tax_agency" class="o_light_label"/>
|
||||
<field name="l10n_es_edi_tax_agency"/>
|
||||
<div class="text-muted" attrs="{'invisible': [('l10n_es_edi_tax_agency', '!=', False)]}">
|
||||
No tax agency selected: SII not activated.
|
||||
</div>
|
||||
<div class="text-muted" attrs="{'invisible': [('l10n_es_edi_tax_agency', '=', False)]}">
|
||||
Tax agency selected: invoices will be sent by SII for journals where it is activated.
|
||||
</div>
|
||||
<br/>
|
||||
<div class="o_row">
|
||||
<label for="l10n_es_edi_test_env" class="o_light_label"/>
|
||||
<field name="l10n_es_edi_test_env"/>
|
||||
</div>
|
||||
<div class="text-muted" attrs="{'invisible': [('l10n_es_edi_test_env', '=', False)]}">
|
||||
Test mode: EDI data is sent to separate test servers and is not considered official.
|
||||
</div>
|
||||
<div class="text-muted" attrs="{'invisible': [('l10n_es_edi_test_env', '!=', False)]}">
|
||||
Production mode: EDI data is sent to the official agency servers.
|
||||
</div>
|
||||
<br/>
|
||||
<div>
|
||||
<button name="%(l10n_es_edi_certificate_action)d" type="action" class="oe_link">Manage certificates (SII/TicketBAI)</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import account_resequence_wizard
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo import models
|
||||
|
||||
|
||||
class AccountResequenceWizard(models.TransientModel):
|
||||
_inherit = "account.resequence.wizard"
|
||||
|
||||
def _frozen_edi_documents(self):
|
||||
docs = super()._frozen_edi_documents()
|
||||
# SII vendor bills are sent with ref, so they can be resequenced
|
||||
return docs.filtered(
|
||||
lambda doc: doc.edi_format_id.code != "es_sii"
|
||||
or doc.move_id.is_sale_document()
|
||||
)
|
||||
43
odoo-bringout-oca-ocb-l10n_es_edi_sii/pyproject.toml
Normal file
43
odoo-bringout-oca-ocb-l10n_es_edi_sii/pyproject.toml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[project]
|
||||
name = "odoo-bringout-oca-ocb-l10n_es_edi_sii"
|
||||
version = "16.0.0"
|
||||
description = "Spain - SII EDI Suministro de Libros - Odoo addon"
|
||||
authors = [
|
||||
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
|
||||
]
|
||||
dependencies = [
|
||||
"odoo-bringout-oca-ocb-l10n_es>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-account_edi>=16.0.0",
|
||||
"requests>=2.25.1"
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">= 3.11"
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Office/Business",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
homepage = "https://github.com/bringout/0"
|
||||
repository = "https://github.com/bringout/0"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.hatch.metadata]
|
||||
allow-direct-references = true
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["l10n_es_edi_sii"]
|
||||
|
||||
[tool.rye]
|
||||
managed = true
|
||||
dev-dependencies = [
|
||||
"pytest>=8.4.1",
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue