From 59a538281c074d8d7227276d7f907ef2fadb4211 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Wed, 5 Jul 2017 10:31:48 +0200 Subject: [PATCH 001/101] [ADD] l10n_es_facturae_face --- l10n_es_facturae_face/README.rst | 76 ++++++ l10n_es_facturae_face/__init__.py | 5 + l10n_es_facturae_face/__manifest__.py | 30 +++ l10n_es_facturae_face/data/face_data.xml | 62 +++++ l10n_es_facturae_face/models/__init__.py | 9 + .../models/account_invoice_integration.py | 25 ++ .../models/account_invoice_integration_log.py | 156 ++++++++++++ .../account_invoice_integration_method.py | 35 +++ l10n_es_facturae_face/models/config.py | 23 ++ l10n_es_facturae_face/models/res_company.py | 21 ++ l10n_es_facturae_face/models/res_partner.py | 32 +++ .../models/wsse_signature.py | 240 ++++++++++++++++++ l10n_es_facturae_face/tests/__init__.py | 4 + .../tests/test_facturae_face.py | 234 +++++++++++++++++ .../views/res_company_view.xml | 14 + .../views/res_config_views.xml | 16 ++ l10n_es_facturae_face/wizard/__init__.py | 4 + .../account_invoice_integration_cancel.py | 18 ++ ...ccount_invoice_integration_cancel_view.xml | 20 ++ 19 files changed, 1024 insertions(+) create mode 100644 l10n_es_facturae_face/README.rst create mode 100644 l10n_es_facturae_face/__init__.py create mode 100644 l10n_es_facturae_face/__manifest__.py create mode 100644 l10n_es_facturae_face/data/face_data.xml create mode 100644 l10n_es_facturae_face/models/__init__.py create mode 100644 l10n_es_facturae_face/models/account_invoice_integration.py create mode 100644 l10n_es_facturae_face/models/account_invoice_integration_log.py create mode 100644 l10n_es_facturae_face/models/account_invoice_integration_method.py create mode 100644 l10n_es_facturae_face/models/config.py create mode 100644 l10n_es_facturae_face/models/res_company.py create mode 100644 l10n_es_facturae_face/models/res_partner.py create mode 100644 l10n_es_facturae_face/models/wsse_signature.py create mode 100644 l10n_es_facturae_face/tests/__init__.py create mode 100644 l10n_es_facturae_face/tests/test_facturae_face.py create mode 100644 l10n_es_facturae_face/views/res_company_view.xml create mode 100644 l10n_es_facturae_face/views/res_config_views.xml create mode 100644 l10n_es_facturae_face/wizard/__init__.py create mode 100644 l10n_es_facturae_face/wizard/account_invoice_integration_cancel.py create mode 100644 l10n_es_facturae_face/wizard/account_invoice_integration_cancel_view.xml diff --git a/l10n_es_facturae_face/README.rst b/l10n_es_facturae_face/README.rst new file mode 100644 index 00000000000..9fff22e6dcb --- /dev/null +++ b/l10n_es_facturae_face/README.rst @@ -0,0 +1,76 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=============================================================== +Envío de la facturación electrónica española (Factura-E) a FACe +=============================================================== + +Este módulo permite la gestión del envío de la facturación electrónica española +a FACe. + +La gestión del envío se realiza mediante los certificados con los que se firma. + +Instalación +=========== + +Este módulo depende del módulo *l10n_es_facturae* y sus dependencias + +Es necesario tener instalado el módulo xmlsec y zeep en la versión que envía en +formato c14n. + +Configuración +============= + +* Es necesario añadir el correo electrónico al que notificar los cambios de + estado en la empresa +* Se debe configurar el servidor de envío +* Por defecto se añado el servicio web de test: + https://se-face-webservice.redsara.es/facturasspp2 +* Si queremos añadir el de producción, debemos cambiar el parámetro por + https://webservice.face.gob.es/facturasspp2 y modificar el certificado en + parámetros de sistema + +Uso +=== + +* Accedemos a un cliente y le configuramos la factura electrónica +* Accedemos a una factura validada del cliente y pulsamos el botón + 'Enviar a FACe' +* Podremos añadir adjuntos que al envío de la factura original +* Pulsamos 'Enviar' en el registro de envío a FACe +* Si el envío es correcto, nos mostrará el resultado y el número de registro +* Si el envío es correcto, podremos actualizar el estado de forma online +* Si el envío es correcto, podremos solicitar la anulación de la factura + pulsando 'Cancelar Envío' e introduciendo el motivo +* Un registro Enviado correctamente no puede ser Eliminado +* Sólo puede existir un envío Enviado correctamente +* Se genera una tarea programada que actualiza los registros enviados + correctamente no pagados y no anulados + +.. 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 + +Credits +======= + +Contributors +------------ + +* Enric Tobella + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/l10n_es_facturae_face/__init__.py b/l10n_es_facturae_face/__init__.py new file mode 100644 index 00000000000..55f67ffe148 --- /dev/null +++ b/l10n_es_facturae_face/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models +from . import wizard diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py new file mode 100644 index 00000000000..f1288253949 --- /dev/null +++ b/l10n_es_facturae_face/__manifest__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Envío de Factura-e a FACe", + "version": "10.0.1.0.0", + "author": "Creu Blanca, " + "Odoo Community Association (OCA)", + "category": "Accounting & Finance", + "website": "https://github.com/OCA/l10n-spain", + "license": "AGPL-3", + "depends": [ + "l10n_es_facturae", + ], + "data": [ + "data/face_data.xml", + "views/res_company_view.xml", + "views/res_config_views.xml", + "wizard/account_invoice_integration_cancel_view.xml" + ], + "external_dependencies": { + "python": [ + "OpenSSL", + "zeep", + "xmlsec" + ] + }, + "installable": True, +} diff --git a/l10n_es_facturae_face/data/face_data.xml b/l10n_es_facturae_face/data/face_data.xml new file mode 100644 index 00000000000..fef1505b4ef --- /dev/null +++ b/l10n_es_facturae_face/data/face_data.xml @@ -0,0 +1,62 @@ + + + + account.invoice.face.server + https://se-face-webservice.redsara.es/facturasspp2?wsdl + + + + account.invoice.face.certificate + face_certificate.crt + LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUYvVENDQk9XZ0F3SUJBZ0lRVWo1b2Z5N1RZ +WGhXc0tCWlZ6Nmx4REFOQmdrcWhraUc5dzBCQVFzRkFEQkgKTVFzd0NRWURWUVFHRXdKRlV6RVJN +QThHQTFVRUNnd0lSazVOVkMxU1EwMHhKVEFqQmdOVkJBc01IRUZESUVOdgpiWEJ2Ym1WdWRHVnpJ +RWx1Wm05eWJjT2hkR2xqYjNNd0hoY05NVFl3TWpBeU1USXlOakF4V2hjTk1Ua3dNakF5Ck1USXlO +VFU1V2pDQjJERUxNQWtHQTFVRUJoTUNSVk14RHpBTkJnTlZCQWNNQmsxQlJGSkpSREU4TURvR0Ex +VUUKQ2d3elRVbE9TVk5VUlZKSlR5QkVSU0JJUVVOSlJVNUVRU0JaSUVGRVRVbE9TVk5VVWtGRFNV +OU9SVk1nVU1PYQpRa3hKUTBGVE1Vc3dTUVlEVlFRTERFSkVTVkpGUTBOSnc1Tk9JRVJGSUZSRlEw +NVBURTlIdzQxQlV5QkVSU0JNClFTQkpUa1pQVWsxQlEwbkRrMDRnV1NCTVFWTWdRMDlOVlU1SlEw +RkRTVTlPUlZNeEVqQVFCZ05WQkFVVENWTXkKT0RNek1EQXlSVEVaTUJjR0ExVUVBd3dRUkZSSlF5 +QkJSMFVnVUZKVlJVSkJVekNDQVNJd0RRWUpLb1pJaHZjTgpBUUVCQlFBRGdnRVBBRENDQVFvQ2dn +RUJBTEJjb3V5NXdrMVAxTHdxMzhiK21WYlpmb3Fza1BCZXBhd2llSGFyClExTnJrSkpWK2hJWU9u +Z0dYLzREZHBvVUtyL2V6QXFyTml1MG1IMVd4UEkrZVJMc2UxbG9VYmp3UVRneG5KSTkKUVAwdjc5 +TDZnMFVxTHlGY3d5eTcvZEl4VmtKVUlxN3FQSFhianZsZ3U1ZkN3NnVCOGgwRVEySmxycEtmcXRk +awpoK2lwRG1VZmluYWdlTTExc01YRWViUytZeE8waWlxSzBXZ0hQRzI3ZFN6ZDBUZm8yU0tRL1hI +c2d1VHRySW9WCjRra3RHaGtiN0lFcE84K0c4UXpIZDM0N0hpUUF5L01ydXplTEFKamFCaGNZemtD +bU1GdzV4V2M3azZQQjBTODIKaGVGQjZSTis0UkdZUDE0OVZJTkdTUXJTMFdxSVhyWEpDSExRYjVj +N0hCZU5wbTBDQXdFQUFhT0NBbEV3Z2dKTgpNQWtHQTFVZEV3UUNNQUF3Z1lFR0NDc0dBUVVGQndF +QkJIVXdjekE3QmdnckJnRUZCUWN3QVlZdmFIUjBjRG92CkwyOWpjM0JqYjIxd0xtTmxjblF1Wm01 +dGRDNWxjeTl2WTNOd0wwOWpjM0JTWlhOd2IyNWtaWEl3TkFZSUt3WUIKQlFVSE1BS0dLR2gwZEhB +Nkx5OTNkM2N1WTJWeWRDNW1ibTEwTG1WekwyTmxjblJ6TDBGRFEwOU5VQzVqY25RdwpSQVlEVlIw +Z0JEMHdPekE1QmdvckJnRUVBYXhtQXdrQ01Dc3dLUVlJS3dZQkJRVUhBZ0VXSFdoMGRIQTZMeTkz +CmQzY3VZMlZ5ZEM1bWJtMTBMbVZ6TDJSd1kzTXZNQzRHQTFVZEVRUW5NQ1drSXpBaE1SOHdIUVlK +S3dZQkJBR3MKWmdFSURCQkVWRWxESUVGSFJTQlFVbFZGUWtGVE1CTUdBMVVkSlFRTU1Bb0dDQ3NH +QVFVRkJ3TUNNQTRHQTFVZApEd0VCL3dRRUF3SUVzREFkQmdOVkhRNEVGZ1FVbVVQYUNLUzFHWFVM +UnY3VFlHRk1HNkJ4bWNRd0h3WURWUjBqCkJCZ3dGb0FVR2ZoWUx4VFdwc3liQkpnSURVelhxd0Nu +ZzJVd2dlQUdBMVVkSHdTQjJEQ0IxVENCMHFDQno2Q0IKeklhQm5teGtZWEE2THk5c1pHRndZMjl0 +Y0M1alpYSjBMbVp1YlhRdVpYTXZRMDQ5UTFKTU1TeFBWVDFCUXlVeQpNRU52YlhCdmJtVnVkR1Z6 +SlRJd1NXNW1iM0p0WVhScFkyOXpMRTg5Ums1TlZDMVNRMDBzUXoxRlV6OWpaWEowCmFXWnBZMkYw +WlZKbGRtOWpZWFJwYjI1TWFYTjBPMkpwYm1GeWVUOWlZWE5sUDI5aWFtVmpkR05zWVhOelBXTlMK +VEVScGMzUnlhV0oxZEdsdmJsQnZhVzUwaGlsb2RIUndPaTh2ZDNkM0xtTmxjblF1Wm01dGRDNWxj +eTlqY214egpZMjl0Y0M5RFVrd3hMbU55YkRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQVRsWjNE +UEZ6MWdRMzJZT1lJSUx6CmY5OWt1azJ3RllVTGcrWGFEcWlzL3kvUzZicGhLRjN4YnR5eHNJWCts +eDB6STE3ZHlEVEtBKzZzV05IaWl1SDQKWWpYa3FieGJJOEVZSGZlUnpiUkszUzRHajF5YXRHVnRo +c0NLNndEcmxyOFJyajhRZ250RkFNKy9rZnlzR0psSApFaUZzZ1ROMmlYZk9zam1YTk5LMUx3U2JR +M0dDd1BhTFlLWm9uTnNFajhQL1M1cjkxSUNlamZHbFZacDFBRVh5ClAzakp6aWJyMFNLeHdFdDMy +ci8rWmpUbVFnckx1QW1HcmdjVnNqQUFtMkNwN3VzSllhUy9TeVBGajFRRFVsWm8KVk91bzRkZmdG +VVpMQ1ZCZk1VQlk3M1dOYXpWQW9qcVpoRzlkOHRBZ2cyYzY0bnVzdU1EWSsyNU1MVUtGenNiegpG +Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCg== + + + + Integration FACe + account.invoice.integration.face + FACe + 8 + + + FACe + FACe + + + diff --git a/l10n_es_facturae_face/models/__init__.py b/l10n_es_facturae_face/models/__init__.py new file mode 100644 index 00000000000..1be2b8d07df --- /dev/null +++ b/l10n_es_facturae_face/models/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import res_partner +from . import res_company +from . import config +from . import account_invoice_integration_method +from . import account_invoice_integration +from . import account_invoice_integration_log diff --git a/l10n_es_facturae_face/models/account_invoice_integration.py b/l10n_es_facturae_face/models/account_invoice_integration.py new file mode 100644 index 00000000000..686670958b6 --- /dev/null +++ b/l10n_es_facturae_face/models/account_invoice_integration.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from odoo import models, fields + + +class AccountInvoiceIntegration(models.Model): + _inherit = "account.invoice.integration" + + integration_status = fields.Selection(selection_add=[ + ('face-1200', 'Registered on REC'), + ('face-1300', 'Registered on RCF'), + ('face-2400', 'Accepted'), + ('face-2500', 'Payed'), + ('face-2600', 'Rejected'), + ('face-3100', 'Cancellation approved'), + ]) + cancellation_status = fields.Selection(selection_add=[ + ('face-4100', 'Not requested'), + ('face-4200', 'Cancellation requested'), + ('face-4300', 'Cancellation accepted'), + ('face-4400', 'Cancellation rejected'), + ]) diff --git a/l10n_es_facturae_face/models/account_invoice_integration_log.py b/l10n_es_facturae_face/models/account_invoice_integration_log.py new file mode 100644 index 00000000000..e4dcfb1212b --- /dev/null +++ b/l10n_es_facturae_face/models/account_invoice_integration_log.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from odoo import models +import base64 +import logging +from .wsse_signature import MemorySignature +try: + from OpenSSL import crypto + from zeep import Client +except (ImportError, IOError) as err: + logging.info(err) + +ns = "https://ssweb.seap.minhap.es/web-service-test-face/sspp" + + +class AccountInvoiceIntegration(models.Model): + _inherit = "account.invoice.integration.log" + + def update_method(self): + if self.integration_id.method_id == self.env.ref( + 'l10n_es_facturae_face.integration_face'): + invoice = self.integration_id.invoice_id + cert = crypto.load_pkcs12( + base64.b64decode(invoice.company_id.facturae_cert), + invoice.company_id.facturae_cert_password + ) + cert.set_ca_certificates(None) + client = Client( + wsdl=self.env["ir.config_parameter"].get_param( + "account.invoice.face.server", default=None), + wsse=MemorySignature( + cert.export(), + base64.b64decode( + self.env.ref( + 'l10n_es_facturae_face.face_certificate').datas + ), + ) + ) + response = client.service.consultarFactura( + self.integration_id.register_number + ) + self.result_code = response.resultado.codigo + self.log = response.resultado.descripcion + if self.result_code == '0': + self.state = 'sent' + factura = response.factura + integ = self.integration_id + integ.integration_status = 'face-' + factura.tramitacion.codigo + integ.integration_description = factura.tramitacion.motivo + integ.cancellation_status = 'face-' + factura.anulacion.codigo + integ.cancellation_description = factura.anulacion.motivo + if integ.cancellation_status != 'face-4100': + integ.can_cancel = False + else: + self.state = 'failed' + return + return super(AccountInvoiceIntegration, self).update_method() + + def cancel_method(self): + if self.integration_id.method_id == self.env.ref( + 'l10n_es_facturae_face.integration_face'): + invoice = self.integration_id.invoice_id + cert = crypto.load_pkcs12( + base64.b64decode(invoice.company_id.facturae_cert), + invoice.company_id.facturae_cert_password + ) + cert.set_ca_certificates(None) + client = Client( + wsdl=self.env["ir.config_parameter"].get_param( + "account.invoice.face.server", default=None), + wsse=MemorySignature( + cert.export(), + base64.b64decode( + self.env.ref( + 'l10n_es_facturae_face.face_certificate').datas + ) + ) + ) + response = client.service.anularFactura( + self.integration_id.register_number, + self.cancellation_motive + ) + self.result_code = response.resultado.codigo + self.log = response.resultado.descripcion + if self.result_code == '0': + self.state = 'sent' + self.integration_id.state = 'cancelled' + self.integration_id.can_cancel = False + else: + self.state = 'failed' + return + return super(AccountInvoiceIntegration, self).cancel_method() + + def send_method(self): + if self.integration_id.method_id == self.env.ref( + 'l10n_es_facturae_face.integration_face'): + invoice = self.integration_id.invoice_id + cert = crypto.load_pkcs12( + base64.b64decode(invoice.company_id.facturae_cert), + invoice.company_id.facturae_cert_password + ) + cert.set_ca_certificates(None) + client = Client( + wsdl=self.env["ir.config_parameter"].get_param( + "account.invoice.face.server", default=None), + wsse=MemorySignature( + cert.export(), + base64.b64decode( + self.env.ref( + 'l10n_es_facturae_face.face_certificate').datas + ) + ) + ) + invoice_file = client.get_type('ns0:FacturaFile')( + self.integration_id.attachment_id.datas, + self.integration_id.attachment_id.datas_fname, + self.integration_id.attachment_id.mimetype + ) + anexos_list = [] + if self.integration_id.attachment_ids: + for attachment in self.attachment_ids: + anexo = client.get_type('ns0:AnexoFile')( + attachment.datas, + attachment.datas_fname, + attachment.mimetype + ) + anexos_list.append(anexo) + anexos = client.get_type('ns0:ArrayOfAnexoFile')( + anexos_list + ) + invoice_call = client.get_type('ns0:EnviarFacturaRequest')( + invoice.company_id.face_email, + invoice_file, + anexos + ) + response = client.service.enviarFactura( + invoice_call + ) + self.result_code = response.resultado.codigo + self.log = response.resultado.descripcion + if self.result_code == '0': + self.state = 'sent' + integ = self.integration_id + integ.register_number = response.factura.numeroRegistro + integ.state = 'sent' + integ.can_cancel = True + integ.can_update = True + integ.can_send = False + else: + self.integration_id.state = 'failed' + self.state = 'failed' + return + return super(AccountInvoiceIntegration, self).send_method() diff --git a/l10n_es_facturae_face/models/account_invoice_integration_method.py b/l10n_es_facturae_face/models/account_invoice_integration_method.py new file mode 100644 index 00000000000..3d5785e90a5 --- /dev/null +++ b/l10n_es_facturae_face/models/account_invoice_integration_method.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from odoo import models, exceptions, _ +import base64 + + +class AccountInvoiceIntegrationMethod(models.Model): + _inherit = "account.invoice.integration.method" + + # Default values for integration. It could be extended + def integration_values(self, invoice): + res = super(AccountInvoiceIntegrationMethod, self).integration_values( + invoice + ) + if self.code == 'FACe': + if not invoice.company_id.facturae_cert: + raise exceptions.UserError( + _('Certificate must be added for company')) + if not invoice.company_id.facturae_cert_password: + raise exceptions.UserError( + _('Certificate password must be added for company')) + invoice_file, file_name = invoice.get_facturae(True) + attachment = self.env['ir.attachment'].create({ + 'name': file_name, + 'datas': base64.b64encode(invoice_file), + 'datas_fname': file_name, + 'res_model': 'account.invoice', + 'res_id': invoice.id, + 'mimetype': 'application/xml' + }) + res['attachment_id'] = attachment.id + return res diff --git a/l10n_es_facturae_face/models/config.py b/l10n_es_facturae_face/models/config.py new file mode 100644 index 00000000000..567315e6bf4 --- /dev/null +++ b/l10n_es_facturae_face/models/config.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models, fields, api + + +class AccountConfigSettings(models.TransientModel): + _inherit = 'account.config.settings' + + face_server = fields.Char(string="FACe server location") + + @api.model + def get_default_face_server(self, fields): + face_server = self.env["ir.config_parameter"].get_param( + "account.invoice.face.server", default=None) + return {'face_server': face_server or False} + + @api.multi + def set_face_server(self): + for record in self: + self.env['ir.config_parameter'].set_param( + "account.invoice.face.server", record.face_server or '') diff --git a/l10n_es_facturae_face/models/res_company.py b/l10n_es_facturae_face/models/res_company.py new file mode 100644 index 00000000000..e9b5e198443 --- /dev/null +++ b/l10n_es_facturae_face/models/res_company.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError +import re + + +class ResCompany(models.Model): + _inherit = 'res.company' + + face_email = fields.Char() + + @api.constrains('face_email') + def check_face_email(self): + for record in self: + if not re.match( + '(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$)', + record.face_email): + raise ValidationError(_('Invalid facturae email')) diff --git a/l10n_es_facturae_face/models/res_partner.py b/l10n_es_facturae_face/models/res_partner.py new file mode 100644 index 00000000000..60f6ebc065e --- /dev/null +++ b/l10n_es_facturae_face/models/res_partner.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from odoo import models, api, exceptions, _ + + +class ResPartner(models.Model): + _inherit = "res.partner" + + @api.constrains('facturae', 'vat', 'country_id', 'state_id', + 'invoice_integration_method_ids') + def constrain_face(self): + face = self.env.ref('l10n_es_facturae_face.integration_face') + for record in self.filtered( + lambda x: face in x.invoice_integration_method_ids): + if not record.facturae: + raise exceptions.ValidationError( + _('Facturae must be selected in order to send to FACe') + ) + if not record.vat: + raise exceptions.ValidationError( + _('Vat must be defined in order to send to FACe')) + if not record.country_id: + raise exceptions.ValidationError( + _('Country must be defined in order to send to FACe')) + if record.country_id.code_alpha3 == 'ESP': + if not record.state_id: + raise exceptions.ValidationError( + _('State must be defined in Spain in order to ' + 'send to FACe')) diff --git a/l10n_es_facturae_face/models/wsse_signature.py b/l10n_es_facturae_face/models/wsse_signature.py new file mode 100644 index 00000000000..9a4ac1bead9 --- /dev/null +++ b/l10n_es_facturae_face/models/wsse_signature.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +"""Functions for WS-Security (WSSE) signature creation and verification. + +Heavily based on test examples in https://github.com/mehcode/python-xmlsec as +well as the xmlsec documentation at https://www.aleksey.com/xmlsec/. + +Reading the xmldsig, xmlenc, and ws-security standards documents, though +admittedly painful, will likely assist in understanding the code in this +module. + +""" +from lxml import etree +from lxml.etree import QName +import logging +try: + from zeep import ns + from zeep.exceptions import SignatureVerificationFailed + from zeep.utils import detect_soap_env + from zeep.wsse.utils import ensure_id, get_security_header + from OpenSSL import crypto +except (ImportError, IOError) as err: + logging.info(err) +import base64 +from datetime import datetime, timedelta + +try: + import xmlsec +except ImportError: + xmlsec = None + +# SOAP envelope +SOAP_NS = 'http://schemas.xmlsoap.org/soap/envelope/' + + +def _read_file(f_name): + with open(f_name, "rb") as f: + return f.read() + + +def _make_sign_key(key_data, cert_data, password): + key = xmlsec.Key.from_memory(key_data, + xmlsec.KeyFormat.PKCS12_PEM, password) + return key + + +def _make_verify_key(cert_data): + key = xmlsec.Key.from_memory(cert_data, + xmlsec.KeyFormat.CERT_PEM, None) + return key + + +class MemorySignature(object): + """Sign given SOAP envelope with WSSE sig using given key and cert.""" + + def __init__(self, key_data, cert_data, password=None): + check_xmlsec_import() + + self.key_data = key_data + self.cert_data = cert_data + self.password = password + + def apply(self, envelope, headers): + signed = sign_envelope(envelope, self.key_data, self.cert_data, + self.password) + return signed, headers + + def verify(self, envelope): + key = _make_verify_key(self.cert_data) + _verify_envelope_with_key(envelope, key) + return envelope + + +class Signature(MemorySignature): + """Sign given SOAP envelope with WSSE sig using given key file and + cert file.""" + + def __init__(self, key_file, certfile, password=None): + super(Signature, self).__init__(_read_file(key_file), + _read_file(certfile), + password) + + +def check_xmlsec_import(): + if xmlsec is None: + raise ImportError( + "The xmlsec module is required for wsse.Signature()\n" + + "You can install xmlsec with: pip install xmlsec\n" + + "or install zeep via: pip install zeep[xmlsec]\n" + ) + + +def sign_envelope(envelope, keyfile, certfile, password=None): + key = _make_sign_key(keyfile, certfile, password) + reference_id = 'Reference' + security = get_security_header(envelope) + security.set(QName(ns.SOAP_ENV_11, 'mustUnderstand'), '1') + x509type = 'http://docs.oasis-open.org/wss/2004/01/' \ + 'oasis-200401-wss-x509-token-profile-1.0#X509v3' + encoding_type = "http://docs.oasis-open.org/wss/2004/01/" \ + "oasis-200401-wss-soap-message-security-1.0#Base64Binary" + binary_token = etree.SubElement( + security, + QName(ns.WSSE, 'BinarySecurityToken'), + attrib={ + QName(ns.WSU, 'Id'): reference_id, + 'ValueType': x509type, + 'EncodingType': encoding_type + } + ) + binary_token.text = base64.b64encode( + crypto.dump_certificate( + crypto.FILETYPE_ASN1, + crypto.load_pkcs12(keyfile, password).get_certificate() + ) + ) + signature = xmlsec.template.create( + envelope, + xmlsec.Transform.EXCL_C14N, + xmlsec.Transform.RSA_SHA1, + ns='ds' + ) + + # Add a KeyInfo node with X509Data child to the Signature. XMLSec will fill + # in this template with the actual certificate details when it signs. + key_info = xmlsec.template.ensure_key_info(signature) + sec_token_ref = etree.SubElement( + key_info, QName(ns.WSSE, 'SecurityTokenReference')) + etree.SubElement( + sec_token_ref, + QName(ns.WSSE, 'Reference'), + attrib={ + 'URI': '#' + reference_id, + 'ValueType': x509type + } + ) + # Insert the Signature node in the wsse:Security header. + + security.append(signature) + + # Perform the actual signing. + ctx = xmlsec.SignatureContext() + ctx.key = key + + timestamp = etree.SubElement(security, QName(ns.WSU, 'Timestamp')) + now = datetime.now() + etree.SubElement(timestamp, QName(ns.WSU, 'Created')).text = now.strftime( + '%Y-%m-%dT%H:%M:%SZ' + ) + exp = now + timedelta(hours=1) + etree.SubElement(timestamp, QName(ns.WSU, 'Expires')).text = exp.strftime( + '%Y-%m-%dT%H:%M:%SZ' + ) + + soap_env = detect_soap_env(envelope) + _sign_node(ctx, signature, envelope.find(QName(soap_env, 'Body'))) + _sign_node(ctx, signature, security.find(QName(ns.WSU, 'Timestamp'))) + + ctx.sign(signature) + return etree.fromstring(etree.tostring(envelope, method='c14n')) + + +def verify_envelope(envelope, certfile): + """Verify WS-Security signature on given SOAP envelope with given cert. + + Expects a document like that found in the sample XML in the ``sign()`` + docstring. + + Raise SignatureVerificationFailed on failure, silent on success. + + """ + key = _make_verify_key(_read_file(certfile)) + return _verify_envelope_with_key(envelope, key) + + +def _verify_envelope_with_key(envelope, key): + soap_env = detect_soap_env(envelope) + + header = envelope.find(QName(soap_env, 'Header')) + if not header: + raise SignatureVerificationFailed() + + security = header.find(QName(ns.WSSE, 'Security')) + signature = security.find(QName(ns.DS, 'Signature')) + + ctx = xmlsec.SignatureContext() + + # Find each signed element and register its ID with the signing context. + refs = signature.xpath( + 'ds:SignedInfo/ds:Reference', namespaces={'ds': ns.DS}) + for ref in refs: + # Get the reference URI and cut off the initial '#' + referenced_id = ref.get('URI')[1:] + referenced = envelope.xpath( + "//*[@wsu:Id='%s']" % referenced_id, + namespaces={'wsu': ns.WSU}, + )[0] + ctx.register_id(referenced, 'Id', ns.WSU) + + ctx.key = key + + try: + ctx.verify(signature) + except xmlsec.Error: + # Sadly xmlsec gives us no details about the reason for the failure, so + # we have nothing to pass on except that verification failed. + raise SignatureVerificationFailed() + + +def _sign_node(ctx, signature, target): + """Add sig for ``target`` in ``signature`` node, using ``ctx`` context. + + Doesn't actually perform the signing; ``ctx.sign(signature)`` should be + called later to do that. + + Adds a Reference node to the signature with URI attribute pointing to the + target node, and registers the target node's ID so XMLSec will be able to + find the target node by ID when it signs. + + """ + + # Ensure the target node has a wsu:Id attribute and get its value. + node_id = ensure_id(target) + + # Unlike HTML, XML doesn't have a single standardized Id. WSSE suggests the + # use of the wsu:Id attribute for this purpose, but XMLSec doesn't + # understand that natively. So for XMLSec to be able to find the referenced + # node by id, we have to tell xmlsec about it using the register_id method. + ctx.register_id(target, 'Id', ns.WSU) + + # Add reference to signature with URI attribute pointing to that ID. + ref = xmlsec.template.add_reference( + signature, xmlsec.Transform.SHA1, uri='#' + node_id) + # This is an XML normalization transform which will be performed on the + # target node contents before signing. This ensures that changes to + # irrelevant whitespace, attribute ordering, etc won't invalidate the + # signature. + xmlsec.template.add_transform(ref, xmlsec.Transform.EXCL_C14N) diff --git a/l10n_es_facturae_face/tests/__init__.py b/l10n_es_facturae_face/tests/__init__.py new file mode 100644 index 00000000000..65b006bc914 --- /dev/null +++ b/l10n_es_facturae_face/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_facturae_face diff --git a/l10n_es_facturae_face/tests/test_facturae_face.py b/l10n_es_facturae_face/tests/test_facturae_face.py new file mode 100644 index 00000000000..086144f6348 --- /dev/null +++ b/l10n_es_facturae_face/tests/test_facturae_face.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +# © 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import base64 + +from odoo import exceptions +from odoo.tests import common +import logging +import mock +try: + from zeep import Client + from OpenSSL import crypto +except (ImportError, IOError) as err: + logging.info(err) + + +class TestL10nEsFacturaeFACe(common.TransactionCase): + def setUp(self): + super(TestL10nEsFacturaeFACe, self).setUp() + pkcs12 = crypto.PKCS12() + pkey = crypto.PKey() + pkey.generate_key(crypto.TYPE_RSA, 512) + x509 = crypto.X509() + x509.set_pubkey(pkey) + x509.set_serial_number(0) + x509.get_subject().CN = "me" + x509.set_issuer(x509.get_subject()) + x509.gmtime_adj_notBefore(0) + x509.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60) + x509.sign(pkey, 'md5') + pkcs12.set_privatekey(pkey) + pkcs12.set_certificate(x509) + main_company = self.env.ref('base.main_company') + main_company.facturae_cert = base64.b64encode( + pkcs12.export(passphrase='password')) + main_company.facturae_cert_password = 'password' + self.tax = self.env['account.tax'].create({ + 'name': 'Test tax', + 'amount_type': 'percent', + 'amount': 21, + 'type_tax_use': 'sale', + 'facturae_code': '01', + }) + self.state = self.env['res.country.state'].create({ + 'name': 'Ciudad Real', + 'code': '13', + 'country_id': self.ref('base.es'), + }) + self.partner = self.env['res.partner'].create({ + 'name': 'Cliente de prueba', + 'street': 'C/ Ejemplo, 13', + 'zip': '13700', + 'city': 'Tomelloso', + 'state_id': self.state.id, + 'country_id': self.ref('base.es'), + 'vat': 'ES05680675C', + 'facturae': True, + 'organo_gestor': 'U00000038', + 'unidad_tramitadora': 'U00000038', + 'oficina_contable': 'U00000038', + 'invoice_integration_method_ids': [(6, 0, [ + self.env.ref('l10n_es_facturae_face.integration_face').id + ])] + }) + main_company.vat = "ESA12345674" + main_company.partner_id.country_id = self.ref('base.uk') + main_company.currency_id = self.ref('base.EUR') + bank_obj = self.env['res.partner.bank'] + self.bank = bank_obj.search([ + ('acc_number', '=', 'BE96 9988 7766 5544')], limit=1) + if not self.bank: + self.bank = bank_obj.create({ + 'state': 'iban', + 'acc_number': 'BE96 9988 7766 5544', + 'partner_id': self.partner.id, + 'bank_id': self.env['res.bank'].search( + [('bic', '=', 'PSSTFRPPXXX')], limit=1).id + }) + self.mandate = self.env['account.banking.mandate'].create({ + 'company_id': main_company.id, + 'format': 'basic', + 'partner_id': self.partner.id, + 'state': 'valid', + 'partner_bank_id': self.bank.id, + 'signature_date': '2016-03-12', + }) + self.payment_method = self.env['account.payment.method'].create({ + 'name': 'inbound_mandate', + 'code': 'inbound_mandate', + 'payment_type': 'inbound', + 'bank_account_required': False, + 'mandate_required': True, + 'active': True + }) + payment_methods = self.env['account.payment.method'].search([ + ('payment_type', '=', 'inbound') + ]) + self.journal = self.env['account.journal'].create({ + 'name': 'Test journal', + 'code': 'TEST', + 'type': 'bank', + 'company_id': main_company.id, + 'inbound_payment_method_ids': [(6, 0, payment_methods.ids)] + }) + self.payment_mode = self.env['account.payment.mode'].create({ + 'name': 'Test payment mode', + 'bank_account_link': 'fixed', + 'fixed_journal_id': self.journal.id, + 'payment_method_id': self.env.ref( + 'payment.account_payment_method_electronic_in').id, + 'facturae_code': '01', + }) + self.payment_mode_02 = self.env['account.payment.mode'].create({ + 'name': 'Test payment mode 02', + 'bank_account_link': 'fixed', + 'fixed_journal_id': self.journal.id, + 'payment_method_id': self.payment_method.id, + 'facturae_code': '02', + }) + account = self.env['account.account'].create({ + 'company_id': main_company.id, + 'name': 'Facturae Product account', + 'code': 'facturae_product', + 'user_type_id': self.env.ref( + 'account.data_account_type_revenue').id + }) + self.invoice = self.env['account.invoice'].create({ + 'partner_id': self.partner.id, + 'account_id': self.partner.property_account_receivable_id.id, + 'journal_id': self.journal.id, + 'date_invoice': '2016-03-12', + 'partner_bank_id': self.bank.id, + 'payment_mode_id': self.payment_mode.id + }) + self.invoice_line = self.env['account.invoice.line'].create({ + 'product_id': self.env.ref('product.product_delivery_02').id, + 'account_id': account.id, + 'invoice_id': self.invoice.id, + 'name': 'Producto de prueba', + 'quantity': 1.0, + 'price_unit': 100.0, + 'invoice_line_tax_ids': [(6, 0, self.tax.ids)], + }) + self.invoice._onchange_invoice_line_ids() + self.invoice.action_invoice_open() + self.invoice.number = '2999/99998' + + def test_facturae_face(self): + class DemoService(object): + def __init__(self, value): + self.value = value + + def enviarFactura(self, *args): + return self.value + + def anularFactura(self, *args): + return self.value + + def consultarFactura(self, *args): + return self.value + + main_company = self.env.ref('base.main_company') + with self.assertRaises(exceptions.ValidationError): + main_company.face_email = 'test' + main_company.face_email = 'test@test.com' + self.invoice.action_integrations() + integration = self.env['account.invoice.integration'].search([ + ('invoice_id', '=', self.invoice.id) + ]) + self.assertEqual(integration.method_id.code, "FACe") + self.assertEqual(integration.can_send, True) + client = Client( + wsdl=self.env["ir.config_parameter"].get_param( + "account.invoice.face.server", default=None) + ) + integration.send_action() + self.assertEqual(integration.state, 'failed') + integration_code = '1234567890' + response_ok = client.get_type('ns0:EnviarFacturaResponse')( + client.get_type('ns0:Resultado')( + codigo='0', + descripcion='OK' + ), + client.get_type('ns0:EnviarFactura')( + numeroRegistro=integration_code + ) + ) + with mock.patch('zeep.client.ServiceProxy') as mock_client: + mock_client.return_value = DemoService(response_ok) + integration.send_action() + self.assertEqual(integration.register_number, integration_code) + self.assertEqual(integration.state, 'sent') + response_update = client.get_type('ns0:ConsultarFacturaResponse')( + client.get_type('ns0:Resultado')( + codigo='0', + descripcion='OK' + ), + client.get_type('ns0:ConsultarFactura')( + '1234567890', + client.get_type('ns0:EstadoFactura')( + '1200', + 'DESC', + 'MOTIVO' + ), + client.get_type('ns0:EstadoFactura')( + '4100', + 'DESC', + 'MOTIVO' + ) + ) + ) + with mock.patch('zeep.client.ServiceProxy') as mock_client: + mock_client.return_value = DemoService(response_update) + integration.update_action() + self.assertEqual(integration.integration_status, 'face-1200') + response_cancel = client.get_type('ns0:ConsultarFacturaResponse')( + client.get_type('ns0:Resultado')( + '0', + 'OK' + ), + client.get_type('ns0:AnularFactura')( + '1234567890', + 'ANULADO' + ) + ) + with mock.patch('zeep.client.ServiceProxy') as mock_client: + mock_client.return_value = DemoService(response_cancel) + cancel = self.env['account.invoice.integration.cancel'].create({ + 'integration_id': integration.id, + 'motive': 'Anulacion' + }) + cancel.cancel_integration() + self.assertEqual(integration.state, 'cancelled') diff --git a/l10n_es_facturae_face/views/res_company_view.xml b/l10n_es_facturae_face/views/res_company_view.xml new file mode 100644 index 00000000000..af88864d481 --- /dev/null +++ b/l10n_es_facturae_face/views/res_company_view.xml @@ -0,0 +1,14 @@ + + + + res.company.form + res.company + + form + + + + + + + diff --git a/l10n_es_facturae_face/views/res_config_views.xml b/l10n_es_facturae_face/views/res_config_views.xml new file mode 100644 index 00000000000..edfed2d2aad --- /dev/null +++ b/l10n_es_facturae_face/views/res_config_views.xml @@ -0,0 +1,16 @@ + + + + Account Settings + account.config.settings + + + + + + + + + + diff --git a/l10n_es_facturae_face/wizard/__init__.py b/l10n_es_facturae_face/wizard/__init__.py new file mode 100644 index 00000000000..eb6be7580be --- /dev/null +++ b/l10n_es_facturae_face/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import account_invoice_integration_cancel diff --git a/l10n_es_facturae_face/wizard/account_invoice_integration_cancel.py b/l10n_es_facturae_face/wizard/account_invoice_integration_cancel.py new file mode 100644 index 00000000000..8dba0349809 --- /dev/null +++ b/l10n_es_facturae_face/wizard/account_invoice_integration_cancel.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models, fields + + +class AccountInvoiceIntegrationCancel(models.TransientModel): + _inherit = 'account.invoice.integration.cancel' + _description = 'Cancels a created integration' + + motive = fields.Char() + method_code = fields.Char(related='integration_id.method_id.code') + + def cancel_values(self): + res = super(AccountInvoiceIntegrationCancel, self).cancel_values() + if self.method_code == 'FACe': + res['cancellation_motive'] = self.motive + return res diff --git a/l10n_es_facturae_face/wizard/account_invoice_integration_cancel_view.xml b/l10n_es_facturae_face/wizard/account_invoice_integration_cancel_view.xml new file mode 100644 index 00000000000..dcff454f040 --- /dev/null +++ b/l10n_es_facturae_face/wizard/account_invoice_integration_cancel_view.xml @@ -0,0 +1,20 @@ + + + + + account.invoice.integration.cancel.form + account.invoice.integration.cancel + + + + + + + + + + From ab06ad70ed96fccfd8bbb0c936170a7ad3d94135 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Fri, 29 Dec 2017 11:46:14 +0100 Subject: [PATCH 002/101] [MIG] l10n_es_facturae_face: Migration to 11.0 --- l10n_es_facturae_face/README.rst | 4 +- l10n_es_facturae_face/__init__.py | 3 +- l10n_es_facturae_face/__manifest__.py | 5 +-- l10n_es_facturae_face/data/face_data.xml | 2 - l10n_es_facturae_face/models/__init__.py | 3 +- .../models/account_invoice_integration.py | 3 +- .../models/account_invoice_integration_log.py | 3 +- .../account_invoice_integration_method.py | 3 +- l10n_es_facturae_face/models/config.py | 21 +++++----- l10n_es_facturae_face/models/res_company.py | 3 +- l10n_es_facturae_face/models/res_partner.py | 3 +- .../models/wsse_signature.py | 3 +- .../static/description/icon.png | Bin 0 -> 2984 bytes l10n_es_facturae_face/tests/__init__.py | 3 +- .../tests/test_facturae_face.py | 3 +- .../views/res_config_views.xml | 36 ++++++++++++------ l10n_es_facturae_face/wizard/__init__.py | 2 +- .../account_invoice_integration_cancel.py | 2 +- 18 files changed, 51 insertions(+), 51 deletions(-) create mode 100644 l10n_es_facturae_face/static/description/icon.png diff --git a/l10n_es_facturae_face/README.rst b/l10n_es_facturae_face/README.rst index 9fff22e6dcb..fdbf6765fe5 100644 --- a/l10n_es_facturae_face/README.rst +++ b/l10n_es_facturae_face/README.rst @@ -1,5 +1,5 @@ .. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 =============================================================== @@ -50,7 +50,7 @@ Uso .. 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 + :target: https://runbot.odoo-community.org/runbot/189/11.0 Credits ======= diff --git a/l10n_es_facturae_face/__init__.py b/l10n_es_facturae_face/__init__.py index 55f67ffe148..25aa51eca4c 100644 --- a/l10n_es_facturae_face/__init__.py +++ b/l10n_es_facturae_face/__init__.py @@ -1,5 +1,4 @@ -# -*- coding: utf-8 -*- -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from . import models from . import wizard diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index f1288253949..4893768133f 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -1,10 +1,9 @@ -# -*- coding: utf-8 -*- # © 2017 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { "name": "Envío de Factura-e a FACe", - "version": "10.0.1.0.0", + "version": "11.0.1.0.0", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", diff --git a/l10n_es_facturae_face/data/face_data.xml b/l10n_es_facturae_face/data/face_data.xml index fef1505b4ef..71b799f8b5f 100644 --- a/l10n_es_facturae_face/data/face_data.xml +++ b/l10n_es_facturae_face/data/face_data.xml @@ -3,7 +3,6 @@ account.invoice.face.server https://se-face-webservice.redsara.es/facturasspp2?wsdl - account.invoice.face.certificate @@ -46,7 +45,6 @@ M0dDd1BhTFlLWm9uTnNFajhQL1M1cjkxSUNlamZHbFZacDFBRVh5ClAzakp6aWJyMFNLeHdFdDMy ci8rWmpUbVFnckx1QW1HcmdjVnNqQUFtMkNwN3VzSllhUy9TeVBGajFRRFVsWm8KVk91bzRkZmdG VVpMQ1ZCZk1VQlk3M1dOYXpWQW9qcVpoRzlkOHRBZ2cyYzY0bnVzdU1EWSsyNU1MVUtGenNiegpG Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCg== - Integration FACe diff --git a/l10n_es_facturae_face/models/__init__.py b/l10n_es_facturae_face/models/__init__.py index 1be2b8d07df..d8b9ceec3f3 100644 --- a/l10n_es_facturae_face/models/__init__.py +++ b/l10n_es_facturae_face/models/__init__.py @@ -1,5 +1,4 @@ -# -*- coding: utf-8 -*- -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from . import res_partner from . import res_company diff --git a/l10n_es_facturae_face/models/account_invoice_integration.py b/l10n_es_facturae_face/models/account_invoice_integration.py index 686670958b6..90b98323bc8 100644 --- a/l10n_es_facturae_face/models/account_invoice_integration.py +++ b/l10n_es_facturae_face/models/account_invoice_integration.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- # © 2017 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import models, fields diff --git a/l10n_es_facturae_face/models/account_invoice_integration_log.py b/l10n_es_facturae_face/models/account_invoice_integration_log.py index e4dcfb1212b..c325e87e328 100644 --- a/l10n_es_facturae_face/models/account_invoice_integration_log.py +++ b/l10n_es_facturae_face/models/account_invoice_integration_log.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- # © 2017 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import models diff --git a/l10n_es_facturae_face/models/account_invoice_integration_method.py b/l10n_es_facturae_face/models/account_invoice_integration_method.py index 3d5785e90a5..7d6b1f17b6c 100644 --- a/l10n_es_facturae_face/models/account_invoice_integration_method.py +++ b/l10n_es_facturae_face/models/account_invoice_integration_method.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- # © 2017 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import models, exceptions, _ diff --git a/l10n_es_facturae_face/models/config.py b/l10n_es_facturae_face/models/config.py index 567315e6bf4..094ec27b8c5 100644 --- a/l10n_es_facturae_face/models/config.py +++ b/l10n_es_facturae_face/models/config.py @@ -1,23 +1,24 @@ -# -*- coding: utf-8 -*- # © 2017 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import models, fields, api -class AccountConfigSettings(models.TransientModel): - _inherit = 'account.config.settings' +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' face_server = fields.Char(string="FACe server location") @api.model - def get_default_face_server(self, fields): + def get_values(self): + res = super(ResConfigSettings, self).get_values() face_server = self.env["ir.config_parameter"].get_param( "account.invoice.face.server", default=None) - return {'face_server': face_server or False} + res.update(face_server=face_server) + return res @api.multi - def set_face_server(self): - for record in self: - self.env['ir.config_parameter'].set_param( - "account.invoice.face.server", record.face_server or '') + def set_values(self): + super(ResConfigSettings, self).set_values() + self.env['ir.config_parameter'].sudo().set_param( + "account.invoice.face.server", self.face_server or '') diff --git a/l10n_es_facturae_face/models/res_company.py b/l10n_es_facturae_face/models/res_company.py index e9b5e198443..084fcbfcaa6 100644 --- a/l10n_es_facturae_face/models/res_company.py +++ b/l10n_es_facturae_face/models/res_company.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- # © 2017 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import models, fields, api, _ from odoo.exceptions import ValidationError diff --git a/l10n_es_facturae_face/models/res_partner.py b/l10n_es_facturae_face/models/res_partner.py index 60f6ebc065e..879ce149e71 100644 --- a/l10n_es_facturae_face/models/res_partner.py +++ b/l10n_es_facturae_face/models/res_partner.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- # © 2017 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import models, api, exceptions, _ diff --git a/l10n_es_facturae_face/models/wsse_signature.py b/l10n_es_facturae_face/models/wsse_signature.py index 9a4ac1bead9..fa578cf6b7e 100644 --- a/l10n_es_facturae_face/models/wsse_signature.py +++ b/l10n_es_facturae_face/models/wsse_signature.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- # © 2017 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). """Functions for WS-Security (WSSE) signature creation and verification. diff --git a/l10n_es_facturae_face/static/description/icon.png b/l10n_es_facturae_face/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5265804804de49543a4d759a870069e16cd78efb GIT binary patch literal 2984 zcma)8S5Om*5=|pQLW{S$`S9G*WFajC!hN|8mvN!tP@0vk9TPG<-O` zl6ZYBM1%a~<|sYxRY@ZaP#_mZ!z_AaJ{N8$D0N8_V~26?X?<;_*cXI+TR?9x@~z&T zsanV|?j~8OmY@ox?>xK=E}nDKsM(x|jz|RzrK79ec#*UTO;5d?Hywy*Zt(|z{{u9Q z?5Bn!%z?J<-e3Dw)vB^jzF{w990uOysZ+5p9BgvFdTN-OHF(=9W+U(eHmSB|5OZQO zkxcM5h&5H|FsFDzs8c&Vzpy)T0hZUmyUzH)X$~ewF1bPMunjqBB51F|cRhC~g@Y9p zfY~ku+CnNf&j5twV=Tr2w;#oAiNH+U(ac`jB-1USf22^Dfp?zC(`$6X^iopL1?rMG zzA5gnl2pUVO=V=bRxyBMt^O3h;FG7&O162AWQrK%9v?ylddT)>E~39A&N^;@b{|zI z9bLl%Ft;W~FFD>AK!4)@xylcY-MxVx*rO=EC_T}6iwTp*v;~+ zmCVydotILV1%8*_6EXIa&6imTwy+U-0N{M6rYKsq#s&GETHj9f~3rM zbi_xt|Gz;y6UMgDmW>JH2h|CI%1dNeEAzt+zXCjj-pa?@3BztYJ);JjfaFQqf>HOs z_i!JJe=z1~AfY3@5?!So8O%y78*L%WOJveGWNGV9_PF;vMaW}?zAfP!K?vb6X`ima zw4bT{UDl9F$JbiZQ@l^$+VbGS;w{nz?s#ix9nCKn>3-+b=Iz;6n}hQ6*Oc1p+r;}} zYq|g}A1MNJa9_%&E3P;`EjpeRX+orzD1RtbUw6=Ph|CzLc6P1JtlSb7U~}N}vvgIx zh4!#tT!e}XN% z_&=n?9fs8JBNwy&;Wp*jX$+WAGeYd(`o0D_U`9nABD;bVXnQ({O(J4tx!0%#QrmQQ zYocx6(O)DcAWFBwSBc-0uTk@YSuA6m_bMYOHuu(LY9H9aQ6Fz?6|h

