From 19abe9fc89e55f2bd74e6cfc5730d6ead8dfb164 Mon Sep 17 00:00:00 2001 From: maiconkkl Date: Tue, 2 Jul 2019 00:33:01 -0300 Subject: [PATCH 1/3] =?UTF-8?q?Criando=20parametros=20para=20conting=C3=AA?= =?UTF-8?q?ncia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foi criado no template de autorização de NF-e o parametros: dhCont = Data que o sistema entrou em contingência; xJust = O motivo do sistema ter entrado em contingência. E foi alterado versão --- pytrustnfe/nfe/templates/NfeAutorizacao.xml | 4 ++++ setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pytrustnfe/nfe/templates/NfeAutorizacao.xml b/pytrustnfe/nfe/templates/NfeAutorizacao.xml index 0eb2e3c..84dc8f5 100644 --- a/pytrustnfe/nfe/templates/NfeAutorizacao.xml +++ b/pytrustnfe/nfe/templates/NfeAutorizacao.xml @@ -28,6 +28,10 @@ {{ ide.indPres }} {{ ide.procEmi }} Odoo Brasil 10 + {% if ide.tpEmis != 1 %} + {{ ide.dhCont }} + {{ ide.xJust }} + {% endif %} {% if ide.NFref is defined -%} {% for ref in ide.NFref %} diff --git a/setup.py b/setup.py index 84578c5..9bb22a2 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages -VERSION = "1.0.40" +VERSION = "1.0.41" setup( From ca0cc25b2440cf141d9c5f42a3115087c1d1c9da Mon Sep 17 00:00:00 2001 From: maiconkkl Date: Mon, 22 Jul 2019 02:15:44 -0300 Subject: [PATCH 2/3] =?UTF-8?q?Gera=C3=A7=C3=A3o=20do=20QRCode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foi alterado para gerar o QRCode pelo pytrustnfe ou manter da forma antiga sem afetar os usuarios que prefere gerar manualmente. Foi alterado a função de assinatura para que possa retornar o etree ou string. --- pytrustnfe/nfe/__init__.py | 88 +++++++++++++++++++++++++++++++++++++++++--- pytrustnfe/nfe/assinatura.py | 4 +- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/pytrustnfe/nfe/__init__.py b/pytrustnfe/nfe/__init__.py index 1a5b9c0..eee228e 100644 --- a/pytrustnfe/nfe/__init__.py +++ b/pytrustnfe/nfe/__init__.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- # © 2016 Danimar Ribeiro, Trustcode # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - - +import hashlib import os import requests from lxml import etree @@ -11,10 +10,9 @@ from .assinatura import Assinatura from pytrustnfe.xml import render_xml, sanitize_response from pytrustnfe.utils import gerar_chave, ChaveNFe from pytrustnfe.Servidores import localizar_url +from pytrustnfe.urls import url_qrcode, url_qrcode_exibicao from pytrustnfe.certificado import extract_cert_and_key_from_pfx, save_cert_key from requests.packages.urllib3.exceptions import InsecureRequestWarning - - # Zeep from requests import Session from zeep import Client @@ -42,6 +40,10 @@ def _generate_nfe_id(**kwargs): def _render(certificado, method, sign, **kwargs): path = os.path.join(os.path.dirname(__file__), 'templates') + if sign and kwargs['ide']['mod'] == '65': + kwargs['qrCode'] = 1 if 'qrCode' not in kwargs else kwargs['qrCode'] + kwargs['urlChave'] = 1 \ + if 'urlChave' not in kwargs else kwargs['urlChave'] xmlElem_send = render_xml(path, '%s.xml' % method, True, **kwargs) modelo = xmlElem_send.find(".//{http://www.portalfiscal.inf.br/nfe}mod") @@ -53,7 +55,83 @@ def _render(certificado, method, sign, **kwargs): xml_send = signer.assina_xml(xmlElem_send, kwargs['obj']['id']) if method == 'NfeAutorizacao': xml_send = signer.assina_xml( - xmlElem_send, kwargs['NFes'][0]['infNFe']['Id']) + xmlElem_send, kwargs['NFes'][0]['infNFe']['Id'], True) + if modelo == '65' and 'urlChave' not in kwargs and 'qrCode' not in\ + kwargs: + if kwargs['ide']['tpEmis'] != 1: + digest_value = xmlElem_send.find( + ".//{http://www.w3.org/2000/09/xmldsig#}DigestValue") + c_hash_qr_code = \ + "{ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \ + "{v_nf}|{dig_val}|{id_csc}|{csc}".format( + ch_acesso=kwargs['NFe']['infNFe']['Id'].replace('NFe', ''), + versao=2, + tp_amb=kwargs['ide']['tpAmb'], + dh_emi=kwargs['ide']['dhEmi'].split("-")[2].split("T")[0], + v_nf=kwargs['total']['vNF'], + dig_val=digest_value.text, + id_csc=int(kwargs['id_csc']), + csc=kwargs['csc'] + ) + c_hash_qr_code = hashlib.sha1(c_hash_qr_code.encode()). \ + hexdigest() + qr_code_url = 'p={ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \ + "{v_nf}|{dig_val}|{id_csc}|{hash}'.format( + ch_acesso=kwargs['NFe']['infNFe']['Id']. + replace('NFe', ''), + versao=2, + tp_amb=kwargs['ide']['tpAmb'], + dh_emi=kwargs['ide']['dhEmi'].split("-")[2]. + split("T")[0], + v_nf=kwargs['total']['vNF'], + dig_val=digest_value.text, + id_csc=int(kwargs['id_csc']), + hash=c_hash_qr_code + ) + qrcode = url_qrcode( + kwargs['emit']['enderEmit']['UF'], + str(kwargs['ide']['tpAmb']) + ) + qr_code_url + url_consulta = url_qrcode_exibicao( + kwargs['emit']['enderEmit']['UF'], + str(kwargs['ide']['tpAmb']) + ) + else: + c_hash_qr_code = \ + "{ch_acesso}|{versao}|{tp_amb}|{id_csc}|{csc}".format( + ch_acesso=kwargs['NFe']['infNFe']['Id']. + replace('NFe', ''), + versao=2, + tp_amb=kwargs['ide']['tpAmb'], + id_csc=int(kwargs['id_csc']), + csc=kwargs['csc'] + ) + c_hash_qr_code = hashlib.sha1( + c_hash_qr_code.encode()).hexdigest() + qr_code_url = "p={ch_acesso}|{versao}|{tp_amb}|{id_csc}|" \ + "{hash}".format( + ch_acesso=kwargs['NFe']['infNFe']['Id'] + .replace('NFe', ''), + versao=2, + tp_amb=kwargs['ide']['tpAmb'], + id_csc=int(kwargs['id_csc']), + hash=c_hash_qr_code + ) + qrcode = url_qrcode( + kwargs['emit']['enderEmit']['UF'], + str(kwargs['ide']['tpAmb']) + ) + qr_code_url + url_consulta = url_qrcode_exibicao( + kwargs['emit']['enderEmit']['UF'], + str(kwargs['ide']['tpAmb']) + ) + qrCode = xml_send.find( + './/{http://www.portalfiscal.inf.br/nfe}qrCode').text = \ + qrcode + urlChave = xml_send.find( + './/{http://www.portalfiscal.inf.br/nfe}urlChave').text = \ + url_consulta + xml_send = etree.tostring(xmlElem_send, encoding=str) elif method == 'RecepcaoEvento': xml_send = signer.assina_xml( xmlElem_send, kwargs['eventos'][0]['Id']) diff --git a/pytrustnfe/nfe/assinatura.py b/pytrustnfe/nfe/assinatura.py index 34df54a..8e088e3 100644 --- a/pytrustnfe/nfe/assinatura.py +++ b/pytrustnfe/nfe/assinatura.py @@ -14,7 +14,7 @@ class Assinatura(object): self.arquivo = arquivo self.senha = senha - def assina_xml(self, xml_element, reference): + def assina_xml(self, xml_element, reference, return_element_etree=False): cert, key = extract_cert_and_key_from_pfx(self.arquivo, self.senha) for element in xml_element.iter("*"): @@ -42,4 +42,6 @@ class Assinatura(object): if element_signed is not None and signature is not None: parent = element_signed.getparent() parent.append(signature) + if return_element_etree is True: + return signed_root return etree.tostring(signed_root, encoding=str) From 54636cfba4119cdbf9ecaa00a7260f3066e81a38 Mon Sep 17 00:00:00 2001 From: maiconkkl Date: Mon, 22 Jul 2019 11:41:37 -0300 Subject: [PATCH 3/3] =?UTF-8?q?Corre=C3=A7=C3=A3o=20na=20dict?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correção na dict de paramentros --- pytrustnfe/nfe/__init__.py | 48 +++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/pytrustnfe/nfe/__init__.py b/pytrustnfe/nfe/__init__.py index eee228e..0268634 100644 --- a/pytrustnfe/nfe/__init__.py +++ b/pytrustnfe/nfe/__init__.py @@ -40,10 +40,12 @@ def _generate_nfe_id(**kwargs): def _render(certificado, method, sign, **kwargs): path = os.path.join(os.path.dirname(__file__), 'templates') - if sign and kwargs['ide']['mod'] == '65': - kwargs['qrCode'] = 1 if 'qrCode' not in kwargs else kwargs['qrCode'] - kwargs['urlChave'] = 1 \ - if 'urlChave' not in kwargs else kwargs['urlChave'] + if sign and kwargs['NFes'][0]['ide']['mod'] == '65': + kwargs['NFes'][0]['qrCode'] = 1 if 'qrCode' not in kwargs else \ + kwargs['NFes'][0]['qrCode'] + kwargs['NFes'][0]['urlChave'] = 1 \ + if 'urlChave' not in kwargs['NFes'][0] else \ + kwargs['NFes'][0]['urlChave'] xmlElem_send = render_xml(path, '%s.xml' % method, True, **kwargs) modelo = xmlElem_send.find(".//{http://www.portalfiscal.inf.br/nfe}mod") @@ -56,45 +58,47 @@ def _render(certificado, method, sign, **kwargs): if method == 'NfeAutorizacao': xml_send = signer.assina_xml( xmlElem_send, kwargs['NFes'][0]['infNFe']['Id'], True) - if modelo == '65' and 'urlChave' not in kwargs and 'qrCode' not in\ - kwargs: - if kwargs['ide']['tpEmis'] != 1: + if modelo == '65' and 'urlChave' not in kwargs['NFes'][0] and \ + 'qrCode' not in kwargs['NFes'][0]: + if kwargs['NFes'][0]['ide']['tpEmis'] != 1: digest_value = xmlElem_send.find( ".//{http://www.w3.org/2000/09/xmldsig#}DigestValue") c_hash_qr_code = \ "{ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \ "{v_nf}|{dig_val}|{id_csc}|{csc}".format( - ch_acesso=kwargs['NFe']['infNFe']['Id'].replace('NFe', ''), + ch_acesso=kwargs['NFes'][0]['NFe']['infNFe']['Id']. + replace('NFe', ''), versao=2, - tp_amb=kwargs['ide']['tpAmb'], - dh_emi=kwargs['ide']['dhEmi'].split("-")[2].split("T")[0], - v_nf=kwargs['total']['vNF'], + tp_amb=kwargs['NFes'][0]['ide']['tpAmb'], + dh_emi=kwargs['NFes'][0]['ide']['dhEmi'].split("-")[2]. + split("T")[0], + v_nf=kwargs['NFes'][0]['total']['vNF'], dig_val=digest_value.text, - id_csc=int(kwargs['id_csc']), - csc=kwargs['csc'] + id_csc=int(kwargs['NFes'][0]['id_csc']), + csc=kwargs['NFes'][0]['csc'] ) c_hash_qr_code = hashlib.sha1(c_hash_qr_code.encode()). \ hexdigest() qr_code_url = 'p={ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \ "{v_nf}|{dig_val}|{id_csc}|{hash}'.format( - ch_acesso=kwargs['NFe']['infNFe']['Id']. + ch_acesso=kwargs['NFes'][0]['NFe']['infNFe']['Id']. replace('NFe', ''), versao=2, - tp_amb=kwargs['ide']['tpAmb'], - dh_emi=kwargs['ide']['dhEmi'].split("-")[2]. + tp_amb=kwargs['NFes'][0]['ide']['tpAmb'], + dh_emi=kwargs['NFes'][0]['ide']['dhEmi'].split("-")[2]. split("T")[0], - v_nf=kwargs['total']['vNF'], + v_nf=kwargs['NFes'][0]['total']['vNF'], dig_val=digest_value.text, - id_csc=int(kwargs['id_csc']), + id_csc=int(kwargs['NFes'][0]['id_csc']), hash=c_hash_qr_code ) qrcode = url_qrcode( - kwargs['emit']['enderEmit']['UF'], - str(kwargs['ide']['tpAmb']) + kwargs['NFes'][0]['emit']['enderEmit']['UF'], + str(kwargs['NFes'][0]['ide']['tpAmb']) ) + qr_code_url url_consulta = url_qrcode_exibicao( - kwargs['emit']['enderEmit']['UF'], - str(kwargs['ide']['tpAmb']) + kwargs['NFes'][0]['emit']['enderEmit']['UF'], + str(kwargs['NFes'][0]['ide']['tpAmb']) ) else: c_hash_qr_code = \