From 95012e20ccb9f1255e23283bada27fc633c373b1 Mon Sep 17 00:00:00 2001 From: Junior Tada Date: Fri, 13 Nov 2015 17:04:54 -0200 Subject: [PATCH] =?UTF-8?q?Constru=C3=A7=C3=A3o=20de=20cabe=C3=A7alho=20e?= =?UTF-8?q?=20envolope=20soap=20para=20NSF-e=20autoriza=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/entidades/servico.py | 11 ++++++++++ pynfe/processamento/comunicacao.py | 43 ++++++++++++++++++++++++++----------- pynfe/processamento/serializacao.py | 23 ++++++++++++++------ 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/pynfe/entidades/servico.py b/pynfe/entidades/servico.py index e9679bb..49463d2 100644 --- a/pynfe/entidades/servico.py +++ b/pynfe/entidades/servico.py @@ -13,8 +13,19 @@ class Servico(Entidade): Lista com códigos dos serviços """ item_lista = str() + # descrição da atividade discriminacao = str() + """ + 1 – Exigível; + 2 – Não incidência; + 3 – Isenção; + 4 – Exportação; + 5 – Imunidade; + 6 – Exigibilidade Suspensa por Decisão Judicial; + 7 – Exigibilidade Suspensa por ProcessoAdministrativo + """ exigibilidade = int() + # Lista com todos os codigos divididos por estados na pasta data/MunIBGE codigo_municipio = str() def __str__(self): diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index 5894a9d..354eb33 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -357,38 +357,39 @@ class ComunicacaoNfse(Comunicacao): """ Classe de comunicação que segue o padrão definido para as SEFAZ dos Municípios. """ _versao = '' + _namespace = '' def autorizacao(self, autorizador, nota): + if autorizador.upper() == 'BETHA': + self._namespace = NAMESPACE_BETHA + self._versao = '2.02' # url do serviço url = self._get_url(autorizador) + NFSE[autorizador.upper()]['AUTORIZACAO'] # gerar raiz = etree.Element('GerarNfse') # cabecalho - raiz.append(self._cabecalho_soap(autorizador)) + raiz.append(self._cabecalho_soap()) dados = etree.SubElement(raiz, 'nfseDadosMsg') dados.append(nota) # xml soap xml = self._construir_xml(raiz) - print (url) - print (etree.tostring(xml, encoding='unicode').replace(':ns0','').replace('ns0:','')) + retorno = self._post(url, xml) + return retorno - def _cabecalho_soap(self, autorizador): + def _cabecalho_soap(self): u"""Monta o XML do cabeçalho da requisição SOAP""" - if autorizador.upper() == 'BETHA': - namespace = NAMESPACE_BETHA - versao = '2.02' raiz = etree.Element('nfseCabecMsg') - cabecalho = etree.SubElement(raiz, 'cabecalho', xmlns=namespace, versao=versao) - etree.SubElement(cabecalho, 'versaoDados').text = versao + cabecalho = etree.SubElement(raiz, 'cabecalho', xmlns=self._namespace, versao=self._versao) + etree.SubElement(cabecalho, 'versaoDados').text = self._versao return raiz def _construir_xml(self, dados): """Mota o XML para o envio via SOAP""" - raiz = etree.Element('{%s}Envelope'%NAMESPACE_SOAP, nsmap={'soapenv': NAMESPACE_SOAP_NFSE}) + raiz = etree.Element('{%s}Envelope'%NAMESPACE_SOAP, nsmap={'e': self._namespace}) etree.SubElement(raiz, '{%s}Header'%NAMESPACE_SOAP) body = etree.SubElement(raiz, '{%s}Body'%NAMESPACE_SOAP) body.append(dados) @@ -407,5 +408,23 @@ class ComunicacaoNfse(Comunicacao): raise Exception('Autorizador nao encontrado!') return self.url - def _post(self, url): - pass \ No newline at end of file + def _post(self, url, xml): + certificadoA1 = CertificadoA1(self.certificado) + chave, cert = certificadoA1.separar_arquivo(self.certificado_senha, caminho=True) + chave_cert = (cert, chave) + # Abre a conexão HTTPS + try: + xml_declaration='' + #xml = etree.tostring(xml, encoding='unicode', pretty_print=False).replace('\n','').replace('ns0:','soapenv:').replace(':ns0',':soapenv') + xml = etree.tostring(xml, encoding='unicode', pretty_print=False).replace('\n','').replace('ns0:','').replace(':ns0','') + xml = xml_declaration + xml + + print (xml) + # Faz o request com o servidor + #result = requests.post(url, xml, headers=self._post_header(), cert=chave_cert, verify=False) + #result.encoding='utf-8' + #return result + except requests.exceptions.ConnectionError as e: + raise e + finally: + certificadoA1.excluir() \ No newline at end of file diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index af57221..4797327 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -583,7 +583,7 @@ class SerializacaoNfse(Serializacao): def importar(self): pass - def _serializar_emitente(self, emitente, tag_raiz='Prestador', retorna_string=True): + def _serializar_emitente(self, emitente, tag_raiz='Prestador', retorna_string=False): raiz = etree.Element(tag_raiz) documento = etree.SubElement(raiz, 'CpfCnpj') etree.SubElement(documento, 'Cnpj').text = emitente.cnpj @@ -594,7 +594,7 @@ class SerializacaoNfse(Serializacao): else: return raiz - def _serializar_cliente(self, cliente, tag_raiz='Tomador', retorna_string=True): + def _serializar_cliente(self, cliente, tag_raiz='Tomador', retorna_string=False): raiz = etree.Element(tag_raiz) identificacao = etree.SubElement(raiz, 'IdentificacaoTomador') documento = etree.SubElement(identificacao, 'CpfCnpj') @@ -621,7 +621,7 @@ class SerializacaoNfse(Serializacao): else: return raiz - def _serializar_servico(self, servico, tag_raiz='Servico', retorna_string=True): + def _serializar_servico(self, servico, tag_raiz='Servico', retorna_string=False): raiz = etree.Element(tag_raiz) valores = etree.SubElement(raiz, 'Valores') etree.SubElement(valores, 'ValorServicos').text = str('{:.2f}').format(servico.valor_servico) @@ -633,6 +633,15 @@ class SerializacaoNfse(Serializacao): etree.SubElement(raiz, 'Discriminacao').text = servico.discriminacao etree.SubElement(raiz, 'CodigoMunicipio').text = servico.codigo_municipio #etree.SubElement(raiz, 'CodigoPais').text = '' + """ + 1 – Exigível; + 2 – Não incidência; + 3 – Isenção; + 4 – Exportação; + 5 – Imunidade; + 6 – Exigibilidade Suspensa por Decisão Judicial; + 7 – Exigibilidade Suspensa por ProcessoAdministrativo + """ etree.SubElement(raiz, 'ExigibilidadeISS').text = str(servico.exigibilidade) etree.SubElement(raiz, 'MunicipioIncidencia').text = servico.codigo_municipio #etree.SubElement(raiz, 'NumeroProcesso').text = '' @@ -645,7 +654,7 @@ class SerializacaoNfse(Serializacao): def _serializar_gerar(self, nfse, tag_raiz='GerarNfseEnvio', retorna_string=False): if nfse.autorizador.upper() == 'BETHA': - raiz = etree.Element(tag_raiz, xmlns=NAMESPACE_BETHA) + raiz = etree.Element(tag_raiz) # TODO - implementar outros sistemas autorizadores else: raiz = etree.Element(tag_raiz) @@ -654,11 +663,11 @@ class SerializacaoNfse(Serializacao): etree.SubElement(info, 'Competencia').text = nfse.data_emissao.strftime('%Y-%m-%d') # Servico - info.append(self._serializar_servico(nfse.servico, retorna_string=False)) + info.append(self._serializar_servico(nfse.servico)) # Emitente/Prestador - info.append(self._serializar_emitente(nfse.emitente, retorna_string=False)) + info.append(self._serializar_emitente(nfse.emitente)) # Cliente/Tomador - info.append(self._serializar_cliente(nfse.cliente, retorna_string=False)) + info.append(self._serializar_cliente(nfse.cliente)) etree.SubElement(info, 'OptanteSimplesNacional').text = str(nfse.simples) # 1-Sim; 2-Não etree.SubElement(info, 'IncentivoFiscal').text = str(nfse.incentivo) # 1-Sim; 2-Não