Ejemplo n.º 1
0
 def validar(self, xml, nome_xsd = None):
     '''Função que valida um XML usando lxml do Python via arquivo XSD no diretório xsd/<pacote>/<nó_xml>.xsd'''
     # Realiza o parser sobre o xml, identificado como string se iniciar por '<', senão é identificado como nome de arquivo
     if type(xml) == str:
         if xml[0] == '<':
             xml = PoleXML.importar(xml)
         else:
             xml = PoleXML.importar(open(xml).read())
     # Para este sistema com lxml funcionar foi preciso trocar em tiposBasico_v1.03.xsd {0,} por *
     # Obeter a versão do primeiro ou segundo nó
     versao = xml('', 1)['versao'] or xml('', 1)('', 1)['versao']
     # O padrão de nome de arquivos xsd é iniciar com letras minúsculas,
     # mantendo maiúsuclas iniciais de palavras, assim foi preciso desse
     # trecho de código para passar para músculas iniciais maiúsculas
     if nome_xsd is None:
         nome = ''
         temp = xml('', 1)._XML__nome
         for i in range(len(temp)):
             if temp[i].isupper():
                 nome += temp[i].lower()
             else:
                 break
         nome += temp[i:]
     else:
         nome = nome_xsd
     # Caminho do arquivo XSD
     #print nome_xsd, self.__raiz , '/xsd/' , self.__pacote , '/' , nome , '_v' , versao , '.xsd'
     arquivo_xsd = os.path.join(self.__raiz, 'xsd', self.__pacote, nome + '_v' + versao + '.xsd')
     # Verifica a validade do xml
     self.erros = PoleXML.validar(xml, arquivo_xsd)
     return len(self.erros) == 0
Ejemplo n.º 2
0
 def validar(self, xml, nome_xsd=None):
     '''Função que valida um XML usando lxml do Python via arquivo XSD no diretório xsd/<pacote>/<nó_xml>.xsd'''
     # Realiza o parser sobre o xml, identificado como string se iniciar por '<', senão é identificado como nome de arquivo
     if type(xml) == str:
         if xml[0] == '<':
             xml = PoleXML.importar(xml)
         else:
             xml = PoleXML.importar(open(xml).read())
     # Para este sistema com lxml funcionar foi preciso trocar em tiposBasico_v1.03.xsd {0,} por *
     # Obeter a versão do primeiro ou segundo nó
     versao = xml('', 1)['versao'] or xml('', 1)('', 1)['versao']
     # O padrão de nome de arquivos xsd é iniciar com letras minúsculas,
     # mantendo maiúsuclas iniciais de palavras, assim foi preciso desse
     # trecho de código para passar para músculas iniciais maiúsculas
     if nome_xsd is None:
         nome = ''
         temp = xml('', 1)._XML__nome
         for i in range(len(temp)):
             if temp[i].isupper():
                 nome += temp[i].lower()
             else:
                 break
         nome += temp[i:]
     else:
         nome = nome_xsd
     # Caminho do arquivo XSD
     #print nome_xsd, self.__raiz , '/xsd/' , self.__pacote , '/' , nome , '_v' , versao , '.xsd'
     arquivo_xsd = os.path.join(self.__raiz, 'xsd', self.__pacote,
                                nome + '_v' + versao + '.xsd')
     # Verifica a validade do xml
     self.erros = PoleXML.validar(xml, arquivo_xsd)
     return len(self.erros) == 0
Ejemplo n.º 3
0
 def servico(self, nome_wsdl, xml, nome_xsd = None):
     # Validar xml para envio
     if not self.validar(xml, nome_xsd):
         erros = "Erro(s) no XML: "
         for erro in self.erros:
             erros += erro['type_name'] + ': ' + erro['message']
         raise ValueError(erros)
     # Criar meio de transporte criptografado
     transporte = suds.transport.http.HttpTransport()
     transporte.urlopener = urllib2.build_opener(https_ssl(key_file = self.__chave, cert_file = self.__certificado, ca_file = self.__certificadoras))
     # Carrega o wsdl da estrutura de arquivos <raiz>/wsdl/<uf>/<nome_wsdl>.wsdl
     arquivo_wsdl = 'file://' + self.__raiz + '/wsdl/' + self.__sefaz + '/' + self.__str_ambiente + '/' + str(nome_wsdl) + '.wsdl'
     wsdl = suds.client.Client(arquivo_wsdl, transport = transporte)
     # Configurar o ambiente do SOAP
     wsdl.options.cache.clear()
     ns_anterior = suds.bindings.binding.envns
     suds.bindings.binding.envns = ('SOAP-ENV', 'http://www.w3.org/2003/05/soap-envelope')
     # Cria uma função do primeiro serviço, primeira URL (port) e primeiro método, visto que são únicos
     funcao = suds.client.Method(wsdl, wsdl.wsdl.services[0].ports[0].methods.values()[0])
     # Configura o cabeçalho e retorno em XML - Na versão do servidor não tem o parâmetro prettyxml, então tem que comentá-lo para rodar lá
     wsdl.set_options(soapheaders = self.__cabecalho(wsdl, xml('', 1)['versao']), retxml = True, prettyxml = True)
     # Executa a função e coleta o resultado em XML
     resultado = funcao(suds.sax.parser.Parser().parse(string = PoleXML.serializar(xml)).root())
     #resultado = funcao(PoleXML.exportar(xml, -1))
     #print repr(PoleXML.importar(resultado))
     # Voltando o ambiente do SOAP
     suds.bindings.binding.envns = ns_anterior
     # Retornar o resultado na forma da classe XML, somente o corpo do envelope Soap
     return PoleXML.importar(resultado).Envelope.Body('', 1)
