Skip to content

Commit

Permalink
Merge pull request #147 from danimaribeiro/feature/zeep
Browse files Browse the repository at this point in the history
Feature/zeep
  • Loading branch information
danimaribeiro committed Jul 30, 2018
2 parents c95cba8 + 06764a2 commit 40c3068
Show file tree
Hide file tree
Showing 26 changed files with 7,393 additions and 590 deletions.
439 changes: 170 additions & 269 deletions pytrustnfe/Servidores.py

Large diffs are not rendered by default.

31 changes: 0 additions & 31 deletions pytrustnfe/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
# © 2016 Danimar Ribeiro, Trustcode
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import urllib3
import requests
import suds.client
import suds_requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning


def get_authenticated_client(base_url, cert, key):
Expand All @@ -33,32 +31,3 @@ def get_client(base_url):
cache=cache,
transport=suds_requests.RequestsTransport(session)
)


class HttpClient(object):

def __init__(self, url, cert_path, key_path):
self.url = url
self.cert_path = cert_path
self.key_path = key_path

def _headers(self, action, send_raw):
if send_raw:
return {
'Content-type': 'text/xml; charset=utf-8;',
'SOAPAction': "http://www.portalfiscal.inf.br/nfe/wsdl/%s" % action,
'Accept': 'application/soap+xml; charset=utf-8',
}

return {
'Content-type': 'application/soap+xml; charset=utf-8;',
'SOAPAction': 'http://www.portalfiscal.inf.br/nfe/wsdl/%s' % action,
}

def post_soap(self, xml_soap, cabecalho, send_raw):
header = self._headers(cabecalho.soap_action, send_raw)
urllib3.disable_warnings(category=InsecureRequestWarning)
res = requests.post(self.url, data=xml_soap.encode('utf-8'),
cert=(self.cert_path, self.key_path),
verify=False, headers=header)
return res.text
149 changes: 68 additions & 81 deletions pytrustnfe/nfe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,16 @@
import hashlib
import binascii
from lxml import etree
from .comunicacao import executar_consulta
from .assinatura import Assinatura
from pytrustnfe.xml import render_xml
from pytrustnfe.utils import CabecalhoSoap
from pytrustnfe.xml import render_xml, sanitize_response
from pytrustnfe.utils import gerar_chave, ChaveNFe
from pytrustnfe.Servidores import localizar_url, localizar_qrcode
from pytrustnfe.xml.validate import valida_nfe
from pytrustnfe.exceptions import NFeValidationException


def _build_header(method, **kwargs):
action = {
'NfeAutorizacao': ('NfeAutorizacao', '3.10', 'NfeAutorizacao/nfeAutorizacaoLote'),
'NfeRetAutorizacao': ('NfeRetAutorizacao', '3.10', 'NfeRetAutorizacao/nfeRetAutorizacaoLote'),
'NfeConsultaCadastro': ('CadConsultaCadastro2', '2.00', 'CadConsultaCadastro2/consultaCadastro2'),
'NfeInutilizacao': ('NfeInutilizacao2', '3.10', 'NfeInutilizacao2/nfeInutilizacaoNF2'),
'RecepcaoEventoCancelamento': ('RecepcaoEvento', '1.00', 'RecepcaoEvento/nfeRecepcaoEvento'),
'RecepcaoEventoCarta': ('RecepcaoEvento', '1.00', 'RecepcaoEvento/nfeRecepcaoEvento'),
'NFeDistribuicaoDFe': ('NFeDistribuicaoDFe/nfeDistDFeInteresse', '1.00', 'NFeDistribuicaoDFe/nfeDistDFeInteresse'),
'RecepcaoEventoManifesto': ('RecepcaoEvento', '1.00', 'RecepcaoEvento/nfeRecepcaoEvento'),
}
vals = {
'estado': kwargs['estado'],
'method': action[method][0],
'soap_action': action[method][2],
'versao': action[method][1]
}
return CabecalhoSoap(**vals)
from pytrustnfe.certificado import extract_cert_and_key_from_pfx, save_cert_key

# Zeep
from requests import Session
from zeep import Client
from zeep.transports import Transport


def _generate_nfe_id(**kwargs):
Expand Down Expand Up @@ -130,18 +112,6 @@ def _render(certificado, method, sign, **kwargs):

