Browse Source

Correções

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.
pull/233/head
Michael Douglas Pereira de Morais 6 years ago
parent
commit
01ea033660
  1. 159
      pytrustnfe/nfe/__init__.py
  2. 4
      pytrustnfe/nfe/assinatura.py
  3. 10
      pytrustnfe/nfe/templates/NfeAutorizacao.xml

159
pytrustnfe/nfe/__init__.py

@ -3,6 +3,8 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import hashlib import hashlib
import os import os
from datetime import date
import requests import requests
from lxml import etree from lxml import etree
from .patch import has_patch from .patch import has_patch
@ -57,96 +59,129 @@ def _render(certificado, method, sign, **kwargs):
xml_send = signer.assina_xml(xmlElem_send, kwargs['obj']['id']) xml_send = signer.assina_xml(xmlElem_send, kwargs['obj']['id'])
if method == 'NfeAutorizacao': if method == 'NfeAutorizacao':
xml_send = signer.assina_xml( xml_send = signer.assina_xml(
xmlElem_send, kwargs['NFes'][0]['infNFe']['Id'], True)
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(
xmlElem_send, kwargs['NFes'][0]['infNFe']['Id'])
xml_send = etree.tostring(xmlElem_send, encoding=str)
elif method == 'RecepcaoEvento':
xml_send = signer.assina_xml(
xmlElem_send, kwargs['eventos'][0]['Id'])
elif method == 'RecepcaoEventoManifesto':
xml_send = signer.assina_xml(
xmlElem_send, kwargs['manifesto']['identificador'])
else:
xml_send = etree.tostring(xmlElem_send, encoding=str)
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") ".//{http://www.w3.org/2000/09/xmldsig#}DigestValue")
c_hash_qr_code = \ c_hash_qr_code = \
"{ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \ "{ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \
"{v_nf}|{dig_val}|{id_csc}|{csc}".format( "{v_nf}|{dig_val}|{id_csc}|{csc}".format(
ch_acesso=kwargs['NFes'][0]['NFe']['infNFe']['Id'].
replace('NFe', ''),
ch_acesso=chave,
versao=2, versao=2,
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'],
tp_amb=tp_amb.text,
dh_emi=dh_emi,
v_nf=float(v_nf.text),
dig_val=digest_value.text, dig_val=digest_value.text,
id_csc=int(kwargs['NFes'][0]['id_csc']),
csc=kwargs['NFes'][0]['csc']
id_csc=int(id_csc),
csc=csc
) )
c_hash_qr_code = hashlib.sha1(c_hash_qr_code.encode()). \ c_hash_qr_code = hashlib.sha1(c_hash_qr_code.encode()). \
hexdigest() hexdigest()
qr_code_url = 'p={ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \ qr_code_url = 'p={ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \
"{v_nf}|{dig_val}|{id_csc}|{hash}'.format( "{v_nf}|{dig_val}|{id_csc}|{hash}'.format(
ch_acesso=kwargs['NFes'][0]['NFe']['infNFe']['Id'].
replace('NFe', ''),
ch_acesso=chave,
versao=2, versao=2,
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'],
tp_amb=tp_amb.text,
dh_emi=dh_emi,
v_nf=float(v_nf.text),
dig_val=digest_value.text, dig_val=digest_value.text,
id_csc=int(kwargs['NFes'][0]['id_csc']),
id_csc=int(id_csc),
hash=c_hash_qr_code hash=c_hash_qr_code
) )
qrcode = url_qrcode(
kwargs['NFes'][0]['emit']['enderEmit']['UF'],
str(kwargs['NFes'][0]['ide']['tpAmb'])
) + qr_code_url
url_consulta = url_qrcode_exibicao(
kwargs['NFes'][0]['emit']['enderEmit']['UF'],
str(kwargs['NFes'][0]['ide']['tpAmb'])
)
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: else:
c_hash_qr_code = \ c_hash_qr_code = \
"{ch_acesso}|{versao}|{tp_amb}|{id_csc}|{csc}".format( "{ch_acesso}|{versao}|{tp_amb}|{id_csc}|{csc}".format(
ch_acesso=kwargs['NFe']['infNFe']['Id'].
replace('NFe', ''),
ch_acesso=chave,
versao=2, versao=2,
tp_amb=kwargs['ide']['tpAmb'],
id_csc=int(kwargs['id_csc']),
csc=kwargs['csc']
tp_amb=tp_amb.text,
id_csc=int(id_csc),
csc=csc
) )
c_hash_qr_code = hashlib.sha1(
c_hash_qr_code.encode()).hexdigest()
c_hash_qr_code = hashlib.sha1(c_hash_qr_code.encode()).hexdigest()
qr_code_url = "p={ch_acesso}|{versao}|{tp_amb}|{id_csc}|" \ qr_code_url = "p={ch_acesso}|{versao}|{tp_amb}|{id_csc}|" \
"{hash}".format(
ch_acesso=kwargs['NFe']['infNFe']['Id']
.replace('NFe', ''),
"{hash}".\
format(
ch_acesso=chave,
versao=2, versao=2,
tp_amb=kwargs['ide']['tpAmb'],
id_csc=int(kwargs['id_csc']),
tp_amb=tp_amb.text,
id_csc=int(id_csc),
hash=c_hash_qr_code 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(
qrcode = url_qrcode_str + qr_code_url
url_consulta = url_qrcode_exibicao_str
qrCode = xml.find(
'.//{http://www.portalfiscal.inf.br/nfe}qrCode').text = \ './/{http://www.portalfiscal.inf.br/nfe}qrCode').text = \
qrcode qrcode
urlChave = xml_send.find(
urlChave = xml.find(
'.//{http://www.portalfiscal.inf.br/nfe}urlChave').text = \ './/{http://www.portalfiscal.inf.br/nfe}urlChave').text = \
url_consulta url_consulta
xml_send = etree.tostring(xmlElem_send, encoding=str)
elif method == 'RecepcaoEvento':
xml_send = signer.assina_xml(
xmlElem_send, kwargs['eventos'][0]['Id'])
elif method == 'RecepcaoEventoManifesto':
xml_send = signer.assina_xml(
xmlElem_send, kwargs['manifesto']['identificador'])
else:
xml_send = etree.tostring(xmlElem_send, encoding=str)
return xml_send
return etree.tostring(xml)
def _get_session(certificado): def _get_session(certificado):
cert, key = extract_cert_and_key_from_pfx( cert, key = extract_cert_and_key_from_pfx(

4
pytrustnfe/nfe/assinatura.py

@ -14,7 +14,7 @@ class Assinatura(object):
self.arquivo = arquivo self.arquivo = arquivo
self.senha = senha self.senha = senha
def assina_xml(self, xml_element, reference, return_element_etree=False):
def assina_xml(self, xml_element, reference):
cert, key = extract_cert_and_key_from_pfx(self.arquivo, self.senha) cert, key = extract_cert_and_key_from_pfx(self.arquivo, self.senha)
for element in xml_element.iter("*"): for element in xml_element.iter("*"):
@ -42,6 +42,4 @@ class Assinatura(object):
if element_signed is not None and signature is not None: if element_signed is not None and signature is not None:
parent = element_signed.getparent() parent = element_signed.getparent()
parent.append(signature) parent.append(signature)
if return_element_etree is True:
return signed_root
return etree.tostring(signed_root, encoding=str) return etree.tostring(signed_root, encoding=str)

10
pytrustnfe/nfe/templates/NfeAutorizacao.xml

@ -914,10 +914,20 @@
</compra> </compra>
{% endif %} {% endif %}
</infNFe> </infNFe>
{% if ide.mod == '65' %}
<infNFeSupl> <infNFeSupl>
{% if NFe.infNFe.qrCode is defined %}
<qrCode>{{ NFe.infNFe.qrCode }}</qrCode> <qrCode>{{ NFe.infNFe.qrCode }}</qrCode>
{% else %}
<qrCode>.</qrCode>
{% endif %}
{% if NFe.infNFe.urlChave is defined %}
<urlChave>{{ NFe.infNFe.urlChave }}</urlChave> <urlChave>{{ NFe.infNFe.urlChave }}</urlChave>
{% else %}
<urlChave>.</urlChave>
{% endif %}
</infNFeSupl> </infNFeSupl>
{% endif %}
</NFe> </NFe>
{% endfor %} {% endfor %}
</enviNFe> </enviNFe>
Loading…
Cancel
Save