Skip to content

Commit

Permalink
Merge 859123f into 56820b5
Browse files Browse the repository at this point in the history
  • Loading branch information
acysos committed Jun 25, 2019
2 parents 56820b5 + 859123f commit 191b5c4
Show file tree
Hide file tree
Showing 12 changed files with 537 additions and 343 deletions.
9 changes: 9 additions & 0 deletions l10n_es_aeat/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Módulo base para declaraciones de la AEAT, que incluye:
* Motor de cálculo de importes por impuestos.
* Generador del asiento de regularización con cargo a un proveedor "Agencia
Estatal de Administración Tributaria" creado al efecto.
* Certificado para las declaraciones de la AEAT

Configuración
=============
Expand Down Expand Up @@ -64,6 +65,12 @@ Para poder visualizar un archivo BOE, hay que:
correspondiente a dicha línea, y si es un importe numérico, su cifra
asociada.

Para importar el certificado, hay que:

#. Entrar en *Contabilidad > Configuración > AEAT > Certificados*
#. Crear uno nuevo. Rellenas los datos del formulurio y subir el archivo p12
#. Pulsar obtener claves e introducir la contraseña del certificado

.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/189/10.0
Expand Down Expand Up @@ -99,6 +106,8 @@ Contribudores
* Ainara Galdona
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
* Abraham Anes <abraham@studio73.es>
* Diagram Software S.L.
* Consultoría Informática Studio 73 S.L.

Maintainer
----------
Expand Down
10 changes: 6 additions & 4 deletions l10n_es_aeat/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2004-2011 Luis Manuel Angueira Blanco - Pexego
# Copyright 2013 Ignacio Ibeas - Acysos S.L. (http://acysos.com)
# Copyright 2013-2019 Ignacio Ibeas - Acysos S.L. (http://acysos.com)
# Copyright 2015 Ainara Galdona <agaldona@avanzosc.com>
# Copyright 2016 Antonio Espinosa <antonio.espinosa@tecnativa.com>
# Copyright 2013-2018 Pedro M. Baeza <pedro.baeza@tecnativa.com>
Expand All @@ -9,9 +9,9 @@
{
'name': "AEAT Base",
'summary': "Modulo base para declaraciones de la AEAT",
'version': "10.0.2.0.1",
'version': "10.0.2.0.2",
'author': "Pexego,"
"Acysos,"
"Acysos S.L.,"
"AvanzOSC,"
"Tecnativa,"
"Odoo Community Association (OCA)",
Expand All @@ -24,21 +24,23 @@
'account_tax_balance',
],
'external_dependencies': {
'python': ['unidecode'],
'python': ['unidecode', 'OpenSSL'],
},
'data': [
'security/aeat_security.xml',
'security/ir.model.access.csv',
'data/aeat_partner.xml',
'wizard/export_to_boe_wizard.xml',
'wizard/compare_boe_file_views.xml',
'wizard/aeat_certificate_password_view.xml',
'views/aeat_menuitem.xml',
'views/aeat_report_view.xml',
'views/aeat_tax_line_view.xml',
'views/aeat_export_configuration_view.xml',
'views/aeat_tax_code_mapping_view.xml',
'views/account_move_line_view.xml',
'views/report_template.xml',
'views/aeat_certificate_view.xml',
],
'installable': True,
}
361 changes: 151 additions & 210 deletions l10n_es_aeat/i18n/es.po

Large diffs are not rendered by default.

239 changes: 115 additions & 124 deletions l10n_es_aeat/i18n/l10n_es_aeat.pot

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions l10n_es_aeat/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
from . import l10n_es_aeat_tax_line
from . import l10n_es_aeat_export_config
from . import l10n_es_aeat_export_config_line
from . import aeat_certificate
77 changes: 77 additions & 0 deletions l10n_es_aeat/models/aeat_certificate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# (c) 2017 Diagram Software S.L.
# (c) 2017 Consultoría Informática Studio 73 S.L.
# (c) 2019 Acysos S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import api, models, fields, _


class L10nEsAeatCertificate(models.Model):
_name = 'l10n.es.aeat.certificate'

