From e399fc2081b6ee9c703d94b6f1837d0de22fa0bb Mon Sep 17 00:00:00 2001 From: martini97 Date: Mon, 5 Sep 2016 19:21:59 -0300 Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20nota=20fiscal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pytrustnfe/Servidores.py | 4 +-- pytrustnfe/client.py | 6 ++-- pytrustnfe/nfe/__init__.py | 44 +++++++++++++++++------------ pytrustnfe/nfe/assinatura.py | 1 - pytrustnfe/nfe/comunicacao.py | 26 +++++++++-------- pytrustnfe/nfe/templates/NfeAutorizacao.xml | 2 +- pytrustnfe/utils.py | 4 +-- 7 files changed, 48 insertions(+), 39 deletions(-) diff --git a/pytrustnfe/Servidores.py b/pytrustnfe/Servidores.py index 01ba675..f43f09c 100644 --- a/pytrustnfe/Servidores.py +++ b/pytrustnfe/Servidores.py @@ -23,11 +23,11 @@ NFE_AMBIENTE_HOMOLOGACAO = 2 def localizar_url(servico, estado): - return ESTADO_WS[estado]['servidor'], ESTADO_WS[estado][servico] + return ESTADO_WS[estado][2]['servidor'], ESTADO_WS[estado][2][servico] METODO_WS = { - WS_NFE_AUTORIZACAO:{ + WS_NFE_AUTORIZACAO: { 'webservice': 'NfeAutorizacao', 'metodo': 'NfeAutorizacao', }, diff --git a/pytrustnfe/client.py b/pytrustnfe/client.py index 0867982..dbd58e8 100644 --- a/pytrustnfe/client.py +++ b/pytrustnfe/client.py @@ -43,11 +43,11 @@ class HttpClient(object): def _headers(self, action): return { u'Content-type': u'application/soap+xml; charset=utf-8; action="http://www.portalfiscal.inf.br/nfe/wsdl/%s' % action, - u'Accept': u'application/soap+xml; charset=utf-8' + u'Accept': u'application/soap+xml; charset=utf-8' } def post_soap(self, xml_soap, action): - res = requests.post(self.url, data=xml_soap, + res = requests.post(self.url, data=xml_soap, cert=(self.cert_path, self.key_path), verify=False, headers=self._headers(action)) - return res.text + return res.text diff --git a/pytrustnfe/nfe/__init__.py b/pytrustnfe/nfe/__init__.py index 5b69cd8..0c2b0a7 100644 --- a/pytrustnfe/nfe/__init__.py +++ b/pytrustnfe/nfe/__init__.py @@ -16,6 +16,7 @@ def _build_header(**kwargs): vals = {'estado': kwargs['estado'], 'soap_action': ''} return CabecalhoSoap(**vals) + def _generate_nfe_id(**kwargs): for item in kwargs['NFes']: vals = { @@ -28,71 +29,78 @@ def _generate_nfe_id(**kwargs): 'numero': item['infNFe']['ide']['nNF'], 'tipo': item['infNFe']['ide']['tpEmis'], 'codigo': item['infNFe']['ide']['cNF'], - } + } chave = ChaveNFe(**vals) - item['infNFe']['Id'] = gerar_chave(chave, 'NFe') - - + item['infNFe']['Id'] = gerar_chave(chave, 'NFe') + def _send(certificado, method, **kwargs): path = os.path.join(os.path.dirname(__file__), 'templates') xml = render_xml(path, '%s.xml' % method, **kwargs) + xml = ']>' + xml pfx_path = certificado.save_pfx() signer = Assinatura(pfx_path, certificado.password) xml_signed = signer.assina_xml(xml, kwargs['NFes'][0]['infNFe']['Id']) + xml_signed = xml_signed.replace( + '\n\n]>\n', '') + url = localizar_url(0, 'RS') cabecalho = _build_header(**kwargs) - - return executar_consulta(certificado, url, cabecalho, xml_signed) + response, obj = executar_consulta(certificado, url, cabecalho, xml_signed) + return { + 'sent_xml': xml_signed, + 'received_xml': response, + 'object': obj + } def autorizar_nfe(certificado, **kwargs): # Assinar _generate_nfe_id(**kwargs) - _send(certificado, 'NfeAutorizacao', **kwargs) + return _send(certificado, 'NfeAutorizacao', **kwargs) def retorno_autorizar_nfe(certificado, **kwargs): - _send(certificado, 'NfeRetAutorizacao', **kwargs) + return _send(certificado, 'NfeRetAutorizacao', **kwargs) def recepcao_evento_cancelamento(certificado, **kwargs): # Assinar - _send(certificado, 'RecepcaoEventoCancelamento', **kwargs) + return _send(certificado, 'RecepcaoEventoCancelamento', **kwargs) def inutilizar_nfe(certificado, **kwargs): # Assinar - _send(certificado, 'NfeInutilizacao', **kwargs) + return _send(certificado, 'NfeInutilizacao', **kwargs) def consultar_protocolo_nfe(certificado, **kwargs): - _send(certificado, 'NfeConsultaProtocolo', **kwargs) + return _send(certificado, 'NfeConsultaProtocolo', **kwargs) def nfe_status_servico(certificado, **kwargs): - _send(certificado, 'NfeStatusServico.', **kwargs) + return _send(certificado, 'NfeStatusServico.', **kwargs) def consulta_cadastro(certificado, **kwargs): - _send(certificado, 'NfeConsultaCadastro.', **kwargs) + return _send(certificado, 'NfeConsultaCadastro.', **kwargs) def recepcao_evento_carta_correcao(certificado, **kwargs): # Assinar - _send(certificado, 'RecepcaoEventoCarta.', **kwargs) + return _send(certificado, 'RecepcaoEventoCarta.', **kwargs) def recepcao_evento_manifesto(certificado, **kwargs): # Assinar - _send(certificado, 'RecepcaoEventoManifesto', **kwargs) + return _send(certificado, 'RecepcaoEventoManifesto', **kwargs) def recepcao_evento_epec(certificado, **kwargs): # Assinar - _send(certificado, 'RecepcaoEventoEPEC', **kwargs) + return _send(certificado, 'RecepcaoEventoEPEC', **kwargs) def consulta_nfe_destinada(certificado, **kwargs): - _send(certificado, 'NfeConsultaDest', **kwargs) + return _send(certificado, 'NfeConsultaDest', **kwargs) def download_nfe(certificado, **kwargs): - _send(certificado, 'NfeDownloadNF', **kwargs) + return _send(certificado, 'NfeDownloadNF', **kwargs) diff --git a/pytrustnfe/nfe/assinatura.py b/pytrustnfe/nfe/assinatura.py index 63d5f19..81831fc 100644 --- a/pytrustnfe/nfe/assinatura.py +++ b/pytrustnfe/nfe/assinatura.py @@ -38,7 +38,6 @@ class Assinatura(object): self._checar_certificado() self._inicializar_cripto() try: - xml = ']>' + xml doc_xml = libxml2.parseMemory( xml, len(xml)) diff --git a/pytrustnfe/nfe/comunicacao.py b/pytrustnfe/nfe/comunicacao.py index 9805ea4..221c6b6 100644 --- a/pytrustnfe/nfe/comunicacao.py +++ b/pytrustnfe/nfe/comunicacao.py @@ -15,14 +15,26 @@ soap_body_path = './soap:Envelope/soap:Body' soap_fault_path = './soap:Envelope/soap:Body/soap:Fault' +def _soap_xml(body): + xml = '' + xml += '' + xml += '' + xml += '433.10' + xml += '' + xml += body + xml += '' + return xml.rstrip('\n') + + def executar_consulta(certificado, url, cabecalho, xmlEnviar): cert, key = extract_cert_and_key_from_pfx(certificado.pfx, certificado.password) cert_path, key_path = save_cert_key(cert, key) url = 'https://nfe-homologacao.sefazrs.rs.gov.br/ws/NfeAutorizacao/NFeAutorizacao.asmx' web_service = 'NfeAutorizacao/nfeAutorizacaoLote' client = HttpClient(url, cert_path, key_path) - xml_retorno = client.post_soap(xmlEnviar, web_service) - + xmlEnviar = xmlEnviar.replace('', '') + xml_enviar = _soap_xml(xmlEnviar) + xml_retorno = client.post_soap(xml_enviar, web_service) return sanitize_response(xml_retorno) @@ -36,16 +48,6 @@ class Comunicacao(object): self.cert = cert self.key = key - def _soap_xml(self, body): - xml = '' - xml += '' - xml += '' - xml += '433.10' - xml += '' - xml += body - xml += '' - return xml.rstrip('\n') - def _preparar_temp_pem(self): cert_path = '/tmp/' + uuid4().hex key_path = '/tmp/' + uuid4().hex diff --git a/pytrustnfe/nfe/templates/NfeAutorizacao.xml b/pytrustnfe/nfe/templates/NfeAutorizacao.xml index 2ca11ad..f5fa1e8 100644 --- a/pytrustnfe/nfe/templates/NfeAutorizacao.xml +++ b/pytrustnfe/nfe/templates/NfeAutorizacao.xml @@ -62,7 +62,7 @@ {% endif %} {% if dest.tipo == 'company' -%} {{ dest.cnpj_cpf }} - {% endif %} + {% endif %} {{ dest.xNome }} {{ dest.enderDest.xLgr }} diff --git a/pytrustnfe/utils.py b/pytrustnfe/utils.py index 7c69009..c84ffb0 100644 --- a/pytrustnfe/utils.py +++ b/pytrustnfe/utils.py @@ -6,7 +6,7 @@ from datetime import date, datetime class CabecalhoSoap(object): - + def __init__(self, **kwargs): self.estado = kwargs.pop('estado', '') self.soap_action = kwargs.pop('soap_action', '') @@ -53,7 +53,7 @@ def gerar_chave(obj_chave, prefix=None): assert isinstance(obj_chave, ChaveNFe), "Objeto deve ser do tipo ChaveNFe" obj_chave.validar() - chave_parcial = "%s%s%s%s%s%09d%d%08d" % (obj_chave.estado, obj_chave.emissao, + chave_parcial = "%s%s%s%s%s%09d%d%s" % (obj_chave.estado, obj_chave.emissao, obj_chave.cnpj, obj_chave.modelo, obj_chave.serie.zfill(3), obj_chave.numero, obj_chave.tipo, obj_chave.codigo)