N*-y zdi=z~;}35;$g?RUBQ+5bItJi_9w?f^o!hM;S?=q0!kGI0v<`C6r}w3umvd<6l#i&3 zgofVNfqT&62<&)((=@lW^i%%wz^%G&QDdQ@{RfH3y>$jTu6#eNxw~T}sG%%y-R$M; zC6_OvPJc*2DPb{ATht*`W^5Q-LL3QP&bS+2yTpDfN$B(rOx2#w=9HG3)jlL!GmZg< zD|c^-N>FX=R&EwtQhe>MRn=7ZLjFWa#|2Ziohby9TTV4y$3NL!p-P=JboOa2XS!_{ zZV|TP&n7A)s5U&8vu0y7`hc(1xcDy0m=!VCDBeCedNxt;pL^toodmXxCW0y21CF6| zcO@A%Drd_%zr5nNu^61w*hyp`f38Nb@!BCfI|uQmJMks zrd%IuhZ2f2R|F97DSnsD5_O+PzsJ=S;KS)?n|a&3(xg2@*il|8sGRkiEkAZL$8M5I z>YawYnPO-VaPPbt>szBTBXwTa!>EcP5&C58 zPf-o`gboeMwP0JTP%~3#^x6xdv-;v7Zi&eM!W%5UYSNQ$xAsCt^=>BZ`J6~4aQ^GD z0px=p=eBQs>|<(`<0L*OS8X*l3~?)}yHqdlF8le&=aw+t_@DUxYK%xvc4At3pQkDz z$&*~)j6a@veziyfv^$goI=9L49}5^T#4#q`7M(THMJF~x4&T!WRXY)_%a1;{b zw&dbe$u|@;?qI)c)7ry4Q6{pjOp}eun?S5l%z|UL&c=>5NQ3S8TDdhNq`c|Z+Hd<{ zUF8ooJD7_IW}uNF9o;UA%Ht>-bcY|Nbl3ajhTbZbkIU?=dF5FYowve%n#KQs)WVW>#CiY{p)jaY3CH6sR@=Wa)jJJ-EP<*>XSGW2#(1fkuaJZ`^xw$xh6R z7`x^MYT#vvHUAhUFL8oHuMhMStOEQ(?)$Nk3U2(>h5)UU7Wl9G-Z_t<LLTF zA5v7rumM3rw^!p)UXi}ol;S*J>(vPA{;H_Sx`FR?zvMDR#OzobS>E%rXL${+|KLc^ zUz@mhQa`OJe^#usHT1KUKim#!!kR;4M*jt;h1SRz8x(bF9ao`$Qf_})n(|p)_{Z3| z+`iAun0o0&$xCE*-moL>+%$iGtRTvmFVYNCu>APTX;--IyH18#Drykql0^|k-#Yk7sD#XYdpy^@Vh9qTn{5jX zV5l-XyZ{Ps*{<6cM8R)wP2Z||h-|UfyXBPcNA7(Rk+Shc6{auRdVq{!u*+@j4>%@V zkF{1oZ3-T&e-dSZHj`F|K#dDA>K7Kw$ zdkzzQFcCLGZpHqzqHMLkmPHgsm8J7;O|<|{t3+2UeqBU|Ib1Z54Bx!e6<9X>BO!cn zG)Kq|`j(S5610A%9ZPYEUExn`mS0~Pq9{J@(Yi5%#D2{Fg(HNm-G{~l3iTr^ou4kN zVX{9mvz+@!_M+iApo4uOk;CL+d)!3mO};C4fN3|EzKvvuP9#-&0`bAHeik@#e^CDS zQh*Pw(upqG;woT!LllmHXYo41cwO>Yj>+Z_6>(}+FyHBMrZ&S#;tNXE4(2aTU8T!R z32Wx_h-ZiI;R&f45J7DK?tepZ^^ciLzh!ue#PmyZ`hZI5@~P_2pvQnssm87Gl&Ifj z6+4Bpk(M3w9lYk0<1%=?pR-42te+Z{IS(5R%H0zAH_E?qufwLZFZa)eYrztuRoCPs z80&2V%X6W - + Account Settings - account.config.settings - + res.config.settings + - - - - - - - - + +

FACe Configuration

+
+
+
+
+
+
+
+
+
+
+ + + +
+ diff --git a/l10n_es_facturae_face/wizard/__init__.py b/l10n_es_facturae_face/wizard/__init__.py index eb6be7580be..38f253f4729 100644 --- a/l10n_es_facturae_face/wizard/__init__.py +++ b/l10n_es_facturae_face/wizard/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from . import account_invoice_integration_cancel diff --git a/l10n_es_facturae_face/wizard/account_invoice_integration_cancel.py b/l10n_es_facturae_face/wizard/account_invoice_integration_cancel.py index 8dba0349809..ff951a31373 100644 --- a/l10n_es_facturae_face/wizard/account_invoice_integration_cancel.py +++ b/l10n_es_facturae_face/wizard/account_invoice_integration_cancel.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import models, fields From 49a8190c8bda33ad39ff2b4f96b4adb323f8def4 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Mon, 18 Jun 2018 12:34:06 +0000 Subject: [PATCH 003/101] [UPD] Update l10n_es_facturae_face.pot --- l10n_es_facturae_face/i18n/es.po | 121 ++++++++++++++++++ .../i18n/l10n_es_facturae_face.pot | 117 +++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 l10n_es_facturae_face/i18n/es.po create mode 100644 l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot diff --git a/l10n_es_facturae_face/i18n/es.po b/l10n_es_facturae_face/i18n/es.po new file mode 100644 index 00000000000..056b376dcde --- /dev/null +++ b/l10n_es_facturae_face/i18n/es.po @@ -0,0 +1,121 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_facturae_face +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2018-11-28 23:09+0000\n" +"Last-Translator: Enric Tobella \n" +"Language-Team: none\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" +"X-Generator: Weblate 3.2.2\n" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_cancel +msgid "Cancels a created integration" +msgstr "Cancela una integración creada" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/account_invoice_integration_method.py:20 +#, python-format +msgid "Certificate must be added for company" +msgstr "Se debe añadir un certificado a la compañía" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/account_invoice_integration_method.py:23 +#, python-format +msgid "Certificate password must be added for company" +msgstr "Se debe añadir un password para el certificado en la compañía" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel_method_code +msgid "Code" +msgstr "Código" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_res_partner +msgid "Contact" +msgstr "Contacto" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_partner.py:26 +#, python-format +msgid "Country must be defined in order to send to FACe" +msgstr "Se debe definir el país para poder enviar por FACe" + +#. module: l10n_es_facturae_face +#: model:ir.ui.view,arch_db:l10n_es_facturae_face.res_config_settings_view_form +msgid "FACe Configuration" +msgstr "Configuración FACe" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_config_settings_face_server +msgid "FACe server location" +msgstr "Servidor FACe" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_company_face_email +msgid "Face Email" +msgstr "Email FACe" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_partner.py:19 +#, python-format +msgid "Facturae must be selected in order to send to FACe" +msgstr "Se debe seleccionar el campo facturae para poder enviar por FACe" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_company.py:20 +#, python-format +msgid "Invalid facturae email" +msgstr "Email de Facturae inválido" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel_motive +msgid "Motive" +msgstr "Motivo" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_partner.py:30 +#, python-format +msgid "State must be defined in Spain in order to send to FACe" +msgstr "" +"La provincia debe estar definido si el país es España para poder enviar por " +"FACe" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_partner.py:23 +#, python-format +msgid "Vat must be defined in order to send to FACe" +msgstr "El identificador fiscal debe estar definido para poder enviar por FACe" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration +msgid "account.invoice.integration" +msgstr "account.invoice.integration" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_log +msgid "account.invoice.integration.log" +msgstr "account.invoice.integration.log" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_method +msgid "account.invoice.integration.method" +msgstr "account.invoice.integration.method" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_res_config_settings +msgid "res.config.settings" +msgstr "res.config.settings" diff --git a/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot b/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot new file mode 100644 index 00000000000..09e0899cc4b --- /dev/null +++ b/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot @@ -0,0 +1,117 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_es_facturae_face +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \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_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_cancel +msgid "Cancels a created integration" +msgstr "" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/account_invoice_integration_method.py:20 +#, python-format +msgid "Certificate must be added for company" +msgstr "" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/account_invoice_integration_method.py:23 +#, python-format +msgid "Certificate password must be added for company" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel_method_code +msgid "Code" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_res_company +msgid "Companies" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_res_partner +msgid "Contact" +msgstr "" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_partner.py:26 +#, python-format +msgid "Country must be defined in order to send to FACe" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.ui.view,arch_db:l10n_es_facturae_face.res_config_settings_view_form +msgid "FACe Configuration" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_config_settings_face_server +msgid "FACe server location" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_company_face_email +msgid "Face Email" +msgstr "" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_partner.py:19 +#, python-format +msgid "Facturae must be selected in order to send to FACe" +msgstr "" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_company.py:20 +#, python-format +msgid "Invalid facturae email" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel_motive +msgid "Motive" +msgstr "" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_partner.py:30 +#, python-format +msgid "State must be defined in Spain in order to send to FACe" +msgstr "" + +#. module: l10n_es_facturae_face +#: code:addons/l10n_es_facturae_face/models/res_partner.py:23 +#, python-format +msgid "Vat must be defined in order to send to FACe" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration +msgid "account.invoice.integration" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_log +msgid "account.invoice.integration.log" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_method +msgid "account.invoice.integration.method" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_res_config_settings +msgid "res.config.settings" +msgstr "" + From 1b37f7ed3ae6a5745be0bad6dfc8a43c1207a1b1 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Tue, 29 Jan 2019 17:05:01 +0100 Subject: [PATCH 004/101] [FIX] l10n_es_facturae_face: Avoid some problems + deactivate test They are failing and breaking branch, so this is the best soluction for now --- l10n_es_facturae_face/models/wsse_signature.py | 2 +- l10n_es_facturae_face/tests/__init__.py | 3 ++- l10n_es_facturae_face/tests/test_facturae_face.py | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/l10n_es_facturae_face/models/wsse_signature.py b/l10n_es_facturae_face/models/wsse_signature.py index fa578cf6b7e..fffd5fb29e8 100644 --- a/l10n_es_facturae_face/models/wsse_signature.py +++ b/l10n_es_facturae_face/models/wsse_signature.py @@ -178,7 +178,7 @@ def _verify_envelope_with_key(envelope, key): soap_env = detect_soap_env(envelope) header = envelope.find(QName(soap_env, 'Header')) - if not header: + if header is None: raise SignatureVerificationFailed() security = header.find(QName(ns.WSSE, 'Security')) diff --git a/l10n_es_facturae_face/tests/__init__.py b/l10n_es_facturae_face/tests/__init__.py index 1241c2f460e..f9fb298472e 100644 --- a/l10n_es_facturae_face/tests/__init__.py +++ b/l10n_es_facturae_face/tests/__init__.py @@ -1,3 +1,4 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from . import test_facturae_face +# deactivated for now as it fails +# from . import test_facturae_face diff --git a/l10n_es_facturae_face/tests/test_facturae_face.py b/l10n_es_facturae_face/tests/test_facturae_face.py index c223dc72d1d..e04154971d8 100644 --- a/l10n_es_facturae_face/tests/test_facturae_face.py +++ b/l10n_es_facturae_face/tests/test_facturae_face.py @@ -64,7 +64,10 @@ def setUp(self): }) main_company.vat = "ESA12345674" main_company.partner_id.country_id = self.ref('base.uk') - main_company.currency_id = self.ref('base.EUR') + self.env.cr.execute( + "UPDATE res_company SET currency_id = %s", + (self.ref('base.EUR'), ), + ) bank_obj = self.env['res.partner.bank'] self.bank = bank_obj.search([ ('acc_number', '=', 'BE96 9988 7766 5544')], limit=1) From 40cb27dcb5c484d546cd08378699dff86690c572 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Fri, 22 Feb 2019 12:25:44 +0100 Subject: [PATCH 005/101] [FIX] facturae_face: Certificado en formato DER --- l10n_es_facturae_face/__manifest__.py | 2 +- l10n_es_facturae_face/models/wsse_signature.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index 4893768133f..98d5e40fd89 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Envío de Factura-e a FACe", - "version": "11.0.1.0.0", + "version": "11.0.1.0.1", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", diff --git a/l10n_es_facturae_face/models/wsse_signature.py b/l10n_es_facturae_face/models/wsse_signature.py index fffd5fb29e8..b307ce98b36 100644 --- a/l10n_es_facturae_face/models/wsse_signature.py +++ b/l10n_es_facturae_face/models/wsse_signature.py @@ -183,9 +183,10 @@ def _verify_envelope_with_key(envelope, key): security = header.find(QName(ns.WSSE, 'Security')) signature = security.find(QName(ns.DS, 'Signature')) - + key_text = security.find(QName(ns.WSSE, 'BinarySecurityToken')).text + key = xmlsec.Key.from_memory(base64.b64decode(key_text), + xmlsec.KeyFormat.CERT_DER, None) ctx = xmlsec.SignatureContext() - # Find each signed element and register its ID with the signing context. refs = signature.xpath( 'ds:SignedInfo/ds:Reference', namespaces={'ds': ns.DS}) @@ -199,7 +200,6 @@ def _verify_envelope_with_key(envelope, key): ctx.register_id(referenced, 'Id', ns.WSU) ctx.key = key - try: ctx.verify(signature) except xmlsec.Error: From b463ab02aadea262052fe6315211c3682ae6c373 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Fri, 22 Feb 2019 12:33:29 +0100 Subject: [PATCH 006/101] [FIX] facturae_face: Missing parent field --- l10n_es_facturae_face/models/account_invoice_integration_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_es_facturae_face/models/account_invoice_integration_log.py b/l10n_es_facturae_face/models/account_invoice_integration_log.py index c325e87e328..6b92ff6745b 100644 --- a/l10n_es_facturae_face/models/account_invoice_integration_log.py +++ b/l10n_es_facturae_face/models/account_invoice_integration_log.py @@ -120,7 +120,7 @@ def send_method(self): ) anexos_list = [] if self.integration_id.attachment_ids: - for attachment in self.attachment_ids: + for attachment in self.integration_id.attachment_ids: anexo = client.get_type('ns0:AnexoFile')( attachment.datas, attachment.datas_fname, From 3f26647fad9cdac091c8eafd0bf7c18690e4a082 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Mon, 25 Mar 2019 16:33:37 +0100 Subject: [PATCH 007/101] [FIX] l10n_es_facturae_face: missing sudos --- l10n_es_facturae_face/__manifest__.py | 2 +- .../models/account_invoice_integration_log.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index 98d5e40fd89..c3245e30c4e 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Envío de Factura-e a FACe", - "version": "11.0.1.0.1", + "version": "11.0.1.0.2", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", diff --git a/l10n_es_facturae_face/models/account_invoice_integration_log.py b/l10n_es_facturae_face/models/account_invoice_integration_log.py index 6b92ff6745b..d8a6943173e 100644 --- a/l10n_es_facturae_face/models/account_invoice_integration_log.py +++ b/l10n_es_facturae_face/models/account_invoice_integration_log.py @@ -28,7 +28,7 @@ def update_method(self): ) cert.set_ca_certificates(None) client = Client( - wsdl=self.env["ir.config_parameter"].get_param( + wsdl=self.env["ir.config_parameter"].sudo().get_param( "account.invoice.face.server", default=None), wsse=MemorySignature( cert.export(), @@ -68,7 +68,7 @@ def cancel_method(self): ) cert.set_ca_certificates(None) client = Client( - wsdl=self.env["ir.config_parameter"].get_param( + wsdl=self.env["ir.config_parameter"].sudo().get_param( "account.invoice.face.server", default=None), wsse=MemorySignature( cert.export(), @@ -103,7 +103,7 @@ def send_method(self): ) cert.set_ca_certificates(None) client = Client( - wsdl=self.env["ir.config_parameter"].get_param( + wsdl=self.env["ir.config_parameter"].sudo().get_param( "account.invoice.face.server", default=None), wsse=MemorySignature( cert.export(), From 8c0a110e9c99180a2cabaa0b7950c0d9f9b0a744 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Thu, 4 Jul 2019 11:31:32 +0200 Subject: [PATCH 008/101] [FIX] facturae_face: ejecutar como sudo debido a cambio del mimetype --- l10n_es_facturae_face/__manifest__.py | 2 +- .../models/account_invoice_integration_method.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index c3245e30c4e..26557e39709 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Envío de Factura-e a FACe", - "version": "11.0.1.0.2", + "version": "11.0.1.0.3", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", diff --git a/l10n_es_facturae_face/models/account_invoice_integration_method.py b/l10n_es_facturae_face/models/account_invoice_integration_method.py index 7d6b1f17b6c..2948429260f 100644 --- a/l10n_es_facturae_face/models/account_invoice_integration_method.py +++ b/l10n_es_facturae_face/models/account_invoice_integration_method.py @@ -22,7 +22,7 @@ def integration_values(self, invoice): raise exceptions.UserError( _('Certificate password must be added for company')) invoice_file, file_name = invoice.get_facturae(True) - attachment = self.env['ir.attachment'].create({ + attachment = self.env['ir.attachment'].sudo().create({ 'name': file_name, 'datas': base64.b64encode(invoice_file), 'datas_fname': file_name, From ae2a75df4f85aba6d60e04a0898b65a9b8d51268 Mon Sep 17 00:00:00 2001 From: Jaime Arroyo Date: Thu, 25 Jul 2019 10:49:36 +0200 Subject: [PATCH 009/101] [12.0][MIG] l10n_es_facturae_face --- l10n_es_facturae_face/README.rst | 80 ++++++++++++++------ l10n_es_facturae_face/__manifest__.py | 2 +- l10n_es_facturae_face/readme/CONFIGURE.rst | 8 ++ l10n_es_facturae_face/readme/DESCRIPTION.rst | 3 + l10n_es_facturae_face/readme/INSTALL.rst | 4 + l10n_es_facturae_face/readme/USAGE.rst | 13 ++++ l10n_es_facturae_face/tests/__init__.py | 3 +- 7 files changed, 86 insertions(+), 27 deletions(-) create mode 100644 l10n_es_facturae_face/readme/CONFIGURE.rst create mode 100644 l10n_es_facturae_face/readme/DESCRIPTION.rst create mode 100644 l10n_es_facturae_face/readme/INSTALL.rst create mode 100644 l10n_es_facturae_face/readme/USAGE.rst diff --git a/l10n_es_facturae_face/README.rst b/l10n_es_facturae_face/README.rst index fdbf6765fe5..0f7961845ff 100644 --- a/l10n_es_facturae_face/README.rst +++ b/l10n_es_facturae_face/README.rst @@ -1,25 +1,49 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 - -=============================================================== -Envío de la facturación electrónica española (Factura-E) a FACe -=============================================================== +========================= +Envío de Factura-e a FACe +========================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--spain-lightgray.png?logo=github + :target: https://github.com/OCA/l10n-spain/tree/12.0/l10n_es_facturae_face + :alt: OCA/l10n-spain +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/l10n-spain-12-0/l10n-spain-12-0-l10n_es_facturae_face + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/189/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| Este módulo permite la gestión del envío de la facturación electrónica española a FACe. La gestión del envío se realiza mediante los certificados con los que se firma. -Instalación -=========== +**Table of contents** + +.. contents:: + :local: + +Installation +============ Este módulo depende del módulo *l10n_es_facturae* y sus dependencias Es necesario tener instalado el módulo xmlsec y zeep en la versión que envía en formato c14n. -Configuración +Configuration ============= * Es necesario añadir el correo electrónico al que notificar los cambios de @@ -31,8 +55,8 @@ Configuración https://webservice.face.gob.es/facturasspp2 y modificar el certificado en parámetros de sistema -Uso -=== +Usage +===== * Accedemos a un cliente y le configuramos la factura electrónica * Accedemos a una factura validada del cliente y pulsamos el botón @@ -48,29 +72,37 @@ Uso * Se genera una tarea programada que actualiza los registros enviados correctamente no pagados y no anulados -.. 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/11.0 +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= -Contributors ------------- +Authors +~~~~~~~ + +* Creu Blanca -* Enric Tobella +Maintainers +~~~~~~~~~~~ -Maintainer ----------- +This module is maintained by the OCA. -.. image:: http://odoo-community.org/logo.png +.. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. +This module is part of the `OCA/l10n-spain `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index 26557e39709..c9df44ecf5b 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Envío de Factura-e a FACe", - "version": "11.0.1.0.3", + "version": "12.0.1.0.0", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", diff --git a/l10n_es_facturae_face/readme/CONFIGURE.rst b/l10n_es_facturae_face/readme/CONFIGURE.rst new file mode 100644 index 00000000000..644b4085320 --- /dev/null +++ b/l10n_es_facturae_face/readme/CONFIGURE.rst @@ -0,0 +1,8 @@ +* Es necesario añadir el correo electrónico al que notificar los cambios de + estado en la empresa +* Se debe configurar el servidor de envío +* Por defecto se añado el servicio web de test: + https://se-face-webservice.redsara.es/facturasspp2 +* Si queremos añadir el de producción, debemos cambiar el parámetro por + https://webservice.face.gob.es/facturasspp2 y modificar el certificado en + parámetros de sistema diff --git a/l10n_es_facturae_face/readme/DESCRIPTION.rst b/l10n_es_facturae_face/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..d61acadd959 --- /dev/null +++ b/l10n_es_facturae_face/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +Este módulo permite la gestión del envío de la facturación electrónica española +a FACe. +La gestión del envío se realiza mediante los certificados con los que se firma. diff --git a/l10n_es_facturae_face/readme/INSTALL.rst b/l10n_es_facturae_face/readme/INSTALL.rst new file mode 100644 index 00000000000..86bf197a390 --- /dev/null +++ b/l10n_es_facturae_face/readme/INSTALL.rst @@ -0,0 +1,4 @@ +Este módulo depende del módulo *l10n_es_facturae* y sus dependencias + +Es necesario tener instalado el módulo xmlsec y zeep en la versión que envía en +formato c14n. diff --git a/l10n_es_facturae_face/readme/USAGE.rst b/l10n_es_facturae_face/readme/USAGE.rst new file mode 100644 index 00000000000..e842b721908 --- /dev/null +++ b/l10n_es_facturae_face/readme/USAGE.rst @@ -0,0 +1,13 @@ +* Accedemos a un cliente y le configuramos la factura electrónica +* Accedemos a una factura validada del cliente y pulsamos el botón + 'Enviar a FACe' +* Podremos añadir adjuntos que al envío de la factura original +* Pulsamos 'Enviar' en el registro de envío a FACe +* Si el envío es correcto, nos mostrará el resultado y el número de registro +* Si el envío es correcto, podremos actualizar el estado de forma online +* Si el envío es correcto, podremos solicitar la anulación de la factura + pulsando 'Cancelar Envío' e introduciendo el motivo +* Un registro Enviado correctamente no puede ser Eliminado +* Sólo puede existir un envío Enviado correctamente +* Se genera una tarea programada que actualiza los registros enviados + correctamente no pagados y no anulados diff --git a/l10n_es_facturae_face/tests/__init__.py b/l10n_es_facturae_face/tests/__init__.py index f9fb298472e..1241c2f460e 100644 --- a/l10n_es_facturae_face/tests/__init__.py +++ b/l10n_es_facturae_face/tests/__init__.py @@ -1,4 +1,3 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -# deactivated for now as it fails -# from . import test_facturae_face +from . import test_facturae_face From 62e7017b5c28782f464dc4f80e5e5fb132d81e1e Mon Sep 17 00:00:00 2001 From: oca-travis Date: Fri, 26 Jul 2019 07:58:18 +0000 Subject: [PATCH 010/101] [UPD] Update l10n_es_facturae_face.pot --- .../i18n/l10n_es_facturae_face.pot | 98 +++++++++++++++---- 1 file changed, 79 insertions(+), 19 deletions(-) diff --git a/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot b/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot index 09e0899cc4b..492c037836c 100644 --- a/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot +++ b/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 11.0\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: <>\n" "Language-Team: \n" @@ -13,6 +13,36 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Accepted" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration__cancellation_status +msgid "Cancellation Status" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,cancellation_status:0 +msgid "Cancellation accepted" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Cancellation approved" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,cancellation_status:0 +msgid "Cancellation rejected" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,cancellation_status:0 +msgid "Cancellation requested" +msgstr "" + #. module: l10n_es_facturae_face #: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_cancel msgid "Cancels a created integration" @@ -31,7 +61,7 @@ msgid "Certificate password must be added for company" msgstr "" #. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel_method_code +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel__method_code msgid "Code" msgstr "" @@ -40,6 +70,11 @@ msgstr "" msgid "Companies" msgstr "" +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_res_config_settings +msgid "Config Settings" +msgstr "" + #. module: l10n_es_facturae_face #: model:ir.model,name:l10n_es_facturae_face.model_res_partner msgid "Contact" @@ -52,17 +87,17 @@ msgid "Country must be defined in order to send to FACe" msgstr "" #. module: l10n_es_facturae_face -#: model:ir.ui.view,arch_db:l10n_es_facturae_face.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:l10n_es_facturae_face.res_config_settings_view_form msgid "FACe Configuration" msgstr "" #. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_config_settings_face_server +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_config_settings__face_server msgid "FACe server location" msgstr "" #. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_company_face_email +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_company__face_email msgid "Face Email" msgstr "" @@ -72,6 +107,21 @@ msgstr "" msgid "Facturae must be selected in order to send to FACe" msgstr "" +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration__integration_status +msgid "Integration Status" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration +msgid "Integration for an invoice" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_method +msgid "Integration method for invoices" +msgstr "" + #. module: l10n_es_facturae_face #: code:addons/l10n_es_facturae_face/models/res_company.py:20 #, python-format @@ -79,39 +129,49 @@ msgid "Invalid facturae email" msgstr "" #. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel_motive +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel__motive msgid "Motive" msgstr "" #. module: l10n_es_facturae_face -#: code:addons/l10n_es_facturae_face/models/res_partner.py:30 -#, python-format -msgid "State must be defined in Spain in order to send to FACe" +#: selection:account.invoice.integration,cancellation_status:0 +msgid "Not requested" msgstr "" #. module: l10n_es_facturae_face -#: code:addons/l10n_es_facturae_face/models/res_partner.py:23 -#, python-format -msgid "Vat must be defined in order to send to FACe" +#: selection:account.invoice.integration,integration_status:0 +msgid "Payed" msgstr "" #. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration -msgid "account.invoice.integration" +#: selection:account.invoice.integration,integration_status:0 +msgid "Registered on RCF" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Registered on REC" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Rejected" msgstr "" #. module: l10n_es_facturae_face #: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_log -msgid "account.invoice.integration.log" +msgid "Result logs for integrations of invoices" msgstr "" #. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_method -msgid "account.invoice.integration.method" +#: code:addons/l10n_es_facturae_face/models/res_partner.py:30 +#, python-format +msgid "State must be defined in Spain in order to send to FACe" msgstr "" #. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_res_config_settings -msgid "res.config.settings" +#: code:addons/l10n_es_facturae_face/models/res_partner.py:23 +#, python-format +msgid "Vat must be defined in order to send to FACe" msgstr "" From ad9a4830df47ed55f62980dc8a8c3ead6a1aeb5a Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 26 Jul 2019 08:29:18 +0000 Subject: [PATCH 011/101] [UPD] README.rst --- l10n_es_facturae_face/README.rst | 1 - .../static/description/index.html | 454 ++++++++++++++++++ 2 files changed, 454 insertions(+), 1 deletion(-) create mode 100644 l10n_es_facturae_face/static/description/index.html diff --git a/l10n_es_facturae_face/README.rst b/l10n_es_facturae_face/README.rst index 0f7961845ff..be365d84a47 100644 --- a/l10n_es_facturae_face/README.rst +++ b/l10n_es_facturae_face/README.rst @@ -27,7 +27,6 @@ Envío de Factura-e a FACe Este módulo permite la gestión del envío de la facturación electrónica española a FACe. - La gestión del envío se realiza mediante los certificados con los que se firma. **Table of contents** diff --git a/l10n_es_facturae_face/static/description/index.html b/l10n_es_facturae_face/static/description/index.html new file mode 100644 index 00000000000..24a441316c4 --- /dev/null +++ b/l10n_es_facturae_face/static/description/index.html @@ -0,0 +1,454 @@ + + + + + + +Envío de Factura-e a FACe + + + +
+

Envío de Factura-e a FACe

+ + +

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

+

Este módulo permite la gestión del envío de la facturación electrónica española +a FACe. +La gestión del envío se realiza mediante los certificados con los que se firma.

+

Table of contents

+ +
+

Installation

+

Este módulo depende del módulo l10n_es_facturae y sus dependencias

+

Es necesario tener instalado el módulo xmlsec y zeep en la versión que envía en +formato c14n.

+
+
+

Configuration

+ +
+
+

Usage

+
    +
  • Accedemos a un cliente y le configuramos la factura electrónica
  • +
  • Accedemos a una factura validada del cliente y pulsamos el botón +‘Enviar a FACe’
  • +
  • Podremos añadir adjuntos que al envío de la factura original
  • +
  • Pulsamos ‘Enviar’ en el registro de envío a FACe
  • +
  • Si el envío es correcto, nos mostrará el resultado y el número de registro
  • +
  • Si el envío es correcto, podremos actualizar el estado de forma online
  • +
  • Si el envío es correcto, podremos solicitar la anulación de la factura +pulsando ‘Cancelar Envío’ e introduciendo el motivo
  • +
  • Un registro Enviado correctamente no puede ser Eliminado
  • +
  • Sólo puede existir un envío Enviado correctamente
  • +
  • Se genera una tarea programada que actualiza los registros enviados +correctamente no pagados y no anulados
  • +
+
+
+

Bug Tracker

+

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

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Creu Blanca
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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

+

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

+

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

+
+
+
+ + From 93e081b123b5977e16a8be104533c3bd36250de4 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sat, 27 Jul 2019 16:31:59 +0000 Subject: [PATCH 012/101] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: l10n-spain-12.0/l10n-spain-12.0-l10n_es_facturae_face Translate-URL: https://translation.odoo-community.org/projects/l10n-spain-12-0/l10n-spain-12-0-l10n_es_facturae_face/ --- l10n_es_facturae_face/i18n/es.po | 117 +++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 23 deletions(-) diff --git a/l10n_es_facturae_face/i18n/es.po b/l10n_es_facturae_face/i18n/es.po index 056b376dcde..1997266bf1b 100644 --- a/l10n_es_facturae_face/i18n/es.po +++ b/l10n_es_facturae_face/i18n/es.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * l10n_es_facturae_face +# * l10n_es_facturae_face # msgid "" msgstr "" @@ -16,6 +16,36 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.2.2\n" +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Accepted" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration__cancellation_status +msgid "Cancellation Status" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,cancellation_status:0 +msgid "Cancellation accepted" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Cancellation approved" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,cancellation_status:0 +msgid "Cancellation rejected" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,cancellation_status:0 +msgid "Cancellation requested" +msgstr "" + #. module: l10n_es_facturae_face #: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_cancel msgid "Cancels a created integration" @@ -34,7 +64,7 @@ msgid "Certificate password must be added for company" msgstr "Se debe añadir un password para el certificado en la compañía" #. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel_method_code +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel__method_code msgid "Code" msgstr "Código" @@ -43,6 +73,13 @@ msgstr "Código" msgid "Companies" msgstr "Compañías" +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_res_config_settings +#, fuzzy +#| msgid "res.config.settings" +msgid "Config Settings" +msgstr "res.config.settings" + #. module: l10n_es_facturae_face #: model:ir.model,name:l10n_es_facturae_face.model_res_partner msgid "Contact" @@ -55,17 +92,17 @@ msgid "Country must be defined in order to send to FACe" msgstr "Se debe definir el país para poder enviar por FACe" #. module: l10n_es_facturae_face -#: model:ir.ui.view,arch_db:l10n_es_facturae_face.res_config_settings_view_form +#: model_terms:ir.ui.view,arch_db:l10n_es_facturae_face.res_config_settings_view_form msgid "FACe Configuration" msgstr "Configuración FACe" #. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_config_settings_face_server +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_config_settings__face_server msgid "FACe server location" msgstr "Servidor FACe" #. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_company_face_email +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_company__face_email msgid "Face Email" msgstr "Email FACe" @@ -75,6 +112,21 @@ msgstr "Email FACe" msgid "Facturae must be selected in order to send to FACe" msgstr "Se debe seleccionar el campo facturae para poder enviar por FACe" +#. module: l10n_es_facturae_face +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration__integration_status +msgid "Integration Status" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration +msgid "Integration for an invoice" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_method +msgid "Integration method for invoices" +msgstr "" + #. module: l10n_es_facturae_face #: code:addons/l10n_es_facturae_face/models/res_company.py:20 #, python-format @@ -82,10 +134,40 @@ msgid "Invalid facturae email" msgstr "Email de Facturae inválido" #. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel_motive +#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_invoice_integration_cancel__motive msgid "Motive" msgstr "Motivo" +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,cancellation_status:0 +msgid "Not requested" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Payed" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Registered on RCF" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Registered on REC" +msgstr "" + +#. module: l10n_es_facturae_face +#: selection:account.invoice.integration,integration_status:0 +msgid "Rejected" +msgstr "" + +#. module: l10n_es_facturae_face +#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_log +msgid "Result logs for integrations of invoices" +msgstr "" + #. module: l10n_es_facturae_face #: code:addons/l10n_es_facturae_face/models/res_partner.py:30 #, python-format @@ -100,22 +182,11 @@ msgstr "" msgid "Vat must be defined in order to send to FACe" msgstr "El identificador fiscal debe estar definido para poder enviar por FACe" -#. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration -msgid "account.invoice.integration" -msgstr "account.invoice.integration" +#~ msgid "account.invoice.integration" +#~ msgstr "account.invoice.integration" -#. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_log -msgid "account.invoice.integration.log" -msgstr "account.invoice.integration.log" - -#. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_account_invoice_integration_method -msgid "account.invoice.integration.method" -msgstr "account.invoice.integration.method" +#~ msgid "account.invoice.integration.log" +#~ msgstr "account.invoice.integration.log" -#. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_res_config_settings -msgid "res.config.settings" -msgstr "res.config.settings" +#~ msgid "account.invoice.integration.method" +#~ msgstr "account.invoice.integration.method" From 0121a47596b2110199e47fc2b409984094d62c06 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 29 Jul 2019 03:06:52 +0000 Subject: [PATCH 013/101] [UPD] README.rst --- l10n_es_facturae_face/static/description/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_es_facturae_face/static/description/index.html b/l10n_es_facturae_face/static/description/index.html index 24a441316c4..7d44fc46f64 100644 --- a/l10n_es_facturae_face/static/description/index.html +++ b/l10n_es_facturae_face/static/description/index.html @@ -3,7 +3,7 @@ - + Envío de Factura-e a FACe -
-

Envío de Factura-e a FACe

+
+

Envío de Facturae a FACe

result = record._has_exchange_record("l10n_es_facturae", record.env.ref("l10n_es_facturae_face.face_backend")) + >result = record._has_exchange_record(record.env.ref("l10n_es_facturae_face.facturae_exchange_type"), record.env.ref("l10n_es_facturae_face.face_backend")) Cancel Facturae FACe diff --git a/l10n_es_facturae_face/models/account_move.py b/l10n_es_facturae_face/models/account_move.py index 66c93184ec4..9ef9d5688f8 100644 --- a/l10n_es_facturae_face/models/account_move.py +++ b/l10n_es_facturae_face/models/account_move.py @@ -45,7 +45,8 @@ def _get_edi_missing_records(self): if not partner.facturae or not partner.l10n_es_facturae_sending_code: return False return not self._has_exchange_record( - "l10n_es_facturae", self.env.ref("l10n_es_facturae_face.backend_facturae") + self.env.ref("l10n_es_facturae_face.facturae_exchange_type"), + self.env.ref("l10n_es_facturae_face.backend_facturae"), ) @api.model @@ -62,7 +63,9 @@ def _has_exchange_record_domain( domain = super()._has_exchange_record_domain( exchange_type, backend=backend, extra_domain=extra_domain ) - if exchange_type == "l10n_es_facturae": + if exchange_type == self.env.ref( + "l10n_es_facturae_face.facturae_exchange_type" + ): domain += [ "|", ("l10n_es_facturae_status", "=", False), diff --git a/l10n_es_facturae_face/wizards/edi_l10n_es_facturae_face_cancel.py b/l10n_es_facturae_face/wizards/edi_l10n_es_facturae_face_cancel.py index 13bea44d4e0..6adb85b4302 100644 --- a/l10n_es_facturae_face/wizards/edi_l10n_es_facturae_face_cancel.py +++ b/l10n_es_facturae_face/wizards/edi_l10n_es_facturae_face_cancel.py @@ -16,7 +16,8 @@ class EdiL10nEsFacturaeFaceCancel(models.TransientModel): def cancel_face(self): self.ensure_one() backend = self.env.ref("l10n_es_facturae_face.face_backend") - exchange_record = self.move_id._get_exchange_record("l10n_es_facturae", backend) + exchange_type = self.env.ref("l10n_es_facturae_face.facturae_exchange_type") + exchange_record = self.move_id._get_exchange_record(exchange_type, backend) exchange_record.ensure_one() cancel_exchange_record = backend.create_record( "l10n_es_facturae_face_cancel", From b817086e9135a4d06b74f875829de4ceda62f1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Thu, 18 Aug 2022 10:33:04 +0200 Subject: [PATCH 068/101] [FIX] l10n_es_facturae_face: Change to the correct field name to fix tests. --- l10n_es_facturae_face/tests/test_facturae_face.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_es_facturae_face/tests/test_facturae_face.py b/l10n_es_facturae_face/tests/test_facturae_face.py index 9dcee7806c5..e336c9a620a 100644 --- a/l10n_es_facturae_face/tests/test_facturae_face.py +++ b/l10n_es_facturae_face/tests/test_facturae_face.py @@ -345,7 +345,7 @@ def consultarListadoFacturas(self, *args): self.move.refresh() self.assertIn( str(self.face_update_type.id), - self.move.expected_edi_configuration, + self.move.edi_config, ) try: self.move.edi_create_exchange_record(self.face_update_type.id) From 9c4bd490bde19e8354065a8c697232dd27d942e2 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Tue, 5 Oct 2021 15:39:56 +0200 Subject: [PATCH 069/101] [IMP] l10n_es_facturae: Add disable_edi_auto configuration --- .../components/account_move_l10n_es_facturae_listener.py | 2 ++ l10n_es_facturae_face/tests/test_facturae_face.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/l10n_es_facturae_face/components/account_move_l10n_es_facturae_listener.py b/l10n_es_facturae_face/components/account_move_l10n_es_facturae_listener.py index 109c38c3657..532586aa175 100644 --- a/l10n_es_facturae_face/components/account_move_l10n_es_facturae_listener.py +++ b/l10n_es_facturae_face/components/account_move_l10n_es_facturae_listener.py @@ -21,6 +21,8 @@ def _get_exchange_record_vals(self, record): def on_post_account_move(self, records): for record in records: + if record.disable_edi_auto: + continue partner = record.partner_id if record.move_type not in ["out_invoice", "out_refund"]: continue diff --git a/l10n_es_facturae_face/tests/test_facturae_face.py b/l10n_es_facturae_face/tests/test_facturae_face.py index e336c9a620a..9c9575f7766 100644 --- a/l10n_es_facturae_face/tests/test_facturae_face.py +++ b/l10n_es_facturae_face/tests/test_facturae_face.py @@ -284,7 +284,7 @@ def consultarListadoFacturas(self, *args): self.assertTrue(self.move.exchange_record_ids) self.assertIn( str(self.face_update_type.id), - self.move.expected_edi_configuration, + self.move.edi_config, ) with self.assertRaises(exceptions.UserError): self.move.edi_create_exchange_record(self.face_update_type.id) From e03b060a29b16a36161301685e7d1eef0a03c300 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sun, 12 Feb 2023 00:17:32 +0000 Subject: [PATCH 070/101] l10n_es_facturae_face 15.0.1.2.3 --- l10n_es_facturae_face/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index f58e0b3a15b..38c4df00577 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Envío de Facturae a FACe", - "version": "15.0.1.2.2", + "version": "15.0.1.2.3", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", "website": "https://github.com/OCA/l10n-spain", From 8054df06010c1c58c9f3abc342f53f31dc6b8633 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Tue, 24 May 2022 23:50:08 +0200 Subject: [PATCH 071/101] [IMP] l10n_es_facturae_face: remove edi_webservice dependancy --- l10n_es_facturae_face/__manifest__.py | 3 +-- l10n_es_facturae_face/components/__init__.py | 2 +- .../components/edi_send_l10n_es_facturae_face.py | 8 +++----- .../edi_send_l10n_es_facturae_face_cancel.py | 8 +++----- ...ice_receive_face_l10n_es_facturae_face_update.py | 8 +++----- l10n_es_facturae_face/components/webservice_face.py | 10 +++++----- l10n_es_facturae_face/data/face_data.xml | 10 +++------- l10n_es_facturae_face/models/__init__.py | 1 - l10n_es_facturae_face/models/edi_exchange_record.py | 7 +++++-- l10n_es_facturae_face/models/webservice_backend.py | 13 ------------- l10n_es_facturae_face/tests/test_facturae_face.py | 8 ++++++-- 11 files changed, 30 insertions(+), 48 deletions(-) delete mode 100644 l10n_es_facturae_face/models/webservice_backend.py diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index 38c4df00577..1b6e38e6e6e 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -3,14 +3,13 @@ { "name": "Envío de Facturae a FACe", - "version": "15.0.1.2.3", + "version": "15.0.2.0.0", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", "website": "https://github.com/OCA/l10n-spain", "license": "AGPL-3", "depends": [ "l10n_es_facturae", - "edi_webservice_oca", "edi_account_oca", "edi_exchange_template_oca", ], diff --git a/l10n_es_facturae_face/components/__init__.py b/l10n_es_facturae_face/components/__init__.py index 75a1b578bef..024795b27e6 100644 --- a/l10n_es_facturae_face/components/__init__.py +++ b/l10n_es_facturae_face/components/__init__.py @@ -1,6 +1,6 @@ +from . import webservice_face from . import account_move_l10n_es_facturae_listener from . import edi_send_l10n_es_facturae_face -from . import webservice_face from . import account_move_l10n_es_facturae_face_listener from . import edi_webservice_receive_face_l10n_es_facturae_face_update from . import edi_input_process_l10n_es_facturae_l10n_es_facturae_face_update diff --git a/l10n_es_facturae_face/components/edi_send_l10n_es_facturae_face.py b/l10n_es_facturae_face/components/edi_send_l10n_es_facturae_face.py index 35a469d5f63..cbf672b4ed9 100644 --- a/l10n_es_facturae_face/components/edi_send_l10n_es_facturae_face.py +++ b/l10n_es_facturae_face/components/edi_send_l10n_es_facturae_face.py @@ -7,11 +7,10 @@ class EdiOutputSendL10nEsFacturaeFace(Component): _name = "edi.output.send.l10n_es_facturae.l10n_es_facturae_face_output" - _usage = "webservice.send" + _usage = "output.send" _backend_type = "l10n_es_facturae" _exchange_type = "l10n_es_facturae" - _webservice_protocol = "face" - _inherit = "edi.component.send.mixin" + _inherit = ["edi.component.send.mixin", "base.webservice.face"] def _get_extra_attachment(self): return [] @@ -21,8 +20,7 @@ def send(self): public_crt, private_key = self.env["l10n.es.aeat.certificate"].get_certificates( invoice.company_id ) - response = self.backend.webservice_backend_id.call( - "send", + response = self.send_webservice( public_crt, private_key, self.exchange_record._get_file_content(), diff --git a/l10n_es_facturae_face/components/edi_send_l10n_es_facturae_face_cancel.py b/l10n_es_facturae_face/components/edi_send_l10n_es_facturae_face_cancel.py index 158ff9cd5da..392a0258ef9 100644 --- a/l10n_es_facturae_face/components/edi_send_l10n_es_facturae_face_cancel.py +++ b/l10n_es_facturae_face/components/edi_send_l10n_es_facturae_face_cancel.py @@ -9,11 +9,10 @@ class EdiOutputSendL10nEsFacturaeFace(Component): _name = "edi.output.send.l10n_es_facturae.l10n_es_facturae_face_cancel_output" - _usage = "webservice.send" + _usage = "output.send" _backend_type = "l10n_es_facturae" _exchange_type = "l10n_es_facturae_face_cancel" - _webservice_protocol = "face" - _inherit = "edi.component.send.mixin" + _inherit = ["edi.component.send.mixin", "base.webservice.face"] def send(self): move = self.exchange_record.record @@ -22,8 +21,7 @@ def send(self): public_crt, private_key = self.env["l10n.es.aeat.certificate"].get_certificates( move.company_id ) - self.backend.webservice_backend_id.call( - "cancel", + self.cancel( public_crt, private_key, parent.external_identifier, diff --git a/l10n_es_facturae_face/components/edi_webservice_receive_face_l10n_es_facturae_face_update.py b/l10n_es_facturae_face/components/edi_webservice_receive_face_l10n_es_facturae_face_update.py index 60bb1f193cf..3ea02adb70c 100644 --- a/l10n_es_facturae_face/components/edi_webservice_receive_face_l10n_es_facturae_face_update.py +++ b/l10n_es_facturae_face/components/edi_webservice_receive_face_l10n_es_facturae_face_update.py @@ -14,19 +14,17 @@ class EdiWebServiceReceiveFaceL10nEsFacturaeFaceUpdate(Component): _name = "edi.webservice.receive.face.l10n_es_facturae_face_update" - _usage = "webservice.receive" + _usage = "input.receive" _backend_type = "l10n_es_facturae" _exchange_type = "l10n_es_facturae_face_update" - _webservice_protocol = "face" - _inherit = "edi.component.receive.mixin" + _inherit = ["edi.component.receive.mixin", "base.webservice.face"] def receive(self): invoice = self.exchange_record.record public_crt, private_key = self.env["l10n.es.aeat.certificate"].get_certificates( invoice.company_id ) - response = self.backend.webservice_backend_id.call( - "consult_invoice", + response = self.consult_invoice( public_crt, private_key, self.exchange_record.parent_id.external_identifier, diff --git a/l10n_es_facturae_face/components/webservice_face.py b/l10n_es_facturae_face/components/webservice_face.py index f65f85853ee..d5d087ab424 100644 --- a/l10n_es_facturae_face/components/webservice_face.py +++ b/l10n_es_facturae_face/components/webservice_face.py @@ -25,9 +25,9 @@ class WebServiceFace(Component): _name = "base.webservice.face" - _usage = "webservice.request" - _webservice_protocol = "face" - _inherit = "base.webservice.adapter" + _usage = "face.protocol" + _backend_type = "l10n_es_facturae" + _inherit = "edi.component.mixin" def _get_client(self, public_crt, private_key): with open(public_crt, "rb") as f: @@ -37,7 +37,7 @@ def _get_client(self, public_crt, private_key): f.read(), None, backend=default_backend() ) return Client( - wsdl=self.collection.url, + wsdl=self.env["ir.config_parameter"].sudo().get_param("facturae.face.ws"), wsse=MemorySignature( cert, key, @@ -50,7 +50,7 @@ def _get_client(self, public_crt, private_key): ), ) - def send( + def send_webservice( self, public_crt, private_key, file_data, file_name, email, anexos_list=False ): client = self._get_client(public_crt, private_key) diff --git a/l10n_es_facturae_face/data/face_data.xml b/l10n_es_facturae_face/data/face_data.xml index 8310155a1fd..9ee93d43111 100644 --- a/l10n_es_facturae_face/data/face_data.xml +++ b/l10n_es_facturae_face/data/face_data.xml @@ -44,19 +44,15 @@ VVpMQ1ZCZk1VQlk3M1dOYXpWQW9qcVpoRzlkOHRBZ2cyYzY0bnVzdU1EWSsyNU1MVUtGenNiegpG Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCg== - - face - FACe + + facturae.face.ws https://se-face-webservice.redsara.es/facturasspp2?wsdl - face - application/xml FACe - diff --git a/l10n_es_facturae_face/models/__init__.py b/l10n_es_facturae_face/models/__init__.py index 3f51e96691e..7d6656a5412 100644 --- a/l10n_es_facturae_face/models/__init__.py +++ b/l10n_es_facturae_face/models/__init__.py @@ -4,4 +4,3 @@ from . import res_company from . import account_move from . import edi_exchange_record -from . import webservice_backend diff --git a/l10n_es_facturae_face/models/edi_exchange_record.py b/l10n_es_facturae_face/models/edi_exchange_record.py index 398beb2accf..91bd6e1e2c7 100644 --- a/l10n_es_facturae_face/models/edi_exchange_record.py +++ b/l10n_es_facturae_face/models/edi_exchange_record.py @@ -74,8 +74,11 @@ def _cron_face_update_method(self, company_domain=False): public_crt, private_key = self.env[ "l10n.es.aeat.certificate" ].get_certificates(company) - response = face.webservice_backend_id.call( - "consult_invoices", + response = face._find_component( + face._name, + ["face.protocol"], + work_ctx={"exchange_record": self.env["edi.exchange.record"]}, + ).consult_invoices( public_crt, private_key, exchanges, diff --git a/l10n_es_facturae_face/models/webservice_backend.py b/l10n_es_facturae_face/models/webservice_backend.py deleted file mode 100644 index 49d30846d1d..00000000000 --- a/l10n_es_facturae_face/models/webservice_backend.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2020 Creu Blanca -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import fields, models - - -class WebServiceBackend(models.Model): - - _inherit = "webservice.backend" - - protocol = fields.Selection( - selection_add=[("face", "FACe")], ondelete={"face": "cascade"} - ) diff --git a/l10n_es_facturae_face/tests/test_facturae_face.py b/l10n_es_facturae_face/tests/test_facturae_face.py index 9c9575f7766..63c3813c7b6 100644 --- a/l10n_es_facturae_face/tests/test_facturae_face.py +++ b/l10n_es_facturae_face/tests/test_facturae_face.py @@ -256,7 +256,9 @@ def consultarListadoFacturas(self, *args): return self.value self._activate_certificate(self.certificate_password) - client = Client(wsdl=self.env.ref("l10n_es_facturae_face.face_webservice").url) + client = Client( + wsdl=self.env["ir.config_parameter"].sudo().get_param("facturae.face.ws") + ) integration_code = "1234567890" response_ok = client.get_type("ns0:EnviarFacturaResponse")( client.get_type("ns0:Resultado")(codigo="0", descripcion="OK"), @@ -307,7 +309,9 @@ def consultarListadoFacturas(self, *args): return self.value self._activate_certificate(self.certificate_password) - client = Client(wsdl=self.env.ref("l10n_es_facturae_face.face_webservice").url) + client = Client( + wsdl=self.env["ir.config_parameter"].sudo().get_param("facturae.face.ws") + ) integration_code = "1234567890" response_ok = client.get_type("ns0:EnviarFacturaResponse")( client.get_type("ns0:Resultado")(codigo="0", descripcion="OK"), From 1030dd2460065ec37f69ef22388a68a050615ab3 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Mon, 28 Nov 2022 13:57:30 +0100 Subject: [PATCH 072/101] [OU] l10n_es_facturae_face: Add missing migration scripts --- .../migrations/15.0.2.0.0/post-migration.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 l10n_es_facturae_face/migrations/15.0.2.0.0/post-migration.py diff --git a/l10n_es_facturae_face/migrations/15.0.2.0.0/post-migration.py b/l10n_es_facturae_face/migrations/15.0.2.0.0/post-migration.py new file mode 100644 index 00000000000..24f8d289289 --- /dev/null +++ b/l10n_es_facturae_face/migrations/15.0.2.0.0/post-migration.py @@ -0,0 +1,19 @@ +# Copyright 2022 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + backend = env.ref("l10n_es_facturae_face.face_backend") + if "webservice_backend_id" in backend._fields: + backend.write({"webservice_backend_id": False}) + webservice = env.ref( + "l10n_es_facturae_face.face_webservice", raise_if_not_found=False + ) + if not webservice: + return + # As it was FACe, this was a problem. We need to change it.... + webservice.write({"protocol": "http"}) + env["ir.config_parameter"].sudo().set_param("facturae.face.ws", webservice.url) + webservice.unlink() From f3476f500620691c528de7b369e70c6183502dee Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Mon, 19 Dec 2022 19:16:07 +0100 Subject: [PATCH 073/101] [FIX] l10n_es_facturae_face: "Sending method" field is not displayed on partner's main view only in the child view The "Sending method" field is not displayed in the partner's view, so it is not possible to set it as "FACe" and therefore EDI records are not created when validating invoices --- l10n_es_facturae_face/readme/CONTRIBUTORS.rst | 2 ++ l10n_es_facturae_face/views/res_partner.xml | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 l10n_es_facturae_face/readme/CONTRIBUTORS.rst diff --git a/l10n_es_facturae_face/readme/CONTRIBUTORS.rst b/l10n_es_facturae_face/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..35c99e858e3 --- /dev/null +++ b/l10n_es_facturae_face/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Enric Tobella +* Eric Antones diff --git a/l10n_es_facturae_face/views/res_partner.xml b/l10n_es_facturae_face/views/res_partner.xml index 4eee7ad12d0..6c93055297b 100644 --- a/l10n_es_facturae_face/views/res_partner.xml +++ b/l10n_es_facturae_face/views/res_partner.xml @@ -7,9 +7,18 @@ res.partner - + - + + + + From ad82f1bbcc49ec8e2ac9b03d2690c1ce9c3da821 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Thu, 22 Jun 2023 17:51:12 +0200 Subject: [PATCH 074/101] [FIX] l10n_es_facturae_face: Set some record as noupdate False --- l10n_es_facturae_face/__manifest__.py | 3 +- l10n_es_facturae_face/data/edi.xml | 41 +++++++++++++++++++ l10n_es_facturae_face/data/edi_output.xml | 13 ------ l10n_es_facturae_face/data/face_data.xml | 31 -------------- .../migrations/15.0.2.1.0/post-migration.py | 22 ++++++++++ 5 files changed, 64 insertions(+), 46 deletions(-) delete mode 100644 l10n_es_facturae_face/data/edi_output.xml create mode 100644 l10n_es_facturae_face/migrations/15.0.2.1.0/post-migration.py diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index 1b6e38e6e6e..c7b4ccf4d37 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Envío de Facturae a FACe", - "version": "15.0.2.0.0", + "version": "15.0.2.1.0", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", "website": "https://github.com/OCA/l10n-spain", @@ -17,7 +17,6 @@ "security/ir.model.access.csv", "data/edi.xml", "data/face_data.xml", - "data/edi_output.xml", "data/cron_data.xml", "wizards/edi_l10n_es_facturae_face_cancel.xml", "views/account_move.xml", diff --git a/l10n_es_facturae_face/data/edi.xml b/l10n_es_facturae_face/data/edi.xml index 06f5f6e8ef1..1507460e2c6 100644 --- a/l10n_es_facturae_face/data/edi.xml +++ b/l10n_es_facturae_face/data/edi.xml @@ -20,4 +20,45 @@ name="enable_snippet" >result = not record._has_exchange_record(exchange_type) + + FACe + + + + + Update Facturae FACe + l10n_es_facturae_face_update + + + input + {record_name}--{dt} + json + + [('state', '!=', 'draft'), ('partner_id.l10n_es_facturae_sending_code', '=', "face")] + + result = record._has_exchange_record(record.env.ref("l10n_es_facturae_face.facturae_exchange_type"), record.env.ref("l10n_es_facturae_face.face_backend")) + + + Cancel Facturae FACe + l10n_es_facturae_face_cancel + + + output + {record_name}--{dt} + txt + + + Facturae output + + + l10n_es_facturae.facturae_file + xsig + report + + result = {"res_ids": record.ids} + diff --git a/l10n_es_facturae_face/data/edi_output.xml b/l10n_es_facturae_face/data/edi_output.xml deleted file mode 100644 index 890dfb13d70..00000000000 --- a/l10n_es_facturae_face/data/edi_output.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - Facturae output - - - l10n_es_facturae.facturae_file - xsig - report - - result = {"res_ids": record.ids} - - diff --git a/l10n_es_facturae_face/data/face_data.xml b/l10n_es_facturae_face/data/face_data.xml index 9ee93d43111..67a83c8986b 100644 --- a/l10n_es_facturae_face/data/face_data.xml +++ b/l10n_es_facturae_face/data/face_data.xml @@ -50,35 +50,4 @@ Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KCg== name="value" >https://se-face-webservice.redsara.es/facturasspp2?wsdl - - FACe - - - - - Update Facturae FACe - l10n_es_facturae_face_update - - - input - {record_name}--{dt} - json - - [('state', '!=', 'draft'), ('partner_id.l10n_es_facturae_sending_code', '=', "face")] - - result = record._has_exchange_record(record.env.ref("l10n_es_facturae_face.facturae_exchange_type"), record.env.ref("l10n_es_facturae_face.face_backend")) - - - Cancel Facturae FACe - l10n_es_facturae_face_cancel - - - output - {record_name}--{dt} - txt - diff --git a/l10n_es_facturae_face/migrations/15.0.2.1.0/post-migration.py b/l10n_es_facturae_face/migrations/15.0.2.1.0/post-migration.py new file mode 100644 index 00000000000..a3eadf5d5df --- /dev/null +++ b/l10n_es_facturae_face/migrations/15.0.2.1.0/post-migration.py @@ -0,0 +1,22 @@ +# Copyright 2022 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.set_xml_ids_noupdate_value( + env, + "l10n_es_facturae_face", + [ + "face_backend", + "facturae_face_update_exchange_type", + "facturae_face_cancel_exchange_type", + ], + False, + ) + openupgrade.load_data( + env.cr, + "l10n_es_facturae_face", + "data/edi.xml", + ) From 261b2bf8dc4b9a4fda9a983cb35f9c2fac49db10 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 27 Jun 2023 16:20:24 +0000 Subject: [PATCH 075/101] [UPD] Update l10n_es_facturae_face.pot --- l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot b/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot index 4e438a4df44..7795132b3e4 100644 --- a/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot +++ b/l10n_es_facturae_face/i18n/l10n_es_facturae_face.pot @@ -116,7 +116,6 @@ msgstr "" #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__res_partner__l10n_es_facturae_sending_code__face -#: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__webservice_backend__protocol__face msgid "FACe" msgstr "" @@ -233,11 +232,6 @@ msgstr "" msgid "Paid" msgstr "" -#. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_webservice_backend__protocol -msgid "Protocol" -msgstr "" - #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__account_move__l10n_es_facturae_status__face-1300 msgid "Registered on RCF" @@ -270,8 +264,3 @@ msgstr "" #, python-format msgid "Vat must be defined in order to send to FACe" msgstr "" - -#. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_webservice_backend -msgid "WebService Backend" -msgstr "" From c01fc7cd65fe10c25828ea4532261d0c0f5b754c Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 27 Jun 2023 16:34:01 +0000 Subject: [PATCH 076/101] [UPD] README.rst --- l10n_es_facturae_face/README.rst | 6 ++++++ l10n_es_facturae_face/static/description/index.html | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/l10n_es_facturae_face/README.rst b/l10n_es_facturae_face/README.rst index 0ed027682b3..48530f8f572 100644 --- a/l10n_es_facturae_face/README.rst +++ b/l10n_es_facturae_face/README.rst @@ -108,6 +108,12 @@ Authors * Creu Blanca +Contributors +~~~~~~~~~~~~ + +* Enric Tobella +* Eric Antones + Maintainers ~~~~~~~~~~~ diff --git a/l10n_es_facturae_face/static/description/index.html b/l10n_es_facturae_face/static/description/index.html index 7eee7685042..18fe2032eaf 100644 --- a/l10n_es_facturae_face/static/description/index.html +++ b/l10n_es_facturae_face/static/description/index.html @@ -380,7 +380,8 @@

Envío de Facturae a FACe

  • Bug Tracker
  • Credits
  • @@ -453,8 +454,15 @@

    Authors

  • Creu Blanca
  • +
    +

    Contributors

    + +
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association

    OCA, or the Odoo Community Association, is a nonprofit organization whose From 56d231f91765f64a0e076e5343a5d9c741cbf5ae Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 27 Jun 2023 16:34:24 +0000 Subject: [PATCH 077/101] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: l10n-spain-15.0/l10n-spain-15.0-l10n_es_facturae_face Translate-URL: https://translation.odoo-community.org/projects/l10n-spain-15-0/l10n-spain-15-0-l10n_es_facturae_face/ --- l10n_es_facturae_face/i18n/ca.po | 15 +++++---------- l10n_es_facturae_face/i18n/es.po | 11 ----------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/l10n_es_facturae_face/i18n/ca.po b/l10n_es_facturae_face/i18n/ca.po index 1c9e693b9b6..a8fbfa545f3 100644 --- a/l10n_es_facturae_face/i18n/ca.po +++ b/l10n_es_facturae_face/i18n/ca.po @@ -119,7 +119,6 @@ msgstr "FACe no pot trobar el registre d'intercanvi" #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__res_partner__l10n_es_facturae_sending_code__face -#: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__webservice_backend__protocol__face msgid "FACe" msgstr "FACe" @@ -236,11 +235,6 @@ msgstr "OK" msgid "Paid" msgstr "" -#. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_webservice_backend__protocol -msgid "Protocol" -msgstr "Protocol" - #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__account_move__l10n_es_facturae_status__face-1300 msgid "Registered on RCF" @@ -274,10 +268,11 @@ msgstr "Cal definir la província d'Espanya per a enviar a FACe" msgid "Vat must be defined in order to send to FACe" msgstr "Cal definir el NIF per a enviar per FACe" -#. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_webservice_backend -msgid "WebService Backend" -msgstr "WebService Backend" +#~ msgid "Protocol" +#~ msgstr "Protocol" + +#~ msgid "WebService Backend" +#~ msgstr "WebService Backend" #~ msgid "Edi L10n Es Facturae Face Cancel" #~ msgstr "Cancelar l10n es Facturae FACe" diff --git a/l10n_es_facturae_face/i18n/es.po b/l10n_es_facturae_face/i18n/es.po index 573d70f69af..75903bd0a54 100644 --- a/l10n_es_facturae_face/i18n/es.po +++ b/l10n_es_facturae_face/i18n/es.po @@ -119,7 +119,6 @@ msgstr "" #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__res_partner__l10n_es_facturae_sending_code__face -#: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__webservice_backend__protocol__face msgid "FACe" msgstr "" @@ -236,11 +235,6 @@ msgstr "" msgid "Paid" msgstr "Pagado" -#. module: l10n_es_facturae_face -#: model:ir.model.fields,field_description:l10n_es_facturae_face.field_webservice_backend__protocol -msgid "Protocol" -msgstr "" - #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__account_move__l10n_es_facturae_status__face-1300 msgid "Registered on RCF" @@ -275,8 +269,3 @@ msgstr "" #, python-format msgid "Vat must be defined in order to send to FACe" msgstr "El identificador fiscal debe estar definido para poder enviar por FACe" - -#. module: l10n_es_facturae_face -#: model:ir.model,name:l10n_es_facturae_face.model_webservice_backend -msgid "WebService Backend" -msgstr "" From ad6e3f7d8982334a01e47db3a89685f925983ee3 Mon Sep 17 00:00:00 2001 From: Ivorra78 Date: Wed, 5 Jul 2023 16:20:15 +0000 Subject: [PATCH 078/101] Translated using Weblate (Spanish) Currently translated at 100.0% (47 of 47 strings) Translation: l10n-spain-15.0/l10n-spain-15.0-l10n_es_facturae_face Translate-URL: https://translation.odoo-community.org/projects/l10n-spain-15-0/l10n-spain-15-0-l10n_es_facturae_face/es/ --- l10n_es_facturae_face/i18n/es.po | 55 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/l10n_es_facturae_face/i18n/es.po b/l10n_es_facturae_face/i18n/es.po index 75903bd0a54..28dae05b88a 100644 --- a/l10n_es_facturae_face/i18n/es.po +++ b/l10n_es_facturae_face/i18n/es.po @@ -7,14 +7,15 @@ msgstr "" "Project-Id-Version: Odoo Server 15.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-07-06 09:06+0000\n" -"PO-Revision-Date: 2022-07-06 09:06+0000\n" -"Last-Translator: \n" +"PO-Revision-Date: 2023-07-05 19:08+0000\n" +"Last-Translator: Ivorra78 \n" "Language-Team: \n" -"Language: \n" +"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__account_move__l10n_es_facturae_status__face-2400 @@ -24,18 +25,18 @@ msgstr "Aceptado" #. module: l10n_es_facturae_face #: model_terms:ir.ui.view,arch_db:l10n_es_facturae_face.edi_l10n_es_facturae_face_cancel_form_view msgid "Cancel" -msgstr "" +msgstr "cancelar" #. module: l10n_es_facturae_face #: model:ir.actions.act_window,name:l10n_es_facturae_face.edi_l10n_es_facturae_face_cancel_act_window #: model_terms:ir.ui.view,arch_db:l10n_es_facturae_face.view_move_form msgid "Cancel FACe" -msgstr "" +msgstr "Cancelar FACe" #. module: l10n_es_facturae_face #: model:ir.model,name:l10n_es_facturae_face.model_edi_l10n_es_facturae_face_cancel msgid "Cancel a FACe Exchange Record" -msgstr "" +msgstr "Cancelar un registro de intercambio FACe" #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__account_move__l10n_es_facturae_cancellation_status__face-4300 @@ -73,7 +74,7 @@ msgstr "La compañía %s no puede procesarse" #: code:addons/l10n_es_facturae_face/components/webservice_face.py:0 #, python-format msgid "Connection with FACe returned error %(code)s - %(description)s" -msgstr "" +msgstr "La conexión con FACe devolvió error %(code)s-%(description)s" #. module: l10n_es_facturae_face #: model:ir.model,name:l10n_es_facturae_face.model_res_partner @@ -89,12 +90,12 @@ msgstr "Se debe definir el país para poder enviar por FACe" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_l10n_es_facturae_face_cancel__create_uid msgid "Created by" -msgstr "" +msgstr "creado por" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_l10n_es_facturae_face_cancel__create_date msgid "Created on" -msgstr "" +msgstr "creado el" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_l10n_es_facturae_face_cancel__display_name @@ -104,23 +105,23 @@ msgstr "Nombre mostrado" #. module: l10n_es_facturae_face #: model:ir.model,name:l10n_es_facturae_face.model_edi_exchange_record msgid "EDI exchange Record" -msgstr "" +msgstr "Registro de intercambio EDI" #. module: l10n_es_facturae_face #: model_terms:ir.ui.view,arch_db:l10n_es_facturae_face.edi_l10n_es_facturae_face_cancel_form_view msgid "Edi L10n Es Facturae FACe Cancel" -msgstr "" +msgstr "Edi L10n Es Facturae FACe Cancelar" #. module: l10n_es_facturae_face #: code:addons/l10n_es_facturae_face/components/account_move_l10n_es_facturae_face_listener.py:0 #, python-format msgid "Exchange record cannot be found for FACe" -msgstr "" +msgstr "No se encuentra el registro de intercambio para FACe" #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__res_partner__l10n_es_facturae_sending_code__face msgid "FACe" -msgstr "" +msgstr "FACe" #. module: l10n_es_facturae_face #: model:ir.actions.server,name:l10n_es_facturae_face.update_face_job_ir_actions_server @@ -137,34 +138,34 @@ msgstr "Email FACe" #. module: l10n_es_facturae_face #: model_terms:ir.ui.view,arch_db:l10n_es_facturae_face.edi_exchange_record_view_form msgid "Facturae" -msgstr "" +msgstr "Facturae(factura electrónica)" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_exchange_record__l10n_es_facturae_cancellation_motive msgid "Facturae Cancellation motive" -msgstr "" +msgstr "Motivo de anulación Facturae" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_exchange_record__l10n_es_facturae_cancellation_status msgid "Facturae Cancellation state" -msgstr "" +msgstr "Estado de anulación Facturae" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_exchange_record__l10n_es_facturae_status msgid "Facturae State" -msgstr "" +msgstr "estado de Facturae" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_bank_statement_line__l10n_es_facturae_cancellation_status #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_move__l10n_es_facturae_cancellation_status #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_payment__l10n_es_facturae_cancellation_status msgid "Facturae cancellation status" -msgstr "" +msgstr "Estado de cancelación de la facturae" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_exchange_record__l10n_es_facturae_motive msgid "Facturae description" -msgstr "" +msgstr "descripción de la facturae" #. module: l10n_es_facturae_face #: code:addons/l10n_es_facturae_face/models/res_partner.py:0 @@ -177,12 +178,12 @@ msgstr "Se debe seleccionar el campo facturae para poder enviar por FACe" #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_move__l10n_es_facturae_status #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_account_payment__l10n_es_facturae_status msgid "Facturae status" -msgstr "" +msgstr "estado de la facturae" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_l10n_es_facturae_face_cancel__id msgid "ID" -msgstr "" +msgstr "ID(identificador)" #. module: l10n_es_facturae_face #: code:addons/l10n_es_facturae_face/models/res_company.py:0 @@ -203,12 +204,12 @@ msgstr "Última modificación el" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_l10n_es_facturae_face_cancel__write_uid msgid "Last Updated by" -msgstr "" +msgstr "actualizado por última vez por" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_l10n_es_facturae_face_cancel__write_date msgid "Last Updated on" -msgstr "" +msgstr "actualizado por última vez el" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_l10n_es_facturae_face_cancel__motive @@ -218,7 +219,7 @@ msgstr "Motivo" #. module: l10n_es_facturae_face #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_edi_l10n_es_facturae_face_cancel__move_id msgid "Move" -msgstr "" +msgstr "Mover" #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__account_move__l10n_es_facturae_cancellation_status__face-4100 @@ -228,7 +229,7 @@ msgstr "No solicitado" #. module: l10n_es_facturae_face #: model_terms:ir.ui.view,arch_db:l10n_es_facturae_face.edi_l10n_es_facturae_face_cancel_form_view msgid "OK" -msgstr "" +msgstr "Aceptar" #. module: l10n_es_facturae_face #: model:ir.model.fields.selection,name:l10n_es_facturae_face.selection__account_move__l10n_es_facturae_status__face-2500 @@ -254,7 +255,7 @@ msgstr "Rechazado" #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_partner__l10n_es_facturae_sending_code #: model:ir.model.fields,field_description:l10n_es_facturae_face.field_res_users__l10n_es_facturae_sending_code msgid "Sending method" -msgstr "" +msgstr "Método de envío" #. module: l10n_es_facturae_face #: code:addons/l10n_es_facturae_face/models/res_partner.py:0 From 54e4eb43446a047c089a442f37c58df498543f54 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Sat, 19 Aug 2023 15:38:31 +0200 Subject: [PATCH 079/101] [FIX] l10n_es_facturae_face: buttons where hidden if not coming from an ancient version --- l10n_es_facturae_face/data/edi.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/l10n_es_facturae_face/data/edi.xml b/l10n_es_facturae_face/data/edi.xml index 1507460e2c6..2f898debf09 100644 --- a/l10n_es_facturae_face/data/edi.xml +++ b/l10n_es_facturae_face/data/edi.xml @@ -11,6 +11,7 @@ output {record_name}--{dt} xsig + input {record_name}--{dt} + json Date: Sat, 19 Aug 2023 16:10:22 +0000 Subject: [PATCH 080/101] l10n_es_facturae_face 15.0.2.2.0 --- l10n_es_facturae_face/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_es_facturae_face/__manifest__.py b/l10n_es_facturae_face/__manifest__.py index c7b4ccf4d37..1150225f7c7 100644 --- a/l10n_es_facturae_face/__manifest__.py +++ b/l10n_es_facturae_face/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Envío de Facturae a FACe", - "version": "15.0.2.1.0", + "version": "15.0.2.2.0", "author": "Creu Blanca, " "Odoo Community Association (OCA)", "category": "Accounting & Finance", "website": "https://github.com/OCA/l10n-spain", From f02976580478f783a3810e5884abfcc5aab1e7fb Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sun, 3 Sep 2023 14:03:36 +0000 Subject: [PATCH 081/101] [UPD] README.rst --- l10n_es_facturae_face/README.rst | 15 +++--- .../static/description/index.html | 52 ++++++++++--------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/l10n_es_facturae_face/README.rst b/l10n_es_facturae_face/README.rst index 48530f8f572..ec20ef612fb 100644 --- a/l10n_es_facturae_face/README.rst +++ b/l10n_es_facturae_face/README.rst @@ -2,10 +2,13 @@ Envío de Facturae a FACe ======================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:23e9d0ad7bfd0550b4e20642604d75e947550ae65de00ea9525aeb98c6b9b987 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Envío de Facturae a FACe .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/l10n-spain-15-0/l10n-spain-15-0-l10n_es_facturae_face :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/189/15.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-spain&target_branch=15.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| Este módulo permite la gestión del envío de la facturación electrónica española a FACe. @@ -95,7 +98,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed +If you spotted it first, help us to smash it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. diff --git a/l10n_es_facturae_face/static/description/index.html b/l10n_es_facturae_face/static/description/index.html index 18fe2032eaf..d6d2802845d 100644 --- a/l10n_es_facturae_face/static/description/index.html +++ b/l10n_es_facturae_face/static/description/index.html @@ -1,20 +1,20 @@ - + - + Envío de Facturae a FACe