name = fields.Char(string="Name")
state = fields.Selection([
('draft', 'Draft'),
('active', 'Active')
], string="State", default="draft")
file = fields.Binary(string="File", required=True)
folder = fields.Char(string="Folder Name", required=True)
date_start = fields.Date(string="Start Date")
date_end = fields.Date(string="End Date")
public_key = fields.Char(string="Public Key", readonly=True)
private_key = fields.Char(string="Private Key", readonly=True)
company_id = fields.Many2one(
comodel_name="res.company",
string="Compañía",
required=True,
default=lambda self: self.env.user.company_id.id
)

@api.multi
def load_password_wizard(self):
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': _('Insert Password'),
'res_model': 'l10n.es.aeat.certificate.password',
'view_mode': 'form',
'view_type': 'form',
'views': [(False, 'form')],
'target': 'new',
}

@api.multi
def action_active(self):
self.ensure_one()
other_configs = self.search([('id', '!=', self.id),
('company_id', '=', self.company_id.id)])
for config_id in other_configs:
config_id.state = 'draft'
self.state = 'active'

@api.multi
def get_certificates(self, company = False):
if not company:
company = self.env.user.company_id
today = fields.Date.today()
aeat_certificate = self.search([
('company_id', '=', company.id),
('public_key', '!=', False),
('private_key', '!=', False),
'|', ('date_start', '=', False),
('date_start', '<=', today),
'|', ('date_end', '=', False),
('date_end', '>=', today),
('state', '=', 'active')
], limit=1)
if aeat_certificate:
public_crt = aeat_certificate.public_key
private_key = aeat_certificate.private_key
else:
public_crt = self.env['ir.config_parameter'].get_param(
'l10n_es_aeat_certificate.publicCrt', False)
private_key = self.env['ir.config_parameter'].get_param(
'l10n_es_aeat_certificate.privateKey', False)
return public_crt, private_key

17 changes: 12 additions & 5 deletions l10n_es_aeat/security/aeat_security.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@
<!-- License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>

<record model="res.groups" id="group_account_aeat">
<field name="name">AEAT manager</field>
<field name="category_id" ref="base.module_category_hidden"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<record model="res.groups" id="group_account_aeat">
<field name="name">AEAT manager</field>
<field name="category_id" ref="base.module_category_hidden"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>

<record id="l10n_es_aeat_certificate_rule" model="ir.rule">
<field name="name">AEAT Certificate multi-company</field>
<field ref="model_l10n_es_aeat_certificate" name="model_id"/>
<field eval="True" name="global"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
</record>

</odoo>
1 change: 1 addition & 0 deletions l10n_es_aeat/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ access_model_l10n_es_aeat_map_tax_aeat,aeat.mod.map.tax.code aeat,model_l10n_es_
access_model_l10n_es_aeat_map_tax_line_admin,aeat.mod.map.tax.code.line admin,model_l10n_es_aeat_map_tax_line,base.group_system,1,1,1,1
access_model_l10n_es_aeat_map_taxe_line_aeat,aeat.mod.map.tax.code.line aeat,model_l10n_es_aeat_map_tax_line,group_account_aeat,1,0,0,0
access_model_l10n_es_aeat_tax_line_aeat,l10n.es.aeat.tax.line aeat,model_l10n_es_aeat_tax_line,group_account_aeat,1,1,1,1
access_l10n_es_aeat_certificate_manager,l10n_es_aeat_certificate manager,model_l10n_es_aeat_certificate,account.group_account_manager,1,1,1,1
60 changes: 60 additions & 0 deletions l10n_es_aeat/views/aeat_certificate_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="l10n_es_aeat_certificate_form_view" model="ir.ui.view">
<field name="name">l10n.es.aeat.certificate.form</field>
<field name="model">l10n.es.aeat.certificate</field>
<field name="arch" type="xml">
<form string="Load Certificate">
<header>
<button name="load_password_wizard" type="object" string="Obtain Keys"/>
<button name="action_active" type="object" string="To Active"/>
<field name="state" widget="statusbar" statusbar_visible="draft,active"/>
</header>
<group>
<group>
<field name="name"/>
<field name="file"/>
<field name="folder"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company"/>
<field name="date_start"/>
<field name="date_end"/>
</group>
</group>
<group>
<field name="private_key"/>
<field name="public_key"/>
</group>
</form>
</field>
</record>

