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 %}