From 09a0ff15be335036d69b73f7cc767b6c5c88d5d9 Mon Sep 17 00:00:00 2001 From: Ednaldo Batista Barreto <39229285+ImplantiSolucoes@users.noreply.github.com> Date: Thu, 13 Feb 2020 00:20:30 -0300 Subject: [PATCH] =?UTF-8?q?Criando=20parametros=20para=20conting=C3=AAncia?= =?UTF-8?q?=20(#233)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Criando parametros para contingência 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 * Geração do QRCode 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. corrigindo o retorno do assina_xml para manter codigo criado nova função para gerar qrcode com a possiblidade de assinatura tbm com parametro de entrada minimos; edição do xml para gerar as tags de Informações Suplementares mesmo que não seja repassada a informação, gerando com informação de um ponto. Co-authored-by: Michael Douglas Co-authored-by: Danimar Ribeiro --- pytrustnfe/nfe/__init__.py | 116 +++++++++++++++++++++++++++- pytrustnfe/nfe/danfce.py | 14 +++- pytrustnfe/nfe/templates/NfeAutorizacao.xml | 14 ++++ 3 files changed, 138 insertions(+), 6 deletions(-) diff --git a/pytrustnfe/nfe/__init__.py b/pytrustnfe/nfe/__init__.py index b9bab08..c861bbb 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 @@ -70,6 +68,116 @@ def _render(certificado, method, sign, **kwargs): return xml_send +def gerar_qrcode(id_csc: int, csc: str, xml_send: str, cert = False) -> str: + xml = etree.fromstring(xml_send) + signature = xml.find( + ".//{http://www.w3.org/2000/09/xmldsig#}Signature") + id = xml.find( + ".//{http://www.portalfiscal.inf.br/nfe}infNFe").get('Id') + if id is None: + raise Exception("XML Invalido - Sem o ID") + + chave = id.replace('NFe', '') + emit_uf = chave[:2] + + tp_amb = xml.find(".//{http://www.portalfiscal.inf.br/nfe}tpAmb") + if tp_amb is None: + raise Exception("XML Invalido - Sem o tipo de ambiente") + + dh_emi = xml.find(".//{http://www.portalfiscal.inf.br/nfe}dhEmi") + if dh_emi is None: + raise Exception("XML Invalido - Sem data de Emissao") + dh_emi = dh_emi.text.split("-")[2].split("T")[0] + + tp_emis = xml.find(".//{http://www.portalfiscal.inf.br/nfe}tpEmis") + if tp_emis is None: + raise Exception("XML Invalido - Sem tipo de emissao") + + v_nf = xml.find(".//{http://www.portalfiscal.inf.br/nfe}vNF") + if v_nf is None: + raise Exception("XML Invalido - Sem o valor da NFe") + + url_qrcode_str = url_qrcode( + estado=emit_uf, + ambiente=tp_amb.text) + url_qrcode_exibicao_str = url_qrcode_exibicao( + estado=emit_uf, + ambiente=tp_amb.text) + + if tp_emis != 1: + if signature is None: + if cert is not False: + signer = Assinatura(certificado.pfx, certificado.password) + xml_send = signer.assina_xml(xmlElem_send, id) + else: + raise Exception("XML Invalido - Sem assinatura e não " + "foi enviado o certificado nos parametros") + digest_value = xml.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=chave, + versao=2, + tp_amb=tp_amb.text, + dh_emi=dh_emi, + v_nf=float(v_nf.text), + dig_val=digest_value.text, + id_csc=int(id_csc), + csc=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=chave, + versao=2, + tp_amb=tp_amb.text, + dh_emi=dh_emi, + v_nf=float(v_nf.text), + dig_val=digest_value.text, + id_csc=int(id_csc), + hash=c_hash_qr_code + ) + qrcode = url_qrcode_str + qr_code_url + url_consulta = url_qrcode_exibicao_str + + qrCode = xml.find( + './/{http://www.portalfiscal.inf.br/nfe}qrCode').text = \ + qrcode + urlChave = xml.find( + './/{http://www.portalfiscal.inf.br/nfe}urlChave').text = \ + url_consulta + else: + c_hash_qr_code = \ + "{ch_acesso}|{versao}|{tp_amb}|{id_csc}|{csc}".format( + ch_acesso=chave, + versao=2, + tp_amb=tp_amb.text, + id_csc=int(id_csc), + csc=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=chave, + versao=2, + tp_amb=tp_amb.text, + id_csc=int(id_csc), + hash=c_hash_qr_code + ) + qrcode = url_qrcode_str + qr_code_url + url_consulta = url_qrcode_exibicao_str + qrCode = xml.find( + './/{http://www.portalfiscal.inf.br/nfe}qrCode').text = \ + qrcode + urlChave = xml.find( + './/{http://www.portalfiscal.inf.br/nfe}urlChave').text = \ + url_consulta + return etree.tostring(xml) + def _get_session(certificado): cert, key = extract_cert_and_key_from_pfx(certificado.pfx, certificado.password) cert, key = save_cert_key(cert, key) diff --git a/pytrustnfe/nfe/danfce.py b/pytrustnfe/nfe/danfce.py index 915a051..fabab91 100644 --- a/pytrustnfe/nfe/danfce.py +++ b/pytrustnfe/nfe/danfce.py @@ -2,10 +2,12 @@ # © 2017 Johny Chen Jy, Trustcode # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import os import re from textwrap import wrap from io import BytesIO - +from reportlab.pdfbase import pdfmetrics +from reportlab.pdfbase.ttfonts import TTFont from reportlab.lib import utils from reportlab.pdfgen import canvas from reportlab.lib.units import cm, mm @@ -77,7 +79,15 @@ def format_telefone(telefone): class danfce(object): def __init__(self, list_xml, logo=None, timezone=None): - + dir_fonts = os.path.dirname(os.path.realpath(__file__)) + pdfmetrics.registerFont( + TTFont( + 'NimbusSanL-Bold', + os.path.join(dir_fonts,'fonts/NimbusSanL Bold.ttf'))) + pdfmetrics.registerFont( + TTFont( + 'NimbusSanL-Regu', + os.path.join(dir_fonts, 'fonts/NimbusSanL Regular.ttf'))) self.current_font_size = 7 self.current_font_name = "NimbusSanL-Regu" diff --git a/pytrustnfe/nfe/templates/NfeAutorizacao.xml b/pytrustnfe/nfe/templates/NfeAutorizacao.xml index 33ccd86..1db6147 100644 --- a/pytrustnfe/nfe/templates/NfeAutorizacao.xml +++ b/pytrustnfe/nfe/templates/NfeAutorizacao.xml @@ -28,6 +28,10 @@ {{ ide.indPres }} {{ ide.procEmi }} {{ ide.verProc }} + {% if ide.tpEmis != 1 %} + {{ ide.dhCont }} + {{ ide.xJust }} + {% endif %} {% if ide.NFref is defined -%} {% for ref in ide.NFref %} @@ -910,10 +914,20 @@ {% endif %} + {% if ide.mod == '65' %} + {% if NFe.infNFe.qrCode is defined %} {{ NFe.infNFe.qrCode }} + {% else %} + . + {% endif %} + {% if NFe.infNFe.urlChave is defined %} {{ NFe.infNFe.urlChave }} + {% else %} + . + {% endif %} + {% endif %} {% endfor %}