<record id="l10n_es_certificate_tree_view" model="ir.ui.view">
<field name="name">l10n.es.aeat.certificate.tree</field>
<field name="model">l10n.es.aeat.certificate</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="state"/>
</tree>
</field>
</record>

<record id="l10n_es_certificate_action" model="ir.actions.act_window">
<field name="name">Certificates</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">l10n.es.aeat.certificate</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>

<menuitem id="l10n_es_aeat_certificate_menu" name="Certificates"
action="l10n_es_certificate_action" sequence="0"
parent="l10n_es_aeat.menu_l10n_es_aeat_config" />

</data>
</odoo>
1 change: 1 addition & 0 deletions l10n_es_aeat/wizard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

from . import compare_boe_file
from . import export_to_boe
from . import aeat_certificate_password
81 changes: 81 additions & 0 deletions l10n_es_aeat/wizard/aeat_certificate_password.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Diagram Software S.L.
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html


from odoo import _, api, exceptions, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import config
from odoo import release
import contextlib
import os
import tempfile
import base64
import logging

_logger = logging.getLogger(__name__)

try:
import OpenSSL.crypto
except (ImportError, IOError) as err:
_logger.debug(err)

if tuple(map(int, OpenSSL.__version__.split('.'))) < (0, 15):
_logger.warning(
'OpenSSL version is not supported. Upgrade to 0.15 or greater.')


@contextlib.contextmanager
def pfx_to_pem(file, pfx_password, directory=None):
with tempfile.NamedTemporaryFile(
prefix='private_', suffix='.pem', delete=False,
dir=directory) as t_pem:
f_pem = open(t_pem.name, 'wb')
p12 = OpenSSL.crypto.load_pkcs12(file, pfx_password)
f_pem.write(OpenSSL.crypto.dump_privatekey(
OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()))
f_pem.close()
yield t_pem.name


@contextlib.contextmanager
def pfx_to_crt(file, pfx_password, directory=None):
with tempfile.NamedTemporaryFile(
prefix='public_', suffix='.crt', delete=False,
dir=directory) as t_crt:
f_crt = open(t_crt.name, 'wb')
p12 = OpenSSL.crypto.load_pkcs12(file, pfx_password)
f_crt.write(OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate()))
f_crt.close()
yield t_crt.name


class L10nEsAeatCertificatePassword(models.TransientModel):
_name = 'l10n.es.aeat.certificate.password'

password = fields.Char(string="Password", required=True)

@api.multi
def get_keys(self):
record = self.env['l10n.es.aeat.certificate'].browse(
self.env.context.get('active_id'))
directory = os.path.join(
os.path.abspath(config['data_dir']), 'certificates',
release.series, self.env.cr.dbname, record.folder)
file = base64.decodestring(record.file)
if tuple(map(int, OpenSSL.__version__.split('.'))) < (0, 15):
raise exceptions.Warning(
_('OpenSSL version is not supported. Upgrade to 0.15 '
'or greater.'))
try:
if directory and not os.path.exists(directory):
os.makedirs(directory)
with pfx_to_pem(file, self.password, directory) as private_key:
record.private_key = private_key
with pfx_to_crt(file, self.password, directory) as public_key:
record.public_key = public_key
except Exception as e:
if e.args:
args = list(e.args)
raise ValidationError(args[-1])
23 changes: 23 additions & 0 deletions l10n_es_aeat/wizard/aeat_certificate_password_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>

<record id="l10n_es_aeat_certificate_password_wizard_view" model="ir.ui.view">
<field name="name">l10n.es.aeat.certificate.password.wizard</field>
<field name="model">l10n.es.aeat.certificate.password</field>
<field name="arch" type="xml">
<form string="Insert Password">
<group>
<field name="password" password="True"/>
</group>
<footer>
<button name="get_keys" type="object" string="Obtain Keys" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>

</data>
</odoo>

0 comments on commit 191b5c4

Please sign in to comment.