Browse Source

Nota de BH utiliza duas assinaturas

Correçõs nos templates
pull/133/head
Danimar Ribeiro 8 years ago
parent
commit
3db71b7b9a
  1. 14
      pytrustnfe/nfse/bh/__init__.py
  2. 44
      pytrustnfe/nfse/bh/assinatura.py
  3. 8
      pytrustnfe/nfse/bh/templates/GerarNfse.xml
  4. 2
      pytrustnfe/nfse/bh/templates/Rps.xml
  5. 1
      setup.py

14
pytrustnfe/nfse/bh/__init__.py

@ -2,14 +2,14 @@
# 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 os import os
from lxml import etree
from requests import Session from requests import Session
from zeep import Client from zeep import Client
from zeep.transports import Transport from zeep.transports import Transport
from pytrustnfe.certificado import extract_cert_and_key_from_pfx, save_cert_key from pytrustnfe.certificado import extract_cert_and_key_from_pfx, save_cert_key
from pytrustnfe.xml import render_xml, sanitize_response from pytrustnfe.xml import render_xml, sanitize_response
from pytrustnfe.nfe.assinatura import Assinatura
from pytrustnfe.nfse.bh.assinatura import Assinatura
def _render(certificado, method, **kwargs): def _render(certificado, method, **kwargs):
@ -18,12 +18,14 @@ def _render(certificado, method, **kwargs):
reference = '' reference = ''
if method == 'GerarNfse': if method == 'GerarNfse':
reference = 'r%s' % kwargs['rps']['numero']
reference = 'rps:%s' % kwargs['rps']['numero']
ref_lote = 'lote%s' % kwargs['rps']['numero_lote']
elif method == 'CancelarNfse': elif method == 'CancelarNfse':
reference = 'Cancelamento_NF%s' % kwargs['cancelamento']['numero_nfse'] reference = 'Cancelamento_NF%s' % kwargs['cancelamento']['numero_nfse']
signer = Assinatura(certificado.pfx, certificado.password) signer = Assinatura(certificado.pfx, certificado.password)
xml_send = signer.assina_xml(xml_send, reference) xml_send = signer.assina_xml(xml_send, reference)
xml_send = signer.assina_xml(etree.fromstring(xml_send), ref_lote)
return xml_send.encode('utf-8') return xml_send.encode('utf-8')
@ -35,7 +37,9 @@ def _send(certificado, method, **kwargs):
base_url = 'https://bhisshomologa.pbh.gov.br/bhiss-ws/nfse?wsdl' base_url = 'https://bhisshomologa.pbh.gov.br/bhiss-ws/nfse?wsdl'
xml_send = kwargs["xml"].decode('utf-8') xml_send = kwargs["xml"].decode('utf-8')
xml_cabecalho = ''
xml_cabecalho = '<?xml version="1.0" encoding="UTF-8"?>\
<cabecalho xmlns="http://www.abrasf.org.br/nfse.xsd" versao="1.00">\
<versaoDados>1.00</versaoDados></cabecalho>'
cert, key = extract_cert_and_key_from_pfx( cert, key = extract_cert_and_key_from_pfx(
certificado.pfx, certificado.password) certificado.pfx, certificado.password)
@ -50,7 +54,7 @@ def _send(certificado, method, **kwargs):
response = client.service[method](xml_cabecalho, xml_send) response = client.service[method](xml_cabecalho, xml_send)
response, obj = sanitize_response(response)
response, obj = sanitize_response(response.encode('utf-8'))
return { return {
'sent_xml': str(xml_send), 'sent_xml': str(xml_send),
'received_xml': str(response), 'received_xml': str(response),

44
pytrustnfe/nfse/bh/assinatura.py

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# © 2016 Danimar Ribeiro, Trustcode
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import signxml
from lxml import etree
from pytrustnfe.certificado import extract_cert_and_key_from_pfx
from signxml import XMLSigner
class Assinatura(object):
def __init__(self, arquivo, senha):
self.arquivo = arquivo
self.senha = senha
def assina_xml(self, xml_element, reference):
cert, key = extract_cert_and_key_from_pfx(self.arquivo, self.senha)
for element in xml_element.iter("*"):
if element.text is not None and not element.text.strip():
element.text = None
signer = XMLSigner(
method=signxml.methods.enveloped, signature_algorithm="rsa-sha1",
digest_algorithm='sha1',
c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315')
ns = {}
ns[None] = signer.namespaces['ds']
signer.namespaces = ns
ref_uri = ('#%s' % reference) if reference else None
signed_root = signer.sign(
xml_element, key=key.encode(), cert=cert.encode(),
reference_uri=ref_uri)
if reference:
element_signed = signed_root.find(".//*[@Id='%s']" % reference)
signature = signed_root.find(".//*[@URI='#%s']" % reference).getparent().getparent()
if element_signed is not None and signature is not None:
parent = element_signed.getparent()
parent.append(signature)
return etree.tostring(signed_root, encoding=str)

8
pytrustnfe/nfse/bh/templates/GerarNfse.xml

@ -1,8 +1,8 @@
<GerarNfseEnvio xmlns="http://www.abrasf.org.br/nfse.xsd"> <GerarNfseEnvio xmlns="http://www.abrasf.org.br/nfse.xsd">
<LoteRps Id="lote{{ nfse.numero_lote }}">
<NumeroLote>{{ nfse.numero_lote }}</NumeroLote>
<Cnpj>{{ nfse.cnpj_prestador }}</Cnpj>
<InscricaoMunicipal>{{ nfse.inscricao_municipal }}</InscricaoMunicipal>
<LoteRps Id="lote{{ rps.numero_lote }}" versao="1.00">
<NumeroLote>{{ rps.numero_lote }}</NumeroLote>
<Cnpj>{{ rps.prestador.cnpj }}</Cnpj>
<InscricaoMunicipal>{{ rps.prestador.inscricao_municipal }}</InscricaoMunicipal>
<QuantidadeRps>1</QuantidadeRps> <QuantidadeRps>1</QuantidadeRps>
<ListaRps xmlns="http://www.abrasf.org.br/nfse.xsd"> <ListaRps xmlns="http://www.abrasf.org.br/nfse.xsd">
{% include 'Rps.xml' %} {% include 'Rps.xml' %}

2
pytrustnfe/nfse/bh/templates/Rps.xml

@ -1,5 +1,5 @@
<Rps> <Rps>
<InfRps xmlns="http://www.abrasf.org.br/ABRASF/arquivos/nfse.xsd" Id="r{{ rps.numero }}">
<InfRps xmlns="http://www.abrasf.org.br/nfse.xsd" Id="rps:{{ rps.numero }}">
<IdentificacaoRps> <IdentificacaoRps>
<Numero>{{ rps.numero }}</Numero> <Numero>{{ rps.numero }}</Numero>
<Serie>{{ rps.serie }}</Serie> <Serie>{{ rps.serie }}</Serie>

1
setup.py

@ -37,6 +37,7 @@ later (LGPLv2+)',
'nfse/imperial/templates/*xml', 'nfse/imperial/templates/*xml',
'nfse/floripa/templates/*xml', 'nfse/floripa/templates/*xml',
'nfse/carioca/templates/*xml', 'nfse/carioca/templates/*xml',
'nfse/bh/templates/*xml',
'xml/schemas/*xsd', 'xml/schemas/*xsd',
]}, ]},
url='https://github.com/danimaribeiro/PyTrustNFe', url='https://github.com/danimaribeiro/PyTrustNFe',

Loading…
Cancel
Save