modelo = xmlElem_send.find(".//{http://www.portalfiscal.inf.br/nfe}mod")
modelo = modelo.text if modelo is not None else '55'
if modelo == '65':
pagamento = etree.Element('pag')
tipo_pagamento = etree.Element('tPag')
valor = etree.Element('vPag')
valor_pago = kwargs['NFes'][0]['infNFe']['total']['vNF']
metodo_pagamento = kwargs['NFes'][0]['infNFe']['pagamento']
tipo_pagamento.text, valor.text = metodo_pagamento, valor_pago
pagamento.append(tipo_pagamento)
pagamento.append(valor)
transp = xmlElem_send.find(
".//{http://www.portalfiscal.inf.br/nfe}transp")
transp.addnext(pagamento)

if sign:
# Caso for autorização temos que adicionar algumas tags tipo
Expand All @@ -155,19 +125,9 @@ def _render(certificado, method, sign, **kwargs):
if method == 'NfeAutorizacao':
xml_send = signer.assina_xml(
xmlElem_send, kwargs['NFes'][0]['infNFe']['Id'])
if 'validate' in kwargs:
erros = valida_nfe(xml_send)
if erros:
raise NFeValidationException('Erro ao validar NFe',
erros=erros,
sent_xml=xml_send)
elif method == 'RecepcaoEventoCancelamento':
elif method == 'RecepcaoEvento':
xml_send = signer.assina_xml(
xmlElem_send, kwargs['eventos'][0]['Id'])

if method == 'RecepcaoEventoCarta':
xml_send = signer.assina_xml(
xmlElem_send, kwargs['Id'])
elif method == 'RecepcaoEventoManifesto':
xml_send = signer.assina_xml(
xmlElem_send, kwargs['manifesto']['identificador'])
Expand All @@ -182,21 +142,31 @@ def _render(certificado, method, sign, **kwargs):

def _send(certificado, method, **kwargs):
xml_send = kwargs["xml"]
url = localizar_url(method, kwargs['estado'], kwargs['modelo'],
kwargs['ambiente'])
cabecalho = _build_header(method, **kwargs)

send_raw = False
if method == 'NFeDistribuicaoDFe':
send_raw = True

response, obj = executar_consulta(certificado, url, cabecalho, xml_send,
send_raw=send_raw)
return {
'sent_xml': xml_send,
'received_xml': response.decode(),
'object': obj
}
base_url = localizar_url(
method, kwargs['estado'], kwargs['modelo'], kwargs['ambiente'])

cert, key = extract_cert_and_key_from_pfx(
certificado.pfx, certificado.password)
cert, key = save_cert_key(cert, key)

session = Session()
session.cert = (cert, key)
session.verify = False
transport = Transport(session=session)

xml = etree.fromstring(xml_send)
client = Client(base_url, transport=transport)

port = next(iter(client.wsdl.port_types))
first_operation = next(iter(client.wsdl.port_types[port].operations))
with client.options(raw_response=True):
response = client.service[first_operation](xml)
response, obj = sanitize_response(response.text)
return {
'sent_xml': xml_send,
'received_xml': response,
'object': obj.Body.getchildren()[0]
}


def xml_autorizar_nfe(certificado, **kwargs):
Expand All @@ -221,13 +191,13 @@ def retorno_autorizar_nfe(certificado, **kwargs):


def xml_recepcao_evento_cancelamento(certificado, **kwargs): # Assinar
return _render(certificado, 'RecepcaoEventoCancelamento', True, **kwargs)
return _render(certificado, 'RecepcaoEvento', True, **kwargs)


def recepcao_evento_cancelamento(certificado, **kwargs): # Assinar
if "xml" not in kwargs:
kwargs['xml'] = xml_recepcao_evento_cancelamento(certificado, **kwargs)
return _send(certificado, 'RecepcaoEventoCancelamento', **kwargs)
return _send(certificado, 'RecepcaoEvento', **kwargs)


def xml_inutilizar_nfe(certificado, **kwargs):
Expand All @@ -241,7 +211,7 @@ def inutilizar_nfe(certificado, **kwargs):


def xml_consultar_protocolo_nfe(certificado, **kwargs):
return _render(certificado, 'NfeConsultaProtocolo', True, **kwargs)
return _render(certificado, 'NfeConsultaProtocolo', False, **kwargs)


def consultar_protocolo_nfe(certificado, **kwargs):
Expand Down Expand Up @@ -272,34 +242,24 @@ def consulta_cadastro(certificado, **kwargs):


def xml_recepcao_evento_carta_correcao(certificado, **kwargs): # Assinar
return _render(certificado, 'RecepcaoEventoCarta', True, **kwargs)
return _render(certificado, 'RecepcaoEvento', True, **kwargs)