Ejemplo n.º 4
0
 def consultar_distribuicao_dfe(self, ultimo_nsu=0, nsu=None, chave=None):
     # Usar sefaz = 'AN' (ambiente nacional)
     if self.__sefaz == 'AN':
         ws = self
     else:
         ws = Webservice(self.__cnpj, self.__ambiente, self.__uf, 'AN',
                         self.__raiz, self.__pacote, self.__contingencia)
     requisicao = PoleXML.XML()
     distDFeInt = requisicao.nfeDadosMsg.distDFeInt
     distDFeInt['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     distDFeInt['versao'] = '1.01' if chave else '1.35'
     distDFeInt.tpAmb = self.__ambiente
     distDFeInt.cUFAutor = UFS_IBGE[self.__uf]
     distDFeInt.CNPJ = self.__cnpj
     if chave:
         distDFeInt.consChNFe.chNFe = chave
     elif nsu:
         distDFeInt.consNSU.NSU = "%015i" % nsu
     else:
         distDFeInt.distNSU.ultNSU = "%015i" % ultimo_nsu
     retorno = ws.servico('NfeDistribuicaoDFe', requisicao,
                          versao_wsdl='1.00')
     lote = retorno.nfeDistDFeInteresseResult.retDistDFeInt.loteDistDFeInt
     for num_doc in range(1, lote('docZip', 0) + 1):
         doc = PoleXML.importar(
             zlib.decompress(str(lote.docZip(num_doc)).decode('base64'),
                             16 + zlib.MAX_WBITS))  # for gZip header
         lote.docZip = None, num_doc
         lote.docZip += doc, num_doc
     return retorno
Ejemplo n.º 5
0
 def servico(self, nome_wsdl, xml, nome_xsd=None, versao_wsdl=None):
     # Validar xml para envio
     if not self.validar(xml, nome_xsd):
         erros = "Erro(s) no XML: "
         for erro in self.erros:
             erros += erro['type_name'] + ': ' + erro['message']
         raise ValueError(erros)
     # Versões do XML e do WSDL
     versao_xml = xml('', 1)['versao'] or xml('', 1)('', 1)['versao']
     if not versao_wsdl:
         versao_wsdl = versao_xml
     # Carrega o wsdl da estrutura de arquivos pela versão do WSDL
     # <raiz>/wsdl/<sefaz>/<ambiente>/<versao>/<nome_wsdl>.wsdl
     arquivo_wsdl = os.path.join(self.__raiz, 'wsdl', self.__sefaz,
                                 self.__str_ambiente, versao_wsdl,
                                 nome_wsdl + '.wsdl')
     # Se não encontrou pela versão do WSDL especificada, vai pela do XML
     if not os.path.exists(arquivo_wsdl):
         arquivo_wsdl = os.path.join(
             self.__raiz, 'wsdl', self.__sefaz,
             self.__str_ambiente, versao_xml, nome_wsdl + '.wsdl')
     arquivo_wsdl = 'file://' + arquivo_wsdl
     # Criar meio de transporte criptografado
     transporte = suds.transport.http.HttpTransport()
     transporte_ssl = (https_ssl_mt
                       if (self.__sefaz == 'MT'
                           or (sys.version_info.major == 2 and
                               sys.version_info.minor < 7))
                       else https_ssl)
     transporte.urlopener = urllib2.build_opener(
         transporte_ssl(key_file=self.__chave, cert_file=self.__certificado,
                        ca_file=self.__certificadoras))
     wsdl = suds.client.Client(arquivo_wsdl, transport=transporte)
     # Configurar o ambiente do SOAP 1.2
     wsdl.options.cache.clear()
     ns_anterior = suds.bindings.binding.envns
     suds.bindings.binding.envns = (
         'soap12', 'http://www.w3.org/2003/05/soap-envelope')
     # Cria uma função do primeiro serviço, primeira URL (port)
     # e primeiro método, visto que são únicos
     funcao = suds.client.Method(wsdl, wsdl.wsdl.
                                 services[0].ports[0].methods.values()[0])
     # Configura os headers http para SOAP 1.2, o cabeçalho e retorno em XML
     wsdl.set_options(soapheaders=self.__cabecalho(wsdl, versao_xml),
                      headers={'Content-Type':
                               'application/soap+xml; charset=utf-8'},
                      retxml=True)
     # Na versão do servidor não tem o parâmetro prettyxml,
     # então tem que comentá-lo para rodar lá
     if sys.version_info.major > 2 or sys.version_info.minor > 6:
         wsdl.set_options(prettyxml=True)
     # Executa a função e coleta o resultado em XML
     resultado = funcao(suds.sax.parser.Parser().parse(
                        string=PoleXML.serializar(xml)).root())
     # Voltando o ambiente do SOAP
     suds.bindings.binding.envns = ns_anterior
     # Retornar o resultado na forma da classe XML,
     # somente o corpo do envelope Soap
     return PoleXML.importar(resultado).Envelope.Body('', 1)
Ejemplo n.º 6
0
 def servico(self, nome_wsdl, xml, nome_xsd=None, versao_wsdl=None):
     # Validar xml para envio
     if not self.validar(xml, nome_xsd):
         erros = "Erro(s) no XML: "
         for erro in self.erros:
             erros += erro['type_name'] + ': ' + erro['message']
         raise ValueError(erros)
     # Versões do XML e do WSDL
     versao_xml = xml('', 1)['versao'] or xml('', 1)('', 1)['versao']
     if not versao_wsdl:
         versao_wsdl = versao_xml
     # Carrega o wsdl da estrutura de arquivos pela versão do WSDL
     # <raiz>/wsdl/<sefaz>/<ambiente>/<versao>/<nome_wsdl>.wsdl
     arquivo_wsdl = os.path.join(self.__raiz, 'wsdl', self.__sefaz,
                                 self.__str_ambiente, versao_wsdl,
                                 nome_wsdl + '.wsdl')
     # Se não encontrou pela versão do WSDL especificada, vai pela do XML
     if not os.path.exists(arquivo_wsdl):
         arquivo_wsdl = os.path.join(self.__raiz, 'wsdl', self.__sefaz,
                                     self.__str_ambiente, versao_xml,
                                     nome_wsdl + '.wsdl')
     arquivo_wsdl = 'file://' + arquivo_wsdl
     # Criar meio de transporte criptografado
     transporte = suds.transport.http.HttpTransport()
     transporte_ssl = (https_ssl_mt if
                       (self.__sefaz == 'MT' or
                        (sys.version_info.major == 2
                         and sys.version_info.minor < 7)) else https_ssl)
     transporte.urlopener = urllib2.build_opener(
         transporte_ssl(key_file=self.__chave,
                        cert_file=self.__certificado,
                        ca_file=self.__certificadoras))
     wsdl = suds.client.Client(arquivo_wsdl, transport=transporte)
     # Configurar o ambiente do SOAP 1.2
     wsdl.options.cache.clear()
     ns_anterior = suds.bindings.binding.envns
     suds.bindings.binding.envns = (
         'soap12', 'http://www.w3.org/2003/05/soap-envelope')
     # Cria uma função do primeiro serviço, primeira URL (port)
     # e primeiro método, visto que são únicos
     funcao = suds.client.Method(
         wsdl, wsdl.wsdl.services[0].ports[0].methods.values()[0])
     # Configura os headers http para SOAP 1.2, o cabeçalho e retorno em XML
     wsdl.set_options(
         soapheaders=self.__cabecalho(wsdl, versao_xml),
         headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
         retxml=True)
     # Na versão do servidor não tem o parâmetro prettyxml,
     # então tem que comentá-lo para rodar lá
     if sys.version_info.major > 2 or sys.version_info.minor > 6:
         wsdl.set_options(prettyxml=True)
     # Executa a função e coleta o resultado em XML
     resultado = funcao(suds.sax.parser.Parser().parse(
         string=PoleXML.serializar(xml)).root())
     # Voltando o ambiente do SOAP
     suds.bindings.binding.envns = ns_anterior
     # Retornar o resultado na forma da classe XML,
     # somente o corpo do envelope Soap
     return PoleXML.importar(resultado).Envelope.Body('', 1)
Ejemplo n.º 7
0
    def enviar_envento(self, descr_evento, chave_nfe, data_hora_evento,
                       qtd_mesmo_evento, xml_adicional):
        cod, xsd_evento, ev_maiusculo, xsd_envio, uf = EVENTOS[descr_evento]
        if not uf:
            uf = self.__uf
        if uf == self.__uf:
            ws_envio = self
        else:
            ws_envio = Webservice(self.__cnpj, self.__ambiente,
                                  uf, None, self.__raiz, self.__pacote,
                                  self.__contingencia)
        dh = cf(data_hora_evento, datetime.datetime)[0]
        dh = PoleUtil.tz.localize(dh).strftime('%Y-%m-%dT%H:%M:%S%z')
        dh = dh[:-2] + ':' + dh[-2:]
        evento = PoleXML.XML()
        ev = evento.Evento if ev_maiusculo else evento.evento
        ev['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
        ev['versao'] = '1.00'
        ev.infEvento['Id'] = 'ID%s%s%02i' % (cod, chave_nfe, qtd_mesmo_evento)
        ev.infEvento.cOrgao = UFS_IBGE[uf]
        ev.infEvento.tpAmb = self.__ambiente
        ev.infEvento.CNPJ = self.__cnpj
        ev.infEvento.chNFe = chave_nfe
        ev.infEvento.dhEvento = dh
        ev.infEvento.tpEvento = cod
        ev.infEvento.nSeqEvento = qtd_mesmo_evento
        ev.infEvento.verEvento = '1.00'
        ev.infEvento.detEvento['versao'] = '1.00'
        ev.infEvento.detEvento.descEvento = descr_evento
        ev.infEvento.detEvento += xml_adicional
        self.assinar(ev.infEvento)
        # Validar xml da evento
        if not self.validar(evento, xsd_evento):
            erros = "Erro(s) no XML: "
            for erro in self.erros:
                erros += erro['type_name'] + ': ' + erro['message']
            raise ValueError(erros)
        # Lote para envio
        envio = PoleXML.XML()
        envio.envEvento['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
        envio.envEvento['versao'] = '1.00'
        # idLote = microsegundo/10 do envio - 15 dígitos no máximo
        envio.envEvento.idLote = str(int(time.time() * 100000))
        envio.envEvento.evento = ev(1)
        recibo = ws_envio.servico('RecepcaoEvento', envio, xsd_envio, '4.00')
        retorno = PoleXML.XML()
        retorno.procEventoNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
        retorno.procEventoNFe['versao'] = '1.00'
        retorno.procEventoNFe.evento = ev(1)
        if recibo.retEnvEvento('retEvento'):
            retorno.procEventoNFe.retEvento = recibo.retEnvEvento.retEvento
        else:
            retorno.procEventoNFe.retEnvEvento = recibo.retEnvEvento

        if uf != self.__uf:
            del ws_envio

        return retorno
Ejemplo n.º 8
0
 def enviar_envento(self, descr_evento, chave_nfe, data_hora_evento,
                    qtd_mesmo_evento, xml_adicional):
     dh = cf(data_hora_evento, datetime.datetime)[0]
     cod_evento, xsd_evento, ev_maiusculo, xsd_envio = EVENTOS[descr_evento]
     #tz = time.altzone if time.daylight else time.timezone
     #tz = '%c%02i:%02i' % ('-' if tz > 0 else '+', tz/3600, tz/60%60)
     #dh = dh.strftime('%Y-%m-%dT%H:%M:%S') + tz
     tz = pytz.timezone(open('/etc/timezone').read().strip())
     dh = tz.localize(dh).strftime('%Y-%m-%dT%H:%M:%S%z')
     dh = dh[:-2] + ':' + dh[-2:]
     evento = PoleXML.XML()
     ev = evento.Evento if ev_maiusculo else evento.evento
     ev['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     ev['versao'] = '1.00'
     ev.infEvento[
         'Id'] = 'ID' + cod_evento + chave_nfe + "%02i" % qtd_mesmo_evento
     ev.infEvento.cOrgao = UFS_IBGE[self.__uf]
     ev.infEvento.tpAmb = self.__ambiente
     ev.infEvento.CNPJ = self.__cnpj
     ev.infEvento.chNFe = chave_nfe
     ev.infEvento.dhEvento = dh
     ev.infEvento.tpEvento = cod_evento
     ev.infEvento.nSeqEvento = qtd_mesmo_evento
     ev.infEvento.verEvento = '1.00'
     ev.infEvento.detEvento['versao'] = '1.00'
     ev.infEvento.detEvento.descEvento = descr_evento
     ev.infEvento.detEvento += xml_adicional
     self.assinar(ev.infEvento)
     # Validar xml da evento
     if not self.validar(evento, xsd_evento):
         erros = "Erro(s) no XML: "
         for erro in self.erros:
             erros += erro['type_name'] + ': ' + erro['message']
         raise ValueError(erros)
     # Lote para envio
     envio = PoleXML.XML()
     envio.envEvento['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     envio.envEvento['versao'] = '1.00'
     envio.envEvento.idLote = str(
         int(time.time() *
             100000))  # microsegundo/10 do envio - 15 dígitos no máximo
     envio.envEvento.evento = ev(1)
     recibo = self.servico('RecepcaoEvento', envio, xsd_envio)
     retorno = PoleXML.XML()
     retorno.procEventoNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     retorno.procEventoNFe['versao'] = '1.00'
     retorno.procEventoNFe.evento = ev(1)
     if recibo.retEnvEvento('retEvento'):
         retorno.procEventoNFe.retEvento = recibo.retEnvEvento.retEvento
     else:
         retorno.procEventoNFe.retEnvEvento = recibo.retEnvEvento
     return retorno
Ejemplo n.º 9
0
 def lista_eventos(self, chave):
     xml_eventos = self.consultar_chave(chave)
     eventos = PoleXML.procurar(xml_eventos, 'procEventoNFe')
     retorno = []
     for ev in eventos:
         ev.evento["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
         ev.retEvento["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
         rev = PoleXML.XML()
         rev.procEventoNFe["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
         rev.procEventoNFe["versao"] = ev["versao"]
         rev.procEventoNFe.evento = ev.evento
         rev.procEventoNFe.retEvento = ev.retEvento
         retorno.append(rev)
     return retorno
Ejemplo n.º 10
0
 def inutilizar(self,
                justificativa,
                ano,
                numero_inicial,
                numero_final=None,
                serie=1):
     if numero_final is None:
         numero_final = numero_inicial
     inutilizacao = PoleXML.XML()
     inutilizacao.inutNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     inutilizacao.inutNFe['versao'] = '2.00'
     # Id = Código da UF + Ano (2 posições) + CNPJ + modelo + série + nro inicial e nro final, precedida do literal “ID”
     inutilizacao.inutNFe.infInut['Id'] = 'ID' + UFS_IBGE[self.__uf] + str(
         int(ano) % 100) + self.__cnpj + '55' + ("%03i" % int(serie)) + (
             "%09i" % int(numero_inicial)) + ("%09i" % int(numero_final))
     inutilizacao.inutNFe.infInut.tpAmb = self.__ambiente
     inutilizacao.inutNFe.infInut.xServ = 'INUTILIZAR'
     inutilizacao.inutNFe.infInut.cUF = UFS_IBGE[self.__uf]
     inutilizacao.inutNFe.infInut.ano = int(ano) % 100
     inutilizacao.inutNFe.infInut.CNPJ = self.__cnpj
     inutilizacao.inutNFe.infInut.mod = 55
     inutilizacao.inutNFe.infInut.serie = serie
     inutilizacao.inutNFe.infInut.nNFIni = numero_inicial
     inutilizacao.inutNFe.infInut.nNFFin = numero_final
     inutilizacao.inutNFe.infInut.xJust = justificativa
     self.assinar(inutilizacao, inutilizacao.inutNFe.infInut)
     return self.servico('NfeInutilizacao2', inutilizacao)
Ejemplo n.º 11
0
 def enviar_carta_correcao(self, qtd_carta_correcao, correcao, chave_nfe,
                           data_hora_evento):
     carta = PoleXML.XML()
     carta.xCorrecao = correcao
     carta.xCondUso = 'A Carta de Correcao e disciplinada pelo paragrafo 1o-A do art. 7o do Convenio S/N, de 15 de dezembro de 1970 e pode ser utilizada para regularizacao de erro ocorrido na emissao de documento fiscal, desde que o erro nao esteja relacionado com: I - as variaveis que determinam o valor do imposto tais como: base de calculo, aliquota, diferenca de preco, quantidade, valor da operacao ou da prestacao; II - a correcao de dados cadastrais que implique mudanca do remetente ou do destinatario; III - a data de emissao ou de saida.'
     return self.enviar_envento('Carta de Correcao', chave_nfe,
                                data_hora_evento, qtd_carta_correcao, carta)
Ejemplo n.º 12
0
 def consultar_cadastro(self, CNPJ=None, IE=None, CPF=None):
     sefaz = self.__sefaz
     self.__sefaz = SEFAZ_CONSULTA[self.__uf]
     consulta = PoleXML.XML()
     consulta.ConsCad['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.ConsCad['versao'] = '3.10' if self.__uf == 'MS' else '2.00'
     consulta.ConsCad.infCons.xServ = 'CONS-CAD'
     consulta.ConsCad.infCons.UF = self.__uf
     if CNPJ is not None:
         consulta.ConsCad.infCons.CNPJ = CNPJ
     elif IE is not None:
         consulta.ConsCad.infCons.IE = IE
     elif CPF is not None:
         consulta.ConsCad.infCons.CPF = CPF
     # Para cSit = Situação do contribuinte:
     #     0 - não habilitado
     #     1 - habilitado
     # Para indCredNFe e indCredCTe:
     #     0 - Não credenciado para emissão
     #     1 - Credenciado
     #     2 - Credenciado com obrigatoriedade para todas operações
     #     3 - Credenciado com obrigatoriedade parcial
     #     4 - a SEFAZ não fornece a informação
     # Especificar a versão, pois no XML é 2.00 e o wsdl é 3.10
     retorno = self.servico('NfeConsultaCadastro',
                            consulta,
                            versao_wsdl='3.10')
     self.__sefaz = sefaz
     return retorno
Ejemplo n.º 13
0
 def enviar_nfe_e_consultar_recibo(self,
                                   xml,
                                   tentativas=30,
                                   aviso_processamento=True):
     retorno = self.enviar_nfe(xml)
     if str(retorno.retEnviNFe.cStat
            ) != '103':  # 103 = Lote recebido com sucesso
         return retorno
     recibo = str(retorno.retEnviNFe.infRec.nRec)
     consulta = PoleXML.XML()
     consulta.consReciNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.consReciNFe['versao'] = '2.00'
     consulta.consReciNFe.tpAmb = self.__ambiente
     consulta.consReciNFe.nRec = recibo
     cStat = '105'  # 105 = Lote em processamento
     tentativa = 1
     while cStat == '105' and tentativa <= tentativas:
         time.sleep(1)
         retorno = self.servico('NfeRetRecepcao2', consulta)
         cStat = str(retorno.retConsReciNFe.cStat)
         if aviso_processamento:
             print 'Tentativa ' + str(tentativa) + ': ' + str(
                 retorno.retConsReciNFe.cStat) + ' - ' + str(
                     retorno.retConsReciNFe.xMotivo)
             if cStat == '105':
                 print 'Consultando novamente...'
         tentativa += 1
     # Retorna o resultado da consulta do recibo
     if aviso_processamento:
         print 'Tentativa ' + str(tentativa - 1) + ': ' + str(
             retorno.retConsReciNFe.protNFe.infProt.cStat) + ' - ' + str(
                 retorno.retConsReciNFe.protNFe.infProt.xMotivo)
     return retorno
Ejemplo n.º 14
0
 def cancelar_chave(self, justificativa, chave_nfe, protocolo=None):
     if not protocolo:
         consulta = self.consultar_chave(chave_nfe)
         protocolo = str(consulta.retConsSitNFe.protNFe.infProt.nProt)
     cancelamento = PoleXML.XML()
     #cancelamento.cancNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     #cancelamento.cancNFe['versao'] = '2.00'
     #cancelamento.cancNFe.infCanc['Id'] = 'ID' + chave_nfe
     #cancelamento.cancNFe.infCanc.tpAmb = self.__ambiente
     #cancelamento.cancNFe.infCanc.xServ = 'CANCELAR'
     #cancelamento.cancNFe.infCanc.chNFe = chave_nfe
     #cancelamento.cancNFe.infCanc.nProt = protocolo
     #cancelamento.cancNFe.infCanc.xJust = justificativa
     #self.assinar(cancelamento, cancelamento.cancNFe.infCanc)
     #recibo = self.servico('NfeCancelamento2', cancelamento)
     #retorno = PoleXML.XML()
     #retorno.procCancNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     #retorno.procCancNFe['versao'] = '2.00'
     #retorno.procCancNFe.cancNFe = cancelamento.cancNFe
     #retorno.procCancNFe.retCancNFe = recibo.retCancNFe
     #return retorno
     cancelamento.nProt = protocolo
     cancelamento.xJust = justificativa
     return self.enviar_envento('Cancelamento', chave_nfe,
                                datetime.datetime.now(), 1, cancelamento)
Ejemplo n.º 15
0
 def enviar_nfe_e_consultar_recibo(self,
                                   xml,
                                   tentativas=30,
                                   espera_em_segundos=5,
                                   aviso_processamento=True):
     retorno = self.enviar_nfe(xml)
     # se o lote não foi recebido com sucesso (103), retorna este recibo
     if str(retorno.retEnviNFe.cStat) != '103':
         return retorno
     recibo = str(retorno.retEnviNFe.infRec.nRec)
     consulta = PoleXML.XML()
     consulta.consReciNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.consReciNFe['versao'] = '3.10'
     consulta.consReciNFe.tpAmb = self.__ambiente
     consulta.consReciNFe.nRec = recibo
     cStat = '105'  # 105 = Lote em processamento
     tentativa = 1
     while cStat == '105' and tentativa <= tentativas:
         time.sleep(espera_em_segundos)
         retorno = self.servico('NfeRetAutorizacao', consulta)
         cStat = str(retorno.retConsReciNFe.cStat)
         if aviso_processamento:
             print('Tentativa %i: %s - %s' %
                   (tentativa, str(retorno.retConsReciNFe.cStat),
                    str(retorno.retConsReciNFe.xMotivo)))
             if cStat == '105':
                 print 'Consultando novamente...'
         tentativa += 1
     # Retorna o resultado da consulta do recibo
     if aviso_processamento:
         print('Tentativa %i: %s - %s' %
               (tentativa - 1,
                str(retorno.retConsReciNFe.protNFe.infProt.cStat),
                str(retorno.retConsReciNFe.protNFe.infProt.xMotivo)))
     return retorno
Ejemplo n.º 16
0
 def consultar_recibo(self, recibo):
     # Cria a estrutra consulta pelo número do recibo e faz a consulta
     consulta = PoleXML.XML()
     consulta.consReciNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.consReciNFe['versao'] = '2.00'
     consulta.consReciNFe.tpAmb = self.__ambiente
     consulta.consReciNFe.nRec = recibo
     return self.servico('NfeRetRecepcao2', consulta)
Ejemplo n.º 17
0
 def consultar_chave(self, chave):
     consulta = PoleXML.XML()
     consulta.consSitNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.consSitNFe['versao'] = '2.01'
     consulta.consSitNFe.tpAmb = self.__ambiente
     consulta.consSitNFe.xServ = 'CONSULTAR'
     consulta.consSitNFe.chNFe = chave
     return self.servico('NfeConsulta2', consulta)
Ejemplo n.º 18
0
 def download_nfe(self, chave):
     ret = self.consultar_distribuicao_dfe(chave=chave)
     doc = ret.nfeDistDFeInteresseResult.retDistDFeInt.loteDistDFeInt.docZip
     if doc('', PoleXML.FILHOS) == 0:
         return None
     nfe = PoleXML.XML()
     nfe += doc
     return nfe
Ejemplo n.º 19
0
 def status(self):
     consulta = PoleXML.XML()
     consulta.consStatServ['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.consStatServ['versao'] = '2.00'
     consulta.consStatServ.tpAmb = self.__ambiente
     consulta.consStatServ.cUF = UFS_IBGE[self.__uf]
     consulta.consStatServ.xServ = 'STATUS'
     return self.servico('NfeStatusServico2', consulta)
Ejemplo n.º 20
0
 def download_nfe(self, chave):  # usar uf = 'AN' (ambiente nacional)
     requisicao = PoleXML.XML()
     requisicao.downloadNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     requisicao.downloadNFe['versao'] = '1.00'
     requisicao.downloadNFe.tpAmb = self.__ambiente
     requisicao.downloadNFe.xServ = 'DOWNLOAD NFE'
     requisicao.downloadNFe.CNPJ = self.__cnpj
     requisicao.downloadNFe.chNFe = chave
     return self.servico('NfeDownloadNF', requisicao)
Ejemplo n.º 21
0
 def download_nfe(self, chave):  # usar uf = 'AN' (ambiente nacional)
     requisicao = PoleXML.XML()
     requisicao.downloadNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     requisicao.downloadNFe['versao'] = '1.00'
     requisicao.downloadNFe.tpAmb = self.__ambiente
     requisicao.downloadNFe.xServ = 'DOWNLOAD NFE'
     requisicao.downloadNFe.CNPJ = self.__cnpj
     requisicao.downloadNFe.chNFe = chave
     xml_download = self.servico('NfeDownloadNF', requisicao)
     nfeProc = xml_download.retDownloadNFe.retNFe.procNFe.nfeProc
     nfeProc.NFe["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
     nfeProc.protNFe["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
     procnfe = PoleXML.XML()
     procnfe.nfeProc["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
     procnfe.nfeProc["versao"] = nfeProc["versao"]
     procnfe.nfeProc.NFe = nfeProc.NFe
     procnfe.nfeProc.protNFe = nfeProc.protNFe
     return procnfe
Ejemplo n.º 22
0
 def enviar_nfe(self, xml):
     # Realiza o parser sobre nfe, identificada como string se iniciar por '<', senão é identificada como nome de arquivo
     if type(xml) == str:
         if xml[0] == '<':
             xml = PoleXML.importar(xml)
         else:
             xml = PoleXML.importar(open(xml).read())
     if not isinstance(xml, PoleXML.XML):
         raise TypeError('A NFe em XML precisa ser passada como string XML, string com o nome do arquivo com o XML ou instância de PoleXML.XML!')
     # Assina a NFe
     self.assinar(xml.NFe.infNFe)
     # Cria envelope de lote para a NFe
     lote_nfe = PoleXML.XML()
     lote_nfe.enviNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     lote_nfe.enviNFe['versao'] = '2.00'
     lote_nfe.enviNFe.idLote = datetime.datetime.now().strftime('%y%m%d%H%M%S%f')[:15]
     lote_nfe.enviNFe += xml
     # Envia a NFe
     return self.servico('NfeRecepcao2', lote_nfe)
Ejemplo n.º 23
0
 def enviar_nfe(self, xml):
     # Realiza o parser sobre nfe, identificada como string se iniciar por '<', senão é identificada como nome de arquivo
     if type(xml) == str:
         if xml[0] == '<':
             xml = PoleXML.importar(xml)
         else:
             xml = PoleXML.importar(open(xml).read())
     if not isinstance(xml, PoleXML.XML):
         raise TypeError(
             'A NFe em XML precisa ser passada como string XML, string com o nome do arquivo com o XML ou instância de PoleXML.XML!'
         )
     # Assina a NFe
     self.assinar(xml.NFe.infNFe)
     # Cria envelope de lote para a NFe
     lote_nfe = PoleXML.XML()
     lote_nfe.enviNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     lote_nfe.enviNFe['versao'] = '2.00'
     lote_nfe.enviNFe.idLote = datetime.datetime.now().strftime(
         '%y%m%d%H%M%S%f')[:15]
     lote_nfe.enviNFe += xml
     # Envia a NFe
     return self.servico('NfeRecepcao2', lote_nfe)
Ejemplo n.º 24
0
 def servico(self, nome_wsdl, xml, nome_xsd=None):
     # Validar xml para envio
     if not self.validar(xml, nome_xsd):
         erros = "Erro(s) no XML: "
         for erro in self.erros:
             erros += erro['type_name'] + ': ' + erro['message']
         raise ValueError(erros)
     # Criar meio de transporte criptografado
     transporte = suds.transport.http.HttpTransport()
     transporte.urlopener = urllib2.build_opener(
         https_ssl(key_file=self.__chave,
                   cert_file=self.__certificado,
                   ca_file=self.__certificadoras))
     # Carrega o wsdl da estrutura de arquivos <raiz>/wsdl/<uf>/<nome_wsdl>.wsdl
     arquivo_wsdl = 'file://' + self.__raiz + '/wsdl/' + self.__sefaz + '/' + self.__str_ambiente + '/' + str(
         nome_wsdl) + '.wsdl'
     wsdl = suds.client.Client(arquivo_wsdl, transport=transporte)
     # Configurar o ambiente do SOAP
     wsdl.options.cache.clear()
     ns_anterior = suds.bindings.binding.envns
     suds.bindings.binding.envns = (
         'SOAP-ENV', 'http://www.w3.org/2003/05/soap-envelope')
     # Cria uma função do primeiro serviço, primeira URL (port) e primeiro método, visto que são únicos
     funcao = suds.client.Method(
         wsdl, wsdl.wsdl.services[0].ports[0].methods.values()[0])
     # Configura o cabeçalho e retorno em XML - Na versão do servidor não tem o parâmetro prettyxml, então tem que comentá-lo para rodar lá
     wsdl.set_options(soapheaders=self.__cabecalho(wsdl,
                                                   xml('', 1)['versao']),
                      retxml=True,
                      prettyxml=True)
     # Executa a função e coleta o resultado em XML
     resultado = funcao(suds.sax.parser.Parser().parse(
         string=PoleXML.serializar(xml)).root())
     #resultado = funcao(PoleXML.exportar(xml, -1))
     #print repr(PoleXML.importar(resultado))
     # Voltando o ambiente do SOAP
     suds.bindings.binding.envns = ns_anterior
     # Retornar o resultado na forma da classe XML, somente o corpo do envelope Soap
     return PoleXML.importar(resultado).Envelope.Body('', 1)
Ejemplo n.º 25
0
 def consultar_chave(self, chave):
     if chave[:2] == UFS_IBGE[self.__uf]:
         ws_consulta = self
     else:
         uf_consulta = dict([x[::-1] for x in UFS_IBGE.items()])[chave[:2]]
         ws_consulta = Webservice(self.__cnpj, self.__ambiente, uf_consulta,
                                  uf_consulta, self.__raiz, self.__pacote)
     consulta = PoleXML.XML()
     consulta.consSitNFe['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.consSitNFe['versao'] = '3.10'
     consulta.consSitNFe.tpAmb = self.__ambiente
     consulta.consSitNFe.xServ = 'CONSULTAR'
     consulta.consSitNFe.chNFe = chave
     return ws_consulta.servico('NfeConsultaProtocolo', consulta)
Ejemplo n.º 26
0
 def download_eventos(self, chave):
     xml_eventos = self.consultar_chave(chave)
     eventos = PoleXML.procurar(xml_eventos, 'procEventoNFe')
     retorno = []
     for ev in eventos:
         ev.evento["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
         ev.retEvento["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
         rev = PoleXML.XML()
         rev.procEventoNFe["xmlns"] = "http://www.portalfiscal.inf.br/nfe"
         rev.procEventoNFe["versao"] = ev["versao"]
         rev.procEventoNFe.evento = ev.evento
         rev.procEventoNFe.retEvento = ev.retEvento
         retorno.append(rev)
     return retorno
Ejemplo n.º 27
0
 def consultar_nfes_destinadas(self, consultar=TODAS,
                               sem_cnpj_base=False, ultimo_nsu=0):
     consulta = PoleXML.XML()
     consulta.consNFeDest['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.consNFeDest['versao'] = '1.01'
     consulta.consNFeDest.tpAmb = self.__ambiente
     consulta.consNFeDest.xServ = 'CONSULTAR NFE DEST'
     consulta.consNFeDest.CNPJ = self.__cnpj
     consulta.consNFeDest.indNFe = consultar
     consulta.consNFeDest.indEmi = +sem_cnpj_base
     consulta.consNFeDest.ultNSU = ultimo_nsu
     retorno = self.servico('NfeConsultaDest', consulta)
     while (retorno.retConsNFeDest.cStat == '138' and
            retorno.retConsNFeDest.indCont == '1'):
         consulta.consNFeDest.ultNSU = retorno.consNFeDest.ultNSU
         retorno += self.servico('NfeConsultaDest', consulta)
     return retorno
Ejemplo n.º 28
0
 def consultar_cadastro(self, CNPJ=None, IE=None, CPF=None):
     consulta = PoleXML.XML()
     consulta.ConsCad['xmlns'] = 'http://www.portalfiscal.inf.br/nfe'
     consulta.ConsCad['versao'] = '2.00'
     consulta.ConsCad.infCons.xServ = 'CONS-CAD'
     consulta.ConsCad.infCons.UF = self.__uf
     if CNPJ is not None:
         consulta.ConsCad.infCons.CNPJ = CNPJ
     elif IE is not None:
         consulta.ConsCad.infCons.IE = IE
     elif CPF is not None:
         consulta.ConsCad.infCons.CPF = CPF
     # Para cSit = Situação do contribuinte:
     #     0 - não habilitado
     #     1 - habilitado
     # Para indCredNFe e indCredCTe:
     #     0 - Não credenciado para emissão
     #     1 - Credenciado
     #     2 - Credenciado com obrigatoriedade para todas operações
     #     3 - Credenciado com obrigatoriedade parcial
     #     4 - a SEFAZ não fornece a informação
     return self.servico('CadConsultaCadastro2', consulta)
Ejemplo n.º 29
0
 def assinar(self, filho_id):
     return PoleXML.assinar(filho_id, 'Id', self.__chave,
                            self.__certificado)
Ejemplo n.º 30
0
 def verificar_assinatura(self, filho_id):
     return PoleXML.verificar_assinatura(filho_id, "Id", raiz + "/certificadoras/v1_v2_v3.crt")
Ejemplo n.º 31
0
 def verificar_assinatura(self, filho_id):
     return PoleXML.verificar_assinatura(
         filho_id, 'Id', raiz + '/certificadoras/v1_v2_v3.crt')
Ejemplo n.º 32
0
 def assinar(self, filho_id):
     return PoleXML.assinar(filho_id, 'Id', self.__chave, self.__certificado)
Ejemplo n.º 33
0
 def manifestar(self, manifestacao, chave_nfe, justificativa=None):
     manifesto = PoleXML.XML()
     if justificativa:
         manifesto.xJust = justificativa
     return self.enviar_envento(manifestacao, chave_nfe,
                                datetime.datetime.now(), 1, manifesto)
Ejemplo n.º 34
0
 def verificar_assinatura(self, filho_id):
     return PoleXML.verificar_assinatura(filho_id, 'Id', raiz + '/certificadoras/v1_v2_v3.crt')