Skip to content

Commit

Permalink
Nota de BH utiliza duas assinaturas
Browse files Browse the repository at this point in the history
Correçõs nos templates
  • Loading branch information
danimaribeiro committed May 7, 2018
1 parent 236515b commit 2de3913
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 10 deletions.
14 changes: 9 additions & 5 deletions pytrustnfe/nfse/bh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import os

from lxml import etree
from requests import Session
from zeep import Client
from zeep.transports import Transport

from pytrustnfe.certificado import extract_cert_and_key_from_pfx, save_cert_key
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):
Expand All @@ -18,12 +18,14 @@ def _render(certificado, method, **kwargs):

reference = ''
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':
reference = 'Cancelamento_NF%s' % kwargs['cancelamento']['numero_nfse']

signer = Assinatura(certificado.pfx, certificado.password)
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')


Expand All @@ -35,7 +37,9 @@ def _send(certificado, method, **kwargs):
base_url = 'https://bhisshomologa.pbh.gov.br/bhiss-ws/nfse?wsdl'

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(
certificado.pfx, certificado.password)
Expand All @@ -50,7 +54,7 @@ def _send(certificado, method, **kwargs):

response = client.service[method](xml_cabecalho, xml_send)

response, obj = sanitize_response(response)
response, obj = sanitize_response(response.encode('utf-8'))
return {
'sent_xml': str(xml_send),
'received_xml': str(response),
Expand Down
44 changes: 44 additions & 0 deletions pytrustnfe/nfse/bh/assinatura.py
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 4 deletions pytrustnfe/nfse/bh/templates/GerarNfse.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<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>
<ListaRps xmlns="http://www.abrasf.org.br/nfse.xsd">
{% include 'Rps.xml' %}
Expand Down
2 changes: 1 addition & 1 deletion pytrustnfe/nfse/bh/templates/Rps.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<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>
<Numero>{{ rps.numero }}</Numero>
<Serie>{{ rps.serie }}</Serie>
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
'nfse/imperial/templates/*xml',
'nfse/floripa/templates/*xml',
'nfse/carioca/templates/*xml',
'nfse/bh/templates/*xml',
'xml/schemas/*xsd',
]},
url='https://github.com/danimaribeiro/PyTrustNFe',
Expand Down

0 comments on commit 2de3913

Please sign in to comment.