Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cambios Varios #59

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 52 additions & 201 deletions l10n_ec_account_edi/i18n/es.po

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions l10n_ec_account_edi/models/account_edi_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class AccountEdiDocument(models.Model):
compute="_compute_l10n_ec_document_data",
store=True,
)
l10n_ec_partner_vat = fields.Char(related="l10n_ec_partner_id.vat", string="Ced/RUC", readonly=True)
l10n_ec_partner_email = fields.Char(related="l10n_ec_partner_id.email", string="Customer Email", readonly=True)

@api.depends("move_id")
def _compute_l10n_ec_document_data(self):
Expand Down Expand Up @@ -205,13 +207,10 @@ def _l10n_ec_get_info_tributaria(self, document):
company,
)
self.l10n_ec_xml_access_key = xml_access_key
social_name = "PRUEBAS SERVICIO DE RENTAS INTERNAS"
business_name = "PRUEBAS SERVICIO DE RENTAS INTERNAS"
if environment == "2":
social_name = self._l10n_ec_clean_str(company.partner_id.name)
business_name = self._l10n_ec_clean_str(
company.partner_id.l10n_ec_business_name or social_name
)

social_name = self._l10n_ec_clean_str(company.partner_id.name)
business_name = self._l10n_ec_clean_str(company.partner_id.l10n_ec_business_name or social_name)

