Marcelo Salhab Brogliato 6 years ago
parent
commit
5e50345ac6
  1. 2
      README.md
  2. 3
      pynfe/entidades/base.py
  3. 24
      pynfe/entidades/notafiscal.py
  4. 24
      pynfe/processamento/comunicacao.py
  5. 81
      pynfe/processamento/serializacao.py
  6. 30
      pynfe/utils/descompactar.py
  7. 2
      pynfe/utils/flags.py
  8. 108
      pynfe/utils/webservices.py
  9. 2
      requirements-nfse.txt

2
README.md

@ -1,5 +1,5 @@
Atenção este repositório já esta em desenvolvimento para a versão NF-e 4.00, para a versão 3.10 utilize a última [release](https://github.com/leotada/PyNFe/releases).
Atualizado para a versão 4.00 NF-e/NFC-e
----------- -----------
Visão Geral Visão Geral

3
pynfe/entidades/base.py

@ -16,6 +16,9 @@ class Entidade(object):
self._fonte_dados.adicionar_objeto(self) self._fonte_dados.adicionar_objeto(self)
def __str__(self):
return self.__class__.__name__
def __repr__(self): def __repr__(self):
return '<%s %s>'%(self.__class__.__name__, str(self)) return '<%s %s>'%(self.__class__.__name__, str(self))

24
pynfe/entidades/notafiscal.py

@ -355,6 +355,7 @@ class NotaFiscal(Entidade):
self.duplicatas = [] self.duplicatas = []
self.observacoes_contribuinte = [] self.observacoes_contribuinte = []
self.processos_referenciados = [] self.processos_referenciados = []
self.responsavel_tecnico = []
super(NotaFiscal, self).__init__(*args, **kwargs) super(NotaFiscal, self).__init__(*args, **kwargs)
@ -386,7 +387,6 @@ class NotaFiscal(Entidade):
self.totais_icms_pis += obj.pis_valor self.totais_icms_pis += obj.pis_valor
self.totais_icms_cofins += obj.cofins_valor self.totais_icms_cofins += obj.cofins_valor
self.totais_icms_outras_despesas_acessorias += obj.outras_despesas_acessorias self.totais_icms_outras_despesas_acessorias += obj.outras_despesas_acessorias
self.totais_icms_total_nota += obj.valor_total_bruto
# - Valor Total do FCP (Fundo de Combate à Pobreza) # - Valor Total do FCP (Fundo de Combate à Pobreza)
self.totais_fcp += obj.fcp_valor self.totais_fcp += obj.fcp_valor
self.totais_fcp_destino += obj.fcp_destino_valor self.totais_fcp_destino += obj.fcp_destino_valor
@ -396,6 +396,12 @@ class NotaFiscal(Entidade):
self.totais_icms_inter_remetente += obj.icms_inter_remetente_valor self.totais_icms_inter_remetente += obj.icms_inter_remetente_valor
## TODO calcular impostos aproximados ## TODO calcular impostos aproximados
#self.totais_tributos_aproximado += obj.tributos #self.totais_tributos_aproximado += obj.tributos
self.totais_icms_total_nota += obj.valor_total_bruto - obj.desconto + \
obj.icms_desonerado + obj.icms_st_valor + \
obj.total_frete + obj.total_seguro + \
obj.outras_despesas_acessorias + obj.ipi_valor_ipi
return obj return obj
def adicionar_transporte_volume(self, **kwargs): def adicionar_transporte_volume(self, **kwargs):
@ -417,11 +423,17 @@ class NotaFiscal(Entidade):
return obj return obj
def adicionar_processo_referenciado(self, **kwargs): def adicionar_processo_referenciado(self, **kwargs):
u"""Adiciona uma instancia de Processo Referenciado"""
"""Adiciona uma instancia de Processo Referenciado"""
obj = NotaFiscalProcessoReferenciado(**kwargs) obj = NotaFiscalProcessoReferenciado(**kwargs)
self.processos_referenciados.append(obj) self.processos_referenciados.append(obj)
return obj return obj
def adicionar_responsavel_tecnico(self, **kwargs):
""" Adiciona uma instancia de Responsavel Tecnico """
obj = NotaFiscalResponsavelTecnico(**kwargs)
self.responsavel_tecnico.append(obj)
return obj
def _codigo_numerico_aleatorio(self): def _codigo_numerico_aleatorio(self):
self.codigo_numerico_aleatorio = str(random.randint(0, 99999999)).zfill(8) self.codigo_numerico_aleatorio = str(random.randint(0, 99999999)).zfill(8)
return self.codigo_numerico_aleatorio return self.codigo_numerico_aleatorio
@ -1003,3 +1015,11 @@ class NotaFiscalServico(Entidade):
def __str__(self): def __str__(self):
return ' '.join([str(self.identificador)]) return ' '.join([str(self.identificador)])
class NotaFiscalResponsavelTecnico(Entidade):
# NT 2018/003
cnpj = str()
contato = str()
email = str()
fone = str()
csrt = str()

24
pynfe/processamento/comunicacao.py

@ -83,7 +83,12 @@ class ComunicacaoSefaz(Comunicacao):
if ind_sinc == 1: if ind_sinc == 1:
try: try:
# Protocolo com envio OK # Protocolo com envio OK
try:
inf_prot = prot[0][0] # root protNFe inf_prot = prot[0][0] # root protNFe
except IndexError:
# Estados como GO vem com a tag header
inf_prot = prot[1][0]
lote_status = inf_prot.xpath("ns:retEnviNFe/ns:cStat", namespaces=ns)[0].text lote_status = inf_prot.xpath("ns:retEnviNFe/ns:cStat", namespaces=ns)[0].text
# Lote processado # Lote processado
if lote_status == '104': if lote_status == '104':
@ -168,7 +173,7 @@ class ComunicacaoSefaz(Comunicacao):
# url # url
url = self._get_url_an(consulta='DISTRIBUICAO') url = self._get_url_an(consulta='DISTRIBUICAO')
# Monta XML para envio da requisição # Monta XML para envio da requisição
raiz = etree.Element('distDFeInt', versao='1.00', xmlns=NAMESPACE_NFE)
raiz = etree.Element('distDFeInt', versao='1.01', xmlns=NAMESPACE_NFE)
etree.SubElement(raiz, 'tpAmb').text = str(self._ambiente) etree.SubElement(raiz, 'tpAmb').text = str(self._ambiente)
if self.uf: if self.uf:
etree.SubElement(raiz, 'cUFAutor').text = CODIGOS_ESTADOS[self.uf.upper()] etree.SubElement(raiz, 'cUFAutor').text = CODIGOS_ESTADOS[self.uf.upper()]
@ -176,15 +181,16 @@ class ComunicacaoSefaz(Comunicacao):
etree.SubElement(raiz, 'CNPJ').text = cnpj etree.SubElement(raiz, 'CNPJ').text = cnpj
else: else:
etree.SubElement(raiz, 'CPF').text = cpf etree.SubElement(raiz, 'CPF').text = cpf
if not chave:
distNSU = etree.SubElement(raiz, 'distNSU') distNSU = etree.SubElement(raiz, 'distNSU')
etree.SubElement(distNSU, 'ultNSU').text = str(nsu).zfill(15) etree.SubElement(distNSU, 'ultNSU').text = str(nsu).zfill(15)
# if chave:
# consChNFe = etree.SubElement(raiz, 'consChNFe')
# etree.SubElement(consChNFe, 'chNFe').text = chave
if chave:
consChNFe = etree.SubElement(raiz, 'consChNFe')
etree.SubElement(consChNFe, 'chNFe').text = chave
#Monta XML para envio da requisição #Monta XML para envio da requisição
xml = self._construir_xml_soap('NFeDistribuicaoDFe', raiz) xml = self._construir_xml_soap('NFeDistribuicaoDFe', raiz)
# print(url)
# print(etree.tostring(xml))
return self._post(url, xml) return self._post(url, xml)
def consulta_cadastro(self, modelo, cnpj): def consulta_cadastro(self, modelo, cnpj):
@ -287,7 +293,7 @@ class ComunicacaoSefaz(Comunicacao):
'uf': uf, 'uf': uf,
'ano': ano, 'ano': ano,
'cnpj': cnpj, 'cnpj': cnpj,
'modelo': '55',
'modelo': '55' if modelo == 'nfe' else '65', # 55=NF-e; 65=NFC-e;
'serie': serie.zfill(3), 'serie': serie.zfill(3),
'num_ini': str(numero_inicial).zfill(9), 'num_ini': str(numero_inicial).zfill(9),
'num_fin': str(numero_final).zfill(9), 'num_fin': str(numero_final).zfill(9),
@ -353,7 +359,7 @@ class ComunicacaoSefaz(Comunicacao):
raise Exception('Modelo não encontrado! Defina modelo="nfe" ou "nfce"') raise Exception('Modelo não encontrado! Defina modelo="nfe" ou "nfce"')
# Estados que utilizam outros ambientes # Estados que utilizam outros ambientes
else: else:
lista_svrs = ['AC', 'RJ', 'RN', 'PB', 'SC', 'SE', 'PI']
lista_svrs = ['AC', 'RJ', 'RN', 'PB', 'SC', 'SE', 'PI', 'DF', 'ES']
lista_svan = ['MA','PA'] lista_svan = ['MA','PA']
if self.uf.upper() in lista_svrs: if self.uf.upper() in lista_svrs:
if self._ambiente == 1: if self._ambiente == 1:
@ -419,7 +425,7 @@ class ComunicacaoSefaz(Comunicacao):
# limpa xml com caracteres bugados para infNFeSupl em NFC-e # limpa xml com caracteres bugados para infNFeSupl em NFC-e
xml = re.sub( xml = re.sub(
'<qrCode>(.*?)</qrCode>', '<qrCode>(.*?)</qrCode>',
lambda x: x.group(0).replace('&lt;', '<').replace('&gt;', '>').replace('amp;', ''),
lambda x: x.group(0).replace('&lt;', '<').replace('&gt;', '>').replace('&amp;', ''),
etree.tostring(xml, encoding='unicode').replace('\n', '') etree.tostring(xml, encoding='unicode').replace('\n', '')
) )
xml = xml_declaration + xml xml = xml_declaration + xml

81
pynfe/processamento/serializacao.py

@ -8,6 +8,7 @@ from pynfe.utils.webservices import NFCE
import base64 import base64
import hashlib import hashlib
from datetime import datetime from datetime import datetime
import re
import pytz import pytz
@ -237,6 +238,10 @@ class SerializacaoXML(Serializacao):
etree.SubElement(prod, 'uTrib').text = produto_servico.unidade_tributavel etree.SubElement(prod, 'uTrib').text = produto_servico.unidade_tributavel
etree.SubElement(prod, 'qTrib').text = str(produto_servico.quantidade_tributavel) etree.SubElement(prod, 'qTrib').text = str(produto_servico.quantidade_tributavel)
etree.SubElement(prod, 'vUnTrib').text = '{:.4f}'.format(produto_servico.valor_unitario_tributavel or 0) etree.SubElement(prod, 'vUnTrib').text = '{:.4f}'.format(produto_servico.valor_unitario_tributavel or 0)
if produto_servico.desconto:
etree.SubElement(prod, 'vDesc').text = '{:.2f}'.format(produto_servico.desconto)
""" Indica se valor do Item (vProd) entra no valor total da NF-e (vProd) """ Indica se valor do Item (vProd) entra no valor total da NF-e (vProd)
0=Valor do item (vProd) não compõe o valor total da NF-e 0=Valor do item (vProd) não compõe o valor total da NF-e
1=Valor do item (vProd) compõe o valor total da NF-e (vProd) (v2.0) 1=Valor do item (vProd) compõe o valor total da NF-e (vProd) (v2.0)
@ -257,7 +262,7 @@ class SerializacaoXML(Serializacao):
# Lei da transparencia # Lei da transparencia
# Tributos aprox por item # Tributos aprox por item
if produto_servico.valor_tributos_aprox: if produto_servico.valor_tributos_aprox:
etree.SubElement(imposto, 'vTotTrib').text = produto_servico.valor_tributos_aprox
etree.SubElement(imposto, 'vTotTrib').text = str(produto_servico.valor_tributos_aprox)
### ICMS ### ICMS
icms = etree.SubElement(imposto, 'ICMS') icms = etree.SubElement(imposto, 'ICMS')
@ -350,7 +355,7 @@ class SerializacaoXML(Serializacao):
elif produto_servico.pis_modalidade == '03': elif produto_servico.pis_modalidade == '03':
pis_item = etree.SubElement(pis, 'PISQtde') pis_item = etree.SubElement(pis, 'PISQtde')
etree.SubElement(pis_item, 'CST').text = produto_servico.pis_modalidade etree.SubElement(pis_item, 'CST').text = produto_servico.pis_modalidade
etree.SubElement(pis_item, 'qBCProd').text = produto_servico.quantidade_comercial
etree.SubElement(pis_item, 'qBCProd').text = '{:.4f}'.format(produto_servico.quantidade_comercial)
etree.SubElement(pis_item, 'vAliqProd').text = produto_servico.pis_aliquota_percentual etree.SubElement(pis_item, 'vAliqProd').text = produto_servico.pis_aliquota_percentual
etree.SubElement(pis_item, 'vPIS').text = '{:.2f}'.format(produto_servico.pis_valor_base_calculo or 0) etree.SubElement(pis_item, 'vPIS').text = '{:.2f}'.format(produto_servico.pis_valor_base_calculo or 0)
else: else:
@ -359,7 +364,7 @@ class SerializacaoXML(Serializacao):
etree.SubElement(pis_item, 'vBC').text = '{:.2f}'.format(produto_servico.pis_valor_base_calculo or 0) etree.SubElement(pis_item, 'vBC').text = '{:.2f}'.format(produto_servico.pis_valor_base_calculo or 0)
etree.SubElement(pis_item, 'pPIS').text = '{:.2f}'.format(produto_servico.pis_aliquota_percentual or 0) etree.SubElement(pis_item, 'pPIS').text = '{:.2f}'.format(produto_servico.pis_aliquota_percentual or 0)
if produto_servico.pis_modalidade is not '99': if produto_servico.pis_modalidade is not '99':
etree.SubElement(pis_item, 'qBCProd').text = produto_servico.quantidade_comercial
etree.SubElement(pis_item, 'qBCProd').text = '{:.4f}'.format(produto_servico.quantidade_comercial)
etree.SubElement(pis_item, 'vAliqProd').text = produto_servico.pis_aliquota_percentual etree.SubElement(pis_item, 'vAliqProd').text = produto_servico.pis_aliquota_percentual
etree.SubElement(pis_item, 'vPIS').text = '{:.2f}'.format(produto_servico.pis_valor_base_calculo or 0) etree.SubElement(pis_item, 'vPIS').text = '{:.2f}'.format(produto_servico.pis_valor_base_calculo or 0)
@ -386,9 +391,9 @@ class SerializacaoXML(Serializacao):
elif produto_servico.cofins_modalidade == '03': elif produto_servico.cofins_modalidade == '03':
cofins_item = etree.SubElement(cofins, 'COFINSQtde') cofins_item = etree.SubElement(cofins, 'COFINSQtde')
etree.SubElement(cofins_item, 'CST').text = produto_servico.cofins_modalidade etree.SubElement(cofins_item, 'CST').text = produto_servico.cofins_modalidade
etree.SubElement(cofins_item, 'qBCProd').text = produto_servico.quantidade_comercial
etree.SubElement(cofins_item, 'vAliqProd').text = produto_servico.cofins_aliquota_percentual
etree.SubElement(cofins_item, 'vCOFINS').text = produto_servico.cofins_valor
etree.SubElement(cofins_item, 'qBCProd').text = '{:.4f}'.format(produto_servico.quantidade_comercial)
etree.SubElement(cofins_item, 'vAliqProd').text = '{:.4f}'.format(produto_servico.cofins_aliquota_percentual)
etree.SubElement(cofins_item, 'vCOFINS').text = '{:.2f}'.format(produto_servico.cofins_valor)
else: else:
cofins_item = etree.SubElement(cofins, 'COFINSOutr') cofins_item = etree.SubElement(cofins, 'COFINSOutr')
etree.SubElement(cofins_item, 'CST').text = produto_servico.cofins_modalidade etree.SubElement(cofins_item, 'CST').text = produto_servico.cofins_modalidade
@ -411,6 +416,18 @@ class SerializacaoXML(Serializacao):
else: else:
return raiz return raiz
def _serializar_responsavel_tecnico(self, responsavel_tecnico, tag_raiz='infRespTec', retorna_string=True):
raiz = etree.Element(tag_raiz)
etree.SubElement(raiz, 'CNPJ').text = responsavel_tecnico.cnpj
etree.SubElement(raiz, 'xContato').text = responsavel_tecnico.contato
etree.SubElement(raiz, 'email').text = responsavel_tecnico.email
etree.SubElement(raiz, 'fone').text = responsavel_tecnico.fone
if retorna_string:
return etree.tostring(raiz, encoding="unicode", pretty_print=True)
else:
return raiz
def _serializar_nota_fiscal(self, nota_fiscal, tag_raiz='infNFe', retorna_string=True): def _serializar_nota_fiscal(self, nota_fiscal, tag_raiz='infNFe', retorna_string=True):
raiz = etree.Element(tag_raiz, versao=self._versao) raiz = etree.Element(tag_raiz, versao=self._versao)
@ -638,6 +655,12 @@ class SerializacaoXML(Serializacao):
if nota_fiscal.informacoes_complementares_interesse_contribuinte: if nota_fiscal.informacoes_complementares_interesse_contribuinte:
etree.SubElement(info_ad, 'infCpl').text = nota_fiscal.informacoes_complementares_interesse_contribuinte etree.SubElement(info_ad, 'infCpl').text = nota_fiscal.informacoes_complementares_interesse_contribuinte
# Responsavel Tecnico NT2018/003
if nota_fiscal.responsavel_tecnico:
raiz.append(self._serializar_responsavel_tecnico(
nota_fiscal.responsavel_tecnico[0], retorna_string=False))
if retorna_string: if retorna_string:
return etree.tostring(raiz, encoding="unicode", pretty_print=True) return etree.tostring(raiz, encoding="unicode", pretty_print=True)
else: else:
@ -677,7 +700,7 @@ class SerializacaoXML(Serializacao):
class SerializacaoQrcode(object): class SerializacaoQrcode(object):
""" Classe que gera e serializa o qrcode de NFC-e no xml """ """ Classe que gera e serializa o qrcode de NFC-e no xml """
def gerar_qrcode(self, token, csc, xml, return_qr=False):
def gerar_qrcode(self, token, csc, xml, return_qr=False, online=True):
""" Classe para gerar url do qrcode da NFC-e """ """ Classe para gerar url do qrcode da NFC-e """
# Procura atributos no xml # Procura atributos no xml
ns = {'ns':NAMESPACE_NFE} ns = {'ns':NAMESPACE_NFE}
@ -700,37 +723,55 @@ class SerializacaoQrcode(object):
except IndexError: except IndexError:
cpf = None cpf = None
total = nfe.xpath('ns:infNFe/ns:total/ns:ICMSTot/ns:vNF/text()', namespaces=ns)[0] total = nfe.xpath('ns:infNFe/ns:total/ns:ICMSTot/ns:vNF/text()', namespaces=ns)[0]
icms = nfe.xpath('ns:infNFe/ns:total/ns:ICMSTot/ns:vICMS/text()', namespaces=ns)[0]
# icms = nfe.xpath('ns:infNFe/ns:total/ns:ICMSTot/ns:vICMS/text()', namespaces=ns)[0]
digest = nfe.xpath('sig:Signature/sig:SignedInfo/sig:Reference/sig:DigestValue/text()', namespaces=sig)[0].encode() digest = nfe.xpath('sig:Signature/sig:SignedInfo/sig:Reference/sig:DigestValue/text()', namespaces=sig)[0].encode()
data = base64.b16encode(data).decode()
digest = base64.b16encode(digest).decode()
lista_dia = re.findall("-\d{2}", str(data))
dia = str(lista_dia[1])
dia = dia[1:]
replacements = {'0': ''}
token = re.sub('([0])', lambda m: replacements[m.group()], token)
if cpf is None:
url = 'chNFe={}&nVersao={}&tpAmb={}&dhEmi={}&vNF={}&vICMS={}&digVal={}&cIdToken={}'.format(
chave, VERSAO_QRCODE, tpamb, data.lower(), total, icms, digest.lower(), token)
#VERSAO_QRCODE =2
if online:
#versão online
url = '{}|{}|{}|{}'.format(chave,VERSAO_QRCODE, tpamb, token)
else: else:
url = 'chNFe={}&nVersao={}&tpAmb={}&cDest={}&dhEmi={}&vNF={}&vICMS={}&digVal={}&cIdToken={}'.format(
chave, VERSAO_QRCODE, tpamb, cpf, data.lower(), total, icms, digest.lower(), token)
#versão offline
digest = digest.lower()
digest = digest.hex()
url_hash = hashlib.sha1(url.encode()+csc.encode()).digest()
url = '{}|{}|{}|{}|{}|{}|{}'.format(
chave,VERSAO_QRCODE,tpamb,dia,total,digest,token
)
url_complementar = url + csc
url_hash = hashlib.sha1(url_complementar.encode()).digest()
url_hash = base64.b16encode(url_hash).decode() url_hash = base64.b16encode(url_hash).decode()
url = url + '&cHashQRCode=' + url_hash.upper()
url = 'p={}|{}'.format(url, url_hash)
# url_chave - Texto com a URL de consulta por chave de acesso a ser impressa no DANFE NFC-e. # url_chave - Texto com a URL de consulta por chave de acesso a ser impressa no DANFE NFC-e.
# Informar a URL da “Consulta por chave de acesso da NFC-e”. # Informar a URL da “Consulta por chave de acesso da NFC-e”.
# A mesma URL que deve estar informada no DANFE NFC-e para consulta por chave de acesso # A mesma URL que deve estar informada no DANFE NFC-e para consulta por chave de acesso
lista_uf_padrao = ['PR', 'CE', 'RS', 'RJ', 'RO']
lista_uf_padrao = ['PR', 'CE', 'RS', 'RJ', 'RO', 'DF']
if uf.upper() in lista_uf_padrao: if uf.upper() in lista_uf_padrao:
qrcode = NFCE[uf.upper()]['QR'] + url qrcode = NFCE[uf.upper()]['QR'] + url
url_chave = NFCE[uf.upper()]['URL'] url_chave = NFCE[uf.upper()]['URL']
elif uf.upper() == 'SP': elif uf.upper() == 'SP':
if tpamb == '1': if tpamb == '1':
qrcode = NFCE[uf.upper()]['HTTPS'] + 'www.' + NFCE[uf.upper()]['QR'] + url qrcode = NFCE[uf.upper()]['HTTPS'] + 'www.' + NFCE[uf.upper()]['QR'] + url
url_chave = NFCE[uf.upper()]['HTTPS'] + 'www.' + NFCE[uf.upper()]['URL'] + url
url_chave = NFCE[uf.upper()]['HTTPS'] + 'www.' + NFCE[uf.upper()]['URL']
else: else:
qrcode = NFCE[uf.upper()]['HTTPS'] + 'www.homologacao.' + NFCE[uf.upper()]['QR'] + url qrcode = NFCE[uf.upper()]['HTTPS'] + 'www.homologacao.' + NFCE[uf.upper()]['QR'] + url
url_chave = NFCE[uf.upper()]['HTTPS'] + 'www.homologacao.' + NFCE[uf.upper()]['URL'] + url
url_chave = NFCE[uf.upper()]['HTTPS'] + 'www.homologacao.' + NFCE[uf.upper()]['URL']
# BA tem comportamento distindo para qrcode e url
elif uf.upper() == 'BA':
if tpamb == '1':
qrcode = NFCE[uf.upper()]['HTTPS'] + NFCE[uf.upper()]['QR'] + url
else:
qrcode = NFCE[uf.upper()]['HOMOLOGACAO'] + NFCE[uf.upper()]['QR'] + url
url_chave = url_chave = NFCE[uf.upper()]['URL']
# AC, AM, RR, PA, # AC, AM, RR, PA,
else: else:
if tpamb == '1': if tpamb == '1':

30
pynfe/utils/descompactar.py

@ -0,0 +1,30 @@
"""
@author: Lucas Resende
classe que descompacta o gzip recebido pela consulta distribuicao
"""
from io import BytesIO
import base64
import gzip
from lxml import etree
class DescompactaGzip(object):
@staticmethod
def descompacta(stringZipada):
"""
:paramn stringZipada: String
:return : Etree
"""
arq = BytesIO()
arq.write(base64.b64decode(stringZipada))
arq.seek(0)
zip = gzip.GzipFile(fileobj=arq)
texto = zip.read()
arq.close()
zip.close()
descompactado = texto.decode('utf-8')
return etree.fromstring(descompactado)

2
pynfe/utils/flags.py

@ -12,7 +12,7 @@ NAMESPACE_BETHA = 'http://www.betha.com.br/e-nota-contribuinte-ws'
VERSAO_PADRAO = '4.00' VERSAO_PADRAO = '4.00'
VERSAO_QRCODE = '100'
VERSAO_QRCODE = '2'
TIPOS_DOCUMENTO = ( TIPOS_DOCUMENTO = (
'CNPJ', 'CNPJ',

108
pynfe/utils/webservices.py

@ -27,12 +27,12 @@ NFCE = {
'AM': { 'AM': {
# csc_homologacao = '0123456789' # csc_homologacao = '0123456789'
# token_homologacao = '000001' # token_homologacao = '000001'
'STATUS': 'nfce.sefaz.am.gov.br/nfce-services-nac/services/NfeStatusServico2',
'AUTORIZACAO': 'nfce.sefaz.am.gov.br/nfce-services-nac/services/NfeAutorizacao',
'RECIBO': 'nfce.sefaz.am.gov.br/nfce-services-nac/services/NfeRetAutorizacao',
'CHAVE': 'nfce.sefaz.am.gov.br/nfce-services-nac/services/NfeConsulta2',
'INUTILIZACAO': 'nfce.sefaz.am.gov.br/nfce-services-nac/services/NfeInutilizacao2',
'EVENTOS': 'nfce.sefaz.am.gov.br/nfce-services-nac/services/RecepcaoEvento',
'STATUS': 'nfe.sefaz.am.gov.br/services2/services/NfeStatusServico4',
'AUTORIZACAO': 'nfe.sefaz.am.gov.br/services2/services/NfeAutorizacao4',
'RECIBO': 'nfe.sefaz.am.gov.br/services2/services/NfeRetAutorizacao4',
'CHAVE': 'nfe.sefaz.am.gov.br/services2/services/NfeConsulta4',
'INUTILIZACAO': 'nfe.sefaz.am.gov.br/services2/services/NfeInutilizacao4',
'EVENTOS': 'nfe.sefaz.am.gov.br/services2/services/RecepcaoEvento4',
'QR': 'sefaz.am.gov.br/nfceweb/consultarNFCe.jsp?', 'QR': 'sefaz.am.gov.br/nfceweb/consultarNFCe.jsp?',
'URL': 'sefaz.am.gov.br/nfceweb/formConsulta.do', 'URL': 'sefaz.am.gov.br/nfceweb/formConsulta.do',
'HTTPS': 'http://sistemas.', 'HTTPS': 'http://sistemas.',
@ -126,10 +126,10 @@ NFCE = {
'CHAVE': '', 'CHAVE': '',
'INUTILIZACAO': '', 'INUTILIZACAO': '',
'EVENTOS': '', 'EVENTOS': '',
'QR': 'sefaz.pe.gov.br/nfce-web/consultarNFCe?',
'QR': 'sefaz.pe.gov.br/nfce/consulta?',
'HTTPS': 'http://nfce.', 'HTTPS': 'http://nfce.',
'HOMOLOGACAO': 'http://nfcehomolog.', 'HOMOLOGACAO': 'http://nfcehomolog.',
'URL': 'sefaz.pe.gov.br/nfce-web/consultarNFCe'
'URL': 'sefaz.pe.gov.br/nfce/consulta'
}, },
'AL': { 'AL': {
'STATUS': '', 'STATUS': '',
@ -152,19 +152,23 @@ NFCE = {
'CHAVE': '', 'CHAVE': '',
'INUTILIZACAO': '', 'INUTILIZACAO': '',
'EVENTOS': '', 'EVENTOS': '',
'QR': 'sefaz.ba.gov.br/servicos/nfce/modulos/geral/NFCEC_consulta_chave_acesso.aspx?',
'QR': 'sefaz.ba.gov.br/servicos/nfce/qrcode.aspx?',
'HTTPS': 'http://nfe.', 'HTTPS': 'http://nfe.',
'HOMOLOGACAO': 'http://hnfe.', 'HOMOLOGACAO': 'http://hnfe.',
'URL': 'nfe.sefaz.ba.gov.br/servicos/nfce/default.aspx'
'URL': 'http://hinternet.sefaz.ba.gov.br/nfce/consulta'
}, },
'MG': { 'MG': {
'STATUS': '',
'AUTORIZACAO': '',
'RECIBO': '',
'CHAVE': '',
'INUTILIZACAO': '',
'EVENTOS': '',
'QR': ''
'STATUS': 'fazenda.mg.gov.br/nfce/services/NFeStatusServico4',
'AUTORIZACAO': 'fazenda.mg.gov.br/nfce/services/NFeAutorizacao4',
'RECIBO': 'fazenda.mg.gov.br/nfce/services/NFeRetAutorizacao4',
'CHAVE': 'fazenda.mg.gov.br/nfce/services/NFeConsultaProtocolo4',
'INUTILIZACAO': 'fazenda.mg.gov.br/nfce/services/NFeInutilizacao4',
'EVENTOS': 'fazenda.mg.gov.br/nfce/services/NFeRecepcaoEvento4',
'CADASTRO': 'fazenda.mg.gov.br/nfce/services/CadConsultaCadastro4',
'QR': 'fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml?',
'HTTPS': 'https://nfce.',
'HOMOLOGACAO': 'https://hnfce.',
'URL': 'fazenda.mg.gov.br/portalnfce'
}, },
'ES': { 'ES': {
'STATUS': '', 'STATUS': '',
@ -173,7 +177,10 @@ NFCE = {
'CHAVE': '', 'CHAVE': '',
'INUTILIZACAO': '', 'INUTILIZACAO': '',
'EVENTOS': '', 'EVENTOS': '',
'QR': ''
'QR': 'sefaz.es.gov.br/ConsultaNFCe/qrcode.aspx? ',
'HTTPS': 'http://nfe.',
'HOMOLOGACAO': 'http://homologacao.',
'URL': 'www.sefaz.es.gov.br/nfce/consulta'
}, },
'RJ': { 'RJ': {
'STATUS': '', 'STATUS': '',
@ -200,7 +207,7 @@ NFCE = {
'INUTILIZACAO': 'nfce.fazenda.sp.gov.br/ws/NFeInutilizacao4.asmx', 'INUTILIZACAO': 'nfce.fazenda.sp.gov.br/ws/NFeInutilizacao4.asmx',
'EVENTOS': 'nfce.fazenda.sp.gov.br/ws/NFeRecepcaoEvento4.asmx', 'EVENTOS': 'nfce.fazenda.sp.gov.br/ws/NFeRecepcaoEvento4.asmx',
'QR': 'nfce.fazenda.sp.gov.br/NFCeConsultaPublica/Paginas/ConsultaQRCode.aspx?', 'QR': 'nfce.fazenda.sp.gov.br/NFCeConsultaPublica/Paginas/ConsultaQRCode.aspx?',
'URL': 'nfce.fazenda.sp.gov.br/NFCeConsultaPublica/Paginas/ConsultaPublica.aspx',
'URL': 'nfce.fazenda.sp.gov.br/consulta',
'HTTPS': 'https://', 'HTTPS': 'https://',
'HOMOLOGACAO': 'https://homologacao.' 'HOMOLOGACAO': 'https://homologacao.'
}, },
@ -213,7 +220,7 @@ NFCE = {
'EVENTOS': 'nfce.sefa.pr.gov.br/nfce/NFeRecepcaoEvento4?wsdl', 'EVENTOS': 'nfce.sefa.pr.gov.br/nfce/NFeRecepcaoEvento4?wsdl',
'CADASTRO': 'nfce.sefa.pr.gov.br/nfce/CadConsultaCadastro4?wsdl', 'CADASTRO': 'nfce.sefa.pr.gov.br/nfce/CadConsultaCadastro4?wsdl',
'QR': 'http://www.fazenda.pr.gov.br/nfce/qrcode?', 'QR': 'http://www.fazenda.pr.gov.br/nfce/qrcode?',
'URL': 'http://www.fazenda.pr.gov.br',
'URL': 'http://www.fazenda.pr.gov.br/nfce/consulta',
'HTTPS': 'https://', 'HTTPS': 'https://',
'HOMOLOGACAO': 'https://homologacao.' 'HOMOLOGACAO': 'https://homologacao.'
}, },
@ -261,8 +268,13 @@ NFCE = {
'EVENTOS': 'sefaz.go.gov.br/nfe/services/NFeRecepcaoEvento4?wsdl', 'EVENTOS': 'sefaz.go.gov.br/nfe/services/NFeRecepcaoEvento4?wsdl',
'QR': 'sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe?', 'QR': 'sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe?',
'CADASTRO': 'sefaz.go.gov.br/nfe/services/CadConsultaCadastro4?wsdl', 'CADASTRO': 'sefaz.go.gov.br/nfe/services/CadConsultaCadastro4?wsdl',
'HTTPS': 'http://nfe.',
'HOMOLOGACAO': 'http://homolog.'
'HTTPS': 'https://nfe.',
'HOMOLOGACAO': 'https://homolog.',
'URL': 'sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe'
},
'DF': {
'QR': 'http://www.fazenda.df.gov.br/nfce/qrcode?',
'URL': 'www.fazenda.df.gov.br/nfce/consulta'
}, },
# RO, AC, RR, PA, AP, TO, MA, PI, RN, PB, AL, SE, BA, ES, RJ, GO, DF # RO, AC, RR, PA, AP, TO, MA, PI, RN, PB, AL, SE, BA, ES, RJ, GO, DF
'SVRS': { 'SVRS': {
@ -290,12 +302,12 @@ NFE = {
'HOMOLOGACAO': 'https://hom' 'HOMOLOGACAO': 'https://hom'
}, },
'AM': { 'AM': {
'STATUS': 'nfe.sefaz.am.gov.br/services2/services/NfeStatusServico2',
'AUTORIZACAO': 'nfe.sefaz.am.gov.br/services2/services/NfeAutorizacao',
'RECIBO': 'nfe.sefaz.am.gov.br/services2/services/NfeRetAutorizacao',
'CHAVE': 'nfe.sefaz.am.gov.br/services2/services/NfeConsulta2',
'INUTILIZACAO': 'nfe.sefaz.am.gov.br/services2/services/NfeInutilizacao2',
'EVENTOS': 'nfe.sefaz.am.gov.br/services2/services/RecepcaoEvento',
'STATUS': 'nfe.sefaz.am.gov.br/services2/services/NfeStatusServico4',
'AUTORIZACAO': 'nfe.sefaz.am.gov.br/services2/services/NfeAutorizacao4',
'RECIBO': 'nfe.sefaz.am.gov.br/services2/services/NfeRetAutorizacao4',
'CHAVE': 'nfe.sefaz.am.gov.br/services2/services/NfeConsulta4',
'INUTILIZACAO': 'nfe.sefaz.am.gov.br/services2/services/NfeInutilizacao4',
'EVENTOS': 'nfe.sefaz.am.gov.br/services2/services/RecepcaoEvento4',
'CADASTRO': 'nfe.sefaz.am.gov.br/services2/services/cadconsultacadastro2', 'CADASTRO': 'nfe.sefaz.am.gov.br/services2/services/cadconsultacadastro2',
'HTTPS': 'https://', 'HTTPS': 'https://',
'HOMOLOGACAO': 'https://hom' 'HOMOLOGACAO': 'https://hom'
@ -310,7 +322,7 @@ NFE = {
'CHAVE': 'sefaz.ce.gov.br/nfe4/services/NFeConsultaProtocolo4?WSDL', 'CHAVE': 'sefaz.ce.gov.br/nfe4/services/NFeConsultaProtocolo4?WSDL',
'INUTILIZACAO': 'sefaz.ce.gov.br/nfe4/services/NFeInutilizacao4?WSDL', 'INUTILIZACAO': 'sefaz.ce.gov.br/nfe4/services/NFeInutilizacao4?WSDL',
'EVENTOS': 'sefaz.ce.gov.br/nfe4/services/NFeRecepcaoEvento4?WSDL', 'EVENTOS': 'sefaz.ce.gov.br/nfe4/services/NFeRecepcaoEvento4?WSDL',
'CADASTRO': 'sefaz.ce.gov.br/nfe2/services/CadConsultaCadastro2?wsdl',
'CADASTRO': 'nfe.sefaz.ce.gov.br/nfe4/services/CadConsultaCadastro4?wsdl',
'DOWNLOAD': 'sefaz.ce.gov.br/nfe2/services/NfeDownloadNF?wsdl', 'DOWNLOAD': 'sefaz.ce.gov.br/nfe2/services/NfeDownloadNF?wsdl',
'HTTPS': 'https://nfe.', 'HTTPS': 'https://nfe.',
'HOMOLOGACAO': 'https://nfeh.' 'HOMOLOGACAO': 'https://nfeh.'
@ -343,16 +355,16 @@ NFE = {
'RECIBO': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeRetAutorizacao4', 'RECIBO': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeRetAutorizacao4',
'CHAVE': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeConsulta4', 'CHAVE': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeConsulta4',
'INUTILIZACAO': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeInutilizacao4', 'INUTILIZACAO': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeInutilizacao4',
'EVENTOS': 'nfe.fazenda.mg.gov.br/nfe2/services/RecepcaoEvento',
'EVENTOS': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeRecepcaoEvento4',
'CADASTRO': 'nfe.fazenda.mg.gov.br/nfe2/services/cadconsultacadastro2', 'CADASTRO': 'nfe.fazenda.mg.gov.br/nfe2/services/cadconsultacadastro2',
'HTTPS': 'https://', 'HTTPS': 'https://',
'HOMOLOGACAO': 'https://h' 'HOMOLOGACAO': 'https://h'
}, },
'SP': { 'SP': {
'STATUS': 'nfe.fazenda.sp.gov.br/ws/NFeStatusServico4.asmx',
'STATUS': 'nfe.fazenda.sp.gov.br/ws/nfestatusservico4.asmx',
'AUTORIZACAO': 'nfe.fazenda.sp.gov.br/ws/nfeautorizacao4.asmx', 'AUTORIZACAO': 'nfe.fazenda.sp.gov.br/ws/nfeautorizacao4.asmx',
'RECIBO': 'nfe.fazenda.sp.gov.br/ws/nferetautorizacao4.asmx', 'RECIBO': 'nfe.fazenda.sp.gov.br/ws/nferetautorizacao4.asmx',
'CHAVE': 'nfe.fazenda.sp.gov.br/ws/nfeconsulta4.asmx',
'CHAVE': 'nfe.fazenda.sp.gov.br/ws/nfeconsultaprotocolo4.asmx',
'INUTILIZACAO': 'nfe.fazenda.sp.gov.br/ws/nfeinutilizacao4.asmx', 'INUTILIZACAO': 'nfe.fazenda.sp.gov.br/ws/nfeinutilizacao4.asmx',
'EVENTOS': 'nfe.fazenda.sp.gov.br/ws/nferecepcaoevento4.asmx', 'EVENTOS': 'nfe.fazenda.sp.gov.br/ws/nferecepcaoevento4.asmx',
'CADASTRO': 'nfe.fazenda.sp.gov.br/ws/cadconsultacadastro4.asmx', 'CADASTRO': 'nfe.fazenda.sp.gov.br/ws/cadconsultacadastro4.asmx',
@ -378,31 +390,31 @@ NFE = {
'CHAVE': 'sefazrs.rs.gov.br/ws/NfeConsulta/NfeConsulta4.asmx', 'CHAVE': 'sefazrs.rs.gov.br/ws/NfeConsulta/NfeConsulta4.asmx',
'INUTILIZACAO': 'sefazrs.rs.gov.br/ws/nfeinutilizacao/nfeinutilizacao4.asmx', 'INUTILIZACAO': 'sefazrs.rs.gov.br/ws/nfeinutilizacao/nfeinutilizacao4.asmx',
'EVENTOS': 'sefazrs.rs.gov.br/ws/recepcaoevento/recepcaoevento4.asmx', 'EVENTOS': 'sefazrs.rs.gov.br/ws/recepcaoevento/recepcaoevento4.asmx',
'CADASTRO': 'https://cad.sefazrs.rs.gov.br/ws/cadconsultacadastro/cadconsultacadastro2.asmx',
'CADASTRO': 'cad.sefazrs.rs.gov.br/ws/cadconsultacadastro/cadconsultacadastro2.asmx',
'DOWNLOAD': 'sefazrs.rs.gov.br/ws/nfeDownloadNF/nfeDownloadNF.asmx', 'DOWNLOAD': 'sefazrs.rs.gov.br/ws/nfeDownloadNF/nfeDownloadNF.asmx',
'DESTINADAS': 'sefazrs.rs.gov.br/ws/nfeConsultaDest/nfeConsultaDest.asmx', 'DESTINADAS': 'sefazrs.rs.gov.br/ws/nfeConsultaDest/nfeConsultaDest.asmx',
'HTTPS': 'https://nfe.', 'HTTPS': 'https://nfe.',
'HOMOLOGACAO': 'https://nfe-homologacao.' 'HOMOLOGACAO': 'https://nfe-homologacao.'
}, },
'MS': { 'MS': {
'STATUS': 'nfe.ms.gov.br/ws/NFeStatusServico4',
'AUTORIZACAO': 'nfe.ms.gov.br/ws/NFeAutorizacao4',
'RECIBO': 'nfe.ms.gov.br/ws/NFeRetAutorizacao4',
'CHAVE': 'nfe.ms.gov.br/ws/NFeConsultaProtocolo4',
'INUTILIZACAO': 'nfe.ms.gov.br/ws/NFeInutilizacao4',
'EVENTOS': 'nfe.ms.gov.br/ws/NFeRecepcaoEvento4',
'CADASTRO': 'nfe.fazenda.ms.gov.br/producao/services2/CadConsultaCadastro2',
'STATUS': 'nfe.sefaz.ms.gov.br/ws/NFeStatusServico4',
'AUTORIZACAO': 'nfe.sefaz.ms.gov.br/ws/NFeAutorizacao4',
'RECIBO': 'nfe.sefaz.ms.gov.br/ws/NFeRetAutorizacao4',
'CHAVE': 'nfe.sefaz.ms.gov.br/ws/NFeConsultaProtocolo4',
'INUTILIZACAO': 'nfe.sefaz.ms.gov.br/ws/NFeInutilizacao4',
'EVENTOS': 'nfe.sefaz.ms.gov.br/ws/NFeRecepcaoEvento4',
'CADASTRO': 'nfe.sefaz.ms.gov.br/ws/CadConsultaCadastro4',
'HTTPS': 'https://', 'HTTPS': 'https://',
'HOMOLOGACAO': 'https://homologacao.'
'HOMOLOGACAO': 'https://hom.'
}, },
'MT': { 'MT': {
'STATUS': 'sefaz.mt.gov.br/nfews/v2/services/NfeStatusServico2?wsdl',
'AUTORIZACAO': 'sefaz.mt.gov.br/nfews/v2/services/NfeAutorizacao?wsdl',
'RECIBO': 'sefaz.mt.gov.br/nfews/v2/services/NfeRetAutorizacao?wsdl',
'CHAVE': 'sefaz.mt.gov.br/nfews/v2/services/NfeConsulta2?wsdl',
'INUTILIZACAO': 'sefaz.mt.gov.br/nfews/v2/services/NfeInutilizacao2?wsdl',
'EVENTOS': 'sefaz.mt.gov.br/nfews/v2/services/RecepcaoEvento?wsdl',
'CADASTRO': 'sefaz.mt.gov.br/nfews/v2/services/CadConsultaCadastro2?wsdl',
'STATUS': 'sefaz.mt.gov.br/nfews/v2/services/NfeStatusServico4?wsdl',
'AUTORIZACAO': 'sefaz.mt.gov.br/nfews/v2/services/NfeAutorizacao4?wsdl',
'RECIBO': 'sefaz.mt.gov.br/nfews/v2/services/NfeRetAutorizacao4?wsdl',
'CHAVE': 'sefaz.mt.gov.br/nfews/v2/services/NfeConsulta4?wsdl',
'INUTILIZACAO': 'sefaz.mt.gov.br/nfews/v2/services/NfeInutilizacao4?wsdl',
'EVENTOS': 'sefaz.mt.gov.br/nfews/v2/services/RecepcaoEvento4?wsdl',
'CADASTRO': 'sefaz.mt.gov.br/nfews/v2/services/CadConsultaCadastro4?wsdl',
'HTTPS': 'https://nfe.', 'HTTPS': 'https://nfe.',
'HOMOLOGACAO': 'https://homologacao.' 'HOMOLOGACAO': 'https://homologacao.'
}, },

2
requirements-nfse.txt

@ -1,3 +1,3 @@
# Opcional para NFS-e # Opcional para NFS-e
suds-jurko suds-jurko
pyxb
pyxb=1.2.4
Loading…
Cancel
Save