def recepcao_evento_carta_correcao(certificado, **kwargs): # Assinar
if "xml" not in kwargs:
kwargs['xml'] = xml_recepcao_evento_carta_correcao(
certificado, **kwargs)
return _send(certificado, 'RecepcaoEventoCarta', **kwargs)
return _send(certificado, 'RecepcaoEvento', **kwargs)


def xml_recepcao_evento_manifesto(certificado, **kwargs): # Assinar
return _render(certificado, 'RecepcaoEventoManifesto', True, **kwargs)
return _render(certificado, 'RecepcaoEvento', True, **kwargs)


def recepcao_evento_manifesto(certificado, **kwargs): # Assinar
if "xml" not in kwargs:
kwargs['xml'] = xml_recepcao_evento_manifesto(certificado, **kwargs)
return _send(certificado, 'RecepcaoEventoManifesto', **kwargs)


def xml_recepcao_evento_epec(certificado, **kwargs): # Assinar
return _render(certificado, 'RecepcaoEventoEPEC', True, **kwargs)


def recepcao_evento_epec(certificado, **kwargs): # Assinar
if "xml" not in kwargs:
kwargs['xml'] = xml_recepcao_evento_epec(certificado, **kwargs)
return _send(certificado, 'RecepcaoEventoEPEC', **kwargs)
return _send(certificado, 'RecepcaoEvento', **kwargs)


def xml_consulta_distribuicao_nfe(certificado, **kwargs): # Assinar
Expand All @@ -309,7 +269,34 @@ def xml_consulta_distribuicao_nfe(certificado, **kwargs): # Assinar
def consulta_distribuicao_nfe(certificado, **kwargs):
if "xml" not in kwargs:
kwargs['xml'] = xml_consulta_distribuicao_nfe(certificado, **kwargs)
return _send(certificado, 'NFeDistribuicaoDFe', **kwargs)
xml_send = kwargs["xml"]
base_url = localizar_url(
'NFeDistribuicaoDFe', kwargs['estado'], kwargs['modelo'],
kwargs['ambiente'])

cert, key = extract_cert_and_key_from_pfx(
certificado.pfx, certificado.password)
cert, key = save_cert_key(cert, key)

session = Session()
session.cert = (cert, key)
session.verify = False
transport = Transport(session=session)

xml = etree.fromstring(xml_send)
xml_um = etree.fromstring('<nfeCabecMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/"><cUF>AN</cUF><versaoDados>1.00</versaoDados></nfeCabecMsg>')
client = Client(base_url, transport=transport)

port = next(iter(client.wsdl.port_types))
first_operation = next(iter(client.wsdl.port_types[port].operations))
with client.options(raw_response=True):
response = client.service[first_operation](nfeDadosMsg=xml, _soapheaders=[xml_um])
response, obj = sanitize_response(response.text)
return {
'sent_xml': xml_send,
'received_xml': response,
'object': obj.Body.nfeDistDFeInteresseResponse.nfeDistDFeInteresseResult
}


def xml_download_nfe(certificado, **kwargs): # Assinar
Expand Down
34 changes: 0 additions & 34 deletions pytrustnfe/nfe/comunicacao.py

This file was deleted.

30 changes: 11 additions & 19 deletions pytrustnfe/nfe/templates/NFeDistribuicaoDFe.xml
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<nfeDistDFeInteresse xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe">
<nfeDadosMsg>
<distDFeInt xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.01">
<tpAmb>{{ ambiente }}</tpAmb>
<cUFAutor>{{ estado }}</cUFAutor>
<CNPJ>{{ cnpj_cpf }}</CNPJ>
<distNSU>
<ultNSU>{{ ultimo_nsu }}</ultNSU>
</distNSU>
<consChNFe>
<chNFe>{{ chave_nfe }}</chNFe>
</consChNFe>
</distDFeInt>
</nfeDadosMsg>
</nfeDistDFeInteresse>
</Body>
</Envelope>
<distDFeInt xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.01">
<tpAmb>{{ ambiente }}</tpAmb>
<cUFAutor>{{ estado }}</cUFAutor>
<CNPJ>{{ cnpj_cpf }}</CNPJ>
<distNSU>
<ultNSU>{{ ultimo_nsu }}</ultNSU>
</distNSU>
<consChNFe>
<chNFe>{{ chave_nfe }}</chNFe>
</consChNFe>
</distDFeInt>
Loading

0 comments on commit 40c3068

Please sign in to comment.