From 76877482668dedebbc864ee1cf3a12a3ef6ea3c8 Mon Sep 17 00:00:00 2001 From: Junior Tada Date: Wed, 15 Jul 2015 02:50:22 -0300 Subject: [PATCH] implementado consulta status --- pynfe/__init__.py | 7 ++- pynfe/processamento/__init__.py | 5 +-- pynfe/processamento/comunicacao.py | 91 +++++++++++++++++--------------------- setup.py | 2 +- texte.xml | 4 +- 5 files changed, 49 insertions(+), 60 deletions(-) diff --git a/pynfe/__init__.py b/pynfe/__init__.py index 546296e..7d3cab9 100644 --- a/pynfe/__init__.py +++ b/pynfe/__init__.py @@ -1,8 +1,7 @@ def get_version(): - return '0.1' + return '0.2' __version__ = get_version() -__author__ = 'Marinho Brandao' +__author__ = 'Marinho Brandao, Junior Tada, Leonardo Tada' __license__ = 'GNU Lesser General Public License (LGPL)' -__url__ = 'http://github.com/marinho/PyNFe' - +__url__ = 'https://github.com/leotada/PyNFe' diff --git a/pynfe/processamento/__init__.py b/pynfe/processamento/__init__.py index 7746eb8..edde458 100644 --- a/pynfe/processamento/__init__.py +++ b/pynfe/processamento/__init__.py @@ -1,6 +1,5 @@ from .serializacao import SerializacaoXML from .validacao import Validacao -#from assinatura import AssinaturaA1 -#from comunicacao import ComunicacaoSefaz +from .assinatura import AssinaturaA1 +from .comunicacao import ComunicacaoSefaz from .danfe import DANFE - diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index 9ddbe55..0583a66 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -1,17 +1,16 @@ # -*- coding: utf-8 -*- import datetime -from httplib import HTTPSConnection, HTTPResponse - +import requests from pynfe.utils import etree, StringIO, so_numeros from pynfe.utils.flags import NAMESPACE_NFE, NAMESPACE_SOAP, VERSAO_PADRAO from pynfe.utils.flags import CODIGOS_ESTADOS, VERSAO_PADRAO -from assinatura import AssinaturaA1 +from .assinatura import AssinaturaA1 class Comunicacao(object): u"""Classe abstrata responsavel por definir os metodos e logica das classes de comunicação com os webservices da NF-e.""" - _ambiente = 1 # 1 = Produção, 2 = Homologação + _ambiente = 2 # 1 = Produção, 2 = Homologação servidor = None porta = 80 certificado = None @@ -22,14 +21,14 @@ class Comunicacao(object): self.porta = porta self.certificado = certificado self.certificado_senha = certificado_senha - self._ambiente = homologacao and 2 or 1 + self._ambiente = 2 class ComunicacaoSefaz(Comunicacao): u"""Classe de comunicação que segue o padrão definido para as SEFAZ dos Estados.""" _versao = VERSAO_PADRAO _assinatura = AssinaturaA1 - + def transmitir(self, nota_fiscal): pass @@ -40,27 +39,21 @@ class ComunicacaoSefaz(Comunicacao): pass def status_servico(self): - post = '/nfeweb/services/nfestatusservico.asmx' - - # Monta XML do corpo da requisição # FIXME - raiz = etree.Element('teste') - dados = etree.tostring(raiz) - + post = self.servidor + + # Monta XML do corpo da requisição + raiz = etree.Element('consStatServ', versao='3.10', xmlns='http://www.portalfiscal.inf.br/nfe') + etree.SubElement(raiz, 'tpAmb').text = str(self._ambiente) + etree.SubElement(raiz, 'cUF').text = str(41) + etree.SubElement(raiz, 'xServ').text = 'STATUS' + dados = etree.tostring(raiz, encoding='UTF-8') # Monta XML para envio da requisição - xml = self._construir_xml_soap( - metodo='nfeRecepcao2', # FIXME - tag_metodo='nfeStatusServicoNF2', # FIXME - cabecalho=self._cabecalho_soap(), - dados=dados, - ) + xml = self._construir_xml_soap(cabecalho=self._cabecalho_soap(), dados=dados) # Chama método que efetua a requisição POST no servidor SOAP retorno = self._post(post, xml, self._post_header()) - - # Transforma o retorno em etree - #retorno = etree.parse(StringIO(retorno)) - - return bool(retorno) + return retorno + #return bool(retorno) def consultar_cadastro(self, instancia): #post = '/nfeweb/services/cadconsultacadastro.asmx' @@ -125,50 +118,48 @@ class ComunicacaoSefaz(Comunicacao): def _cabecalho_soap(self): u"""Monta o XML do cabeçalho da requisição SOAP""" - raiz = etree.Element('cabecMsg', xmlns=NAMESPACE_NFE, versao="1.02") - etree.SubElement(raiz, 'versaoDados').text = self._versao + raiz = etree.Element('nfeCabecMsg') + etree.SubElement(raiz, 'cUF').text = str(41) + etree.SubElement(raiz, 'versaoDados').text = VERSAO_PADRAO - return etree.tostring(raiz, encoding='utf-8', xml_declaration=True) + return etree.tostring(raiz, encoding='UTF-8') - def _construir_xml_soap(self, metodo, tag_metodo, cabecalho, dados): + def _construir_xml_soap(self, cabecalho, dados): u"""Mota o XML para o envio via SOAP""" - raiz = etree.Element('{%s}Envelope'%NAMESPACE_SOAP, nsmap={'soap': NAMESPACE_SOAP}) - + raiz = etree.Element('{%s}Envelope'%NAMESPACE_SOAP, nsmap={'soap': NAMESPACE_SOAP}, xmlns=self.servidor) + etree.SubElement(raiz, '{%s}Header'%NAMESPACE_SOAP).text = cabecalho body = etree.SubElement(raiz, '{%s}Body'%NAMESPACE_SOAP) - met = etree.SubElement( - body, tag_metodo, xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/%s"%metodo, - ) - - etree.SubElement(met, 'nfeCabecMsg').text = cabecalho - etree.SubElement(met, 'nfeDadosMsg').text = dados + etree.SubElement(body, 'nfeDadosMsg').text = dados - return etree.tostring(raiz, encoding='utf-8', xml_declaration=True) + return etree.tostring(raiz, encoding='UTF-8', xml_declaration=True) def _post_header(self): u"""Retorna um dicionário com os atributos para o cabeçalho da requisição HTTP""" return { u'content-type': u'application/soap+xml; charset=utf-8', + #u'content-type': u'text/xml; charset=utf-8', + #u'Accept': u'text/xml; charset=utf-8', u'Accept': u'application/soap+xml; charset=utf-8', } def _post(self, post, xml, header): # Separa arquivos de certificado para chave e certificado (sozinho) - caminho_chave, caminho_cert = self.certificado.separar_arquivo(senha=self.certificado_senha) + #caminho_chave, caminho_cert = self.certificado.separar_arquivo(senha=self.certificado_senha) + caminho_chave = '/home/junior/Documentos/Certificados/key.pem' + caminho_cert = '/home/junior/Documentos/Certificados/cert.pem' # Abre a conexão HTTPS - con = HTTPSConnection(self.servidor, self.porta, key_file=caminho_chave, cert_file=caminho_cert) - - try: - #con.set_debuglevel(100) - - con.request(u'POST', post, xml, header) - - resp = con.getresponse() + cert = (caminho_cert, caminho_chave) + s = str(xml, 'utf-8').replace('<', '<').replace('>', '>').replace('\'', '"').replace('\n', '') + #headers = {'content-type': 'text/xml'} - # Tudo certo! - if resp.status == 200: - return resp.read() + try: + r = requests.post(post, s, headers=self._post_header(), cert=cert, verify=False) + print (r.content) + if r == 200: + return r.text + except Exception as e: + pass finally: - con.close() - + pass diff --git a/setup.py b/setup.py index ade21a1..4df2f26 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ from setuptools import setup, find_packages setup( name='PyNFe', - version='0.1-custom', + version='0.2', packages=find_packages(), package_data={ 'pynfe': ['data/**/*.txt'], diff --git a/texte.xml b/texte.xml index 52d47b0..df73f3a 100644 --- a/texte.xml +++ b/texte.xml @@ -8,8 +8,8 @@ 55 1 1 - 2015-07-14T00:03:20-03:00 - 2015-07-14T00:03:20-03:00 + 2015-07-14T16:50:11-03:00 + 2015-07-14T16:50:11-03:00 1 1 4118402