data = {
"ambiente": environment,
"tipoEmision": "1", # emision normal, SRI no acepta contingencia
Expand Down
8 changes: 7 additions & 1 deletion l10n_ec_account_edi/models/account_edi_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ def _l10n_ec_post_move_edi(self, documents):
auth_client = self._l10n_ec_get_edi_ws_client(
company.l10n_ec_type_environment, "authorization"
)
# Si no hay conector (Ambiente=none), sale sin hacer nada
if client_send is None or auth_client is None:
return res

for document in documents:
edi_docs = document.edi_document_ids.filtered(
lambda x: x.edi_format_id.code in ("l10n_ec_format_sri",)
Expand Down Expand Up @@ -335,7 +339,9 @@ def _l10n_ec_get_edi_ws_client(self, environment, url_type):
# es necesario que se cree una sola instancia
# Para conexion y asi evitar un reinicio constante de la comunicacion
wsClient = None
if environment == "test":
if environment == "none":
return None
elif environment == "test":
ws_url = TEST_URL.get(url_type)
elif environment == "production":
ws_url = PRODUCTION_URL.get(url_type)
Expand Down
3 changes: 2 additions & 1 deletion l10n_ec_account_edi/models/res_company.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ class ResCompany(models.Model):

l10n_ec_type_environment = fields.Selection(
[
("none", "No Send"),
("test", "Test"),
("production", "Production"),
],
string="Environment type for electronic documents",
default="test",
default="none",
)
l10n_ec_key_type_id = fields.Many2one(
comodel_name="sri.key.type",
Expand Down
49 changes: 34 additions & 15 deletions l10n_ec_account_edi/models/sri_key_type.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import logging
import subprocess
from base64 import b64decode
import datetime
from base64 import b64encode, b64decode
from random import randrange
from tempfile import NamedTemporaryFile

import xmlsig # pylint: disable=W7936
from cryptography.hazmat.primitives import serialization # pylint: disable=W7936
from cryptography.hazmat.primitives.serialization import pkcs12 # pylint: disable=W7936
from cryptography.x509 import ExtensionNotFound # pylint: disable=W7936
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.x509 import load_pem_x509_certificate, ExtensionNotFound # pylint: disable=W7936
from cryptography.x509.oid import ExtensionOID, NameOID # pylint: disable=W7936
from lxml import etree
from xades import XAdESContext, template # pylint: disable=W7936
from xades.policy import ImpliedPolicy # pylint: disable=W7936


from odoo import fields, models, tools
from odoo.exceptions import UserError
from odoo.tools.translate import _


_logger = logging.getLogger(__name__)

KEY_TO_PEM_CMD = (
Expand All @@ -43,7 +47,7 @@ class SriKeyType(models.Model):
_name = "sri.key.type"
_description = "Type of electronic key"

name = fields.Char(size=255, required=True, readonly=False)
name = fields.Char(size=255, default="Nuevo", required=True, readonly=False)
file_content = fields.Binary(string="Signature File")
file_name = fields.Char(string="Filename", readonly=True)
password = fields.Char(string="Signing key")
Expand Down Expand Up @@ -73,6 +77,10 @@ class SriKeyType(models.Model):
)
cert_version = fields.Char(string="Version", readonly=True)

# Almacenar certificados por separado para no procesar el archivo p12 siempre
p_key = fields.Binary("Private Key", readonly=True, attachment=False, required=True, default='p_key')
cert = fields.Binary("X509 Certificate", readonly=True, attachment=False, required=True, default='cert')

@tools.ormcache("self.file_content", "self.password", "self.state")
def _decode_certificate(self):
self.ensure_one()
Expand Down Expand Up @@ -127,14 +135,11 @@ def _decode_certificate(self):
private_key_str = private_key_str[start_index:]
start_index = private_key_str.find("-----BEGIN ENCRYPTED PRIVATE KEY-----")
private_key_str = private_key_str[start_index:]
private_key = serialization.load_pem_private_key(
private_key_str.encode(),
self.password.encode(),
)
return private_key, certificate

return private_key_str, certificate

def action_validate_and_load(self):
_private_key, cert = self._decode_certificate()
private_key_str, cert = self._decode_certificate()
issuer = cert.issuer
subject = cert.subject
subject_common_name = (
Expand All @@ -152,19 +157,21 @@ def action_validate_and_load(self):
if subject.get_attributes_for_oid(NameOID.COMMON_NAME)
else ""
)
caduca = fields.Datetime.context_timestamp(self, cert.not_valid_after).date()
vals = {
"name": f"{subject_common_name} - {caduca}",
"issue_date": fields.Datetime.context_timestamp(
self, cert.not_valid_before
).date(),
"expire_date": fields.Datetime.context_timestamp(
self, cert.not_valid_after
).date(),
"expire_date": caduca,
"subject_common_name": subject_common_name,
"subject_serial_number": subject_serial_number,
"issuer_common_name": issuer_common_name,
"cert_serial_number": cert.serial_number,
"cert_serial_number": "%0.8X" % cert.serial_number,
"cert_version": cert.version,
"state": "valid",
"p_key": b64encode(private_key_str.encode()),
"cert": b64encode(cert.public_bytes(serialization.Encoding.PEM)),
}
self.write(vals)
return True
Expand All @@ -173,7 +180,11 @@ def action_sign(self, xml_string_data):
def new_range():
return randrange(100000, 999999)

p12 = self._decode_certificate()
#current_time = datetime.datetime.utcnow().microsecond

private_key = load_pem_private_key(b64decode(self.p_key), password=self.password.encode())
public_cert = load_pem_x509_certificate(b64decode(self.cert))

doc = etree.fromstring(xml_string_data)
signature_id = f"Signature{new_range()}"
signature_property_id = f"{signature_id}-SignedPropertiesID{new_range()}"
Expand Down Expand Up @@ -217,8 +228,16 @@ def new_range():
mime_type="text/xml",
)
doc.append(signature)


ctx = XAdESContext(ImpliedPolicy(xmlsig.constants.TransformSha1))
ctx.load_pkcs12(p12)
ctx.x509 = public_cert
ctx.public_key = public_cert.public_key()
ctx.private_key = private_key
ctx.sign(signature)
ctx.verify(signature)

#lapso = datetime.datetime.utcnow().microsecond - current_time
#print("Lapso: ", lapso)

return etree.tostring(doc, encoding="UTF-8", pretty_print=True).decode()
6 changes: 4 additions & 2 deletions l10n_ec_account_edi/views/account_edi_document_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
expr="//field[@name='edi_document_ids']/tree//field[@name='state']"
position="before"
>
<field name="l10n_ec_xml_access_key" optional="hide" />
<field name="l10n_ec_authorization_date" optional="hide" />
<field name="l10n_ec_xml_access_key" optional="show" />
<field name="l10n_ec_authorization_date" optional="show" />
<field name="l10n_ec_last_sent_date" optional="hide" />
</xpath>
</field>
Expand Down Expand Up @@ -61,6 +61,8 @@
<field name="l10n_ec_xml_access_key" />
<field name="move_id" string="Related Document" />
<field name="l10n_ec_partner_id" />
<field name="l10n_ec_partner_vat" />
<field name="l10n_ec_partner_email" />
<field name="l10n_ec_document_date" />
<field name="state" />
<field name="l10n_ec_authorization_date" />
Expand Down
3 changes: 3 additions & 0 deletions l10n_ec_base/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"version": "17.0.1.0.0",
"depends": ["l10n_ec", "account"],
"data": [
"data/l10n_latam_identification_type_data.xml" ,
"data/res_partner_data.xml",
"data/res.bank.csv",
"wizard/account_payment_register_views.xml",
"views/account_tax_view.xml",
"views/account_journal_view.xml",
Expand Down
13 changes: 13 additions & 0 deletions l10n_ec_base/data/l10n_latam_identification_type_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<record id='l10n_latam_base.it_vat' model='l10n_latam.identification.type'>
<field name='name'>VAT</field>
<field name='active' eval="False"/>
</record>

<record id='l10n_ec.ec_passport' model='l10n_latam.identification.type'>
<field name='active' eval="False"/>
</record>
</data>
</odoo>
Loading
Loading