From bd068e35188dbd46bcc749d1fa5bac805962fe96 Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 3 Sep 2018 13:20:10 -0300 Subject: [PATCH 01/33] [fix] teste url qrcode nfce 4.00 BA --- pynfe/processamento/serializacao.py | 7 +++++++ pynfe/utils/webservices.py | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index bd2ad3a..a65596e 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -727,6 +727,13 @@ class SerializacaoQrcode(object): else: 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 + # 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, else: if tpamb == '1': diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 579d07e..270d40c 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -151,10 +151,10 @@ NFCE = { 'CHAVE': '', 'INUTILIZACAO': '', '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.', 'HOMOLOGACAO': 'http://hnfe.', - 'URL': 'nfe.sefaz.ba.gov.br/servicos/nfce/default.aspx' + 'URL': 'http://hinternet.sefaz.ba.gov.br/nfce/consulta' }, 'MG': { 'STATUS': '', From 04ccedcf072b5d1b768dfba008b3ba63e1b89333 Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 3 Sep 2018 13:24:12 -0300 Subject: [PATCH 02/33] =?UTF-8?q?[fix]=20atualizado=20readme=20vers=C3=A3o?= =?UTF-8?q?=204.00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01f7436..eb45520 100644 --- a/README.md +++ b/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 From e077e6d412c90c0cac96e1f249b9c56a8e075283 Mon Sep 17 00:00:00 2001 From: erikseyti Date: Thu, 20 Sep 2018 10:03:34 -0300 Subject: [PATCH 03/33] [NEW] Qrcode 2 funcionando de forma online --- pynfe/processamento/serializacao.py | 90 +++++++++++++++++++++++++++---------- pynfe/utils/flags.py | 10 ++--- qrCode2Teste.py | 33 ++++++++++++++ 3 files changed, 104 insertions(+), 29 deletions(-) create mode 100644 qrCode2Teste.py diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index a65596e..0e520bf 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -8,6 +8,7 @@ from pynfe.utils.webservices import NFCE import base64 import hashlib from datetime import datetime +import re class Serializacao(object): @@ -291,17 +292,17 @@ class SerializacaoXML(Serializacao): etree.SubElement(icms_item, 'modBC').text = str(produto_servico.icms_modalidade_determinacao_bc) # 00=Tributada integralmente. if produto_servico.icms_modalidade == '00': - etree.SubElement(icms_item, 'vBC').text = str(produto_servico.icms_valor_base_calculo) # Valor da BC do ICMS + etree.SubElement(icms_item, 'vBC').text = str(produto_servico.icms_valor_base_calculo) # Valor da BC do ICMS etree.SubElement(icms_item, 'pICMS').text = str(produto_servico.icms_aliquota) # Alíquota do imposto - etree.SubElement(icms_item, 'vICMS').text = '{:.2f}'.format(produto_servico.icms_valor or 0) # Valor do ICMS + etree.SubElement(icms_item, 'vICMS').text = '{:.2f}'.format(produto_servico.icms_valor or 0) # Valor do ICMS # 10=Tributada e com cobrança do ICMS por substituição tributária elif produto_servico.icms_modalidade == '10': - etree.SubElement(icms_item, 'vBC').text = str(produto_servico.icms_valor_base_calculo) # Valor da BC do ICMS + etree.SubElement(icms_item, 'vBC').text = str(produto_servico.icms_valor_base_calculo) # Valor da BC do ICMS etree.SubElement(icms_item, 'pICMS').text = str(produto_servico.icms_aliquota) # Alíquota do imposto - etree.SubElement(icms_item, 'vICMS').text = '{:.2f}'.format(produto_servico.icms_valor or 0) # Valor do ICMS + etree.SubElement(icms_item, 'vICMS').text = '{:.2f}'.format(produto_servico.icms_valor or 0) # Valor do ICMS # Modalidade de determinação da BC do ICMS ST # 0=Preço tabelado ou máximo sugerido; 1=Lista Negativa (valor);2=Lista Positiva (valor);3=Lista Neutra (valor);4=Margem Valor Agregado (%);5=Pauta (valor); - etree.SubElement(icms_item, 'modBCST').text = str(produto_servico.icms_st_modalidade_determinacao_bc) + etree.SubElement(icms_item, 'modBCST').text = str(produto_servico.icms_st_modalidade_determinacao_bc) etree.SubElement(icms_item, 'pMVAST').text = str(produto_servico.icms_st_percentual_adicional) # Percentual da margem de valor Adicionado do ICMS ST etree.SubElement(icms_item, 'pRedBCST').text = str(produto_servico.icms_st_percentual_reducao_bc) # APercentual da Redução de BC do ICMS ST etree.SubElement(icms_item, 'vBCST ').text = str(produto_servico.icms_st_valor_base_calculo) @@ -310,16 +311,16 @@ class SerializacaoXML(Serializacao): # 20=Com redução de base de cálculo elif produto_servico.icms_modalidade == '20': etree.SubElement(icms_item, 'pRedBC').text = '{:.2f}'.format(produto_servico.icms_percentual_reducao_bc or 0) # Percentual da Redução de BC - etree.SubElement(icms_item, 'vBC').text = '{:.2f}'.format(produto_servico.icms_valor_base_calculo or 0) # Valor da BC do ICMS + etree.SubElement(icms_item, 'vBC').text = '{:.2f}'.format(produto_servico.icms_valor_base_calculo or 0) # Valor da BC do ICMS etree.SubElement(icms_item, 'pICMS').text = '{:.2f}'.format(produto_servico.icms_aliquota or 0) # Alíquota do imposto etree.SubElement(icms_item, 'vICMS').text = '{:.2f}'.format(produto_servico.icms_valor or 0) # Valor do ICMS # NT_2016_002 - # Inclusão das regras de validação N17b-20, N23b-20 e N27b-20 que impedem que seja informado zero como percentual de FCP ou FCP ST. + # Inclusão das regras de validação N17b-20, N23b-20 e N27b-20 que impedem que seja informado zero como percentual de FCP ou FCP ST. # Os campos relativos ao Fundo de Combate à Pobreza só devem ser informados se o produto estiver sujeito a incidência do mesmo. - if produto_servico.fcp_valor: + if produto_servico.fcp_valor: etree.SubElement(icms_item, 'vBCFCP').text = '{:.2f}'.format(produto_servico.fcp_base_calculo or 0) # Base de calculo FCP - etree.SubElement(icms_item, 'pFCP').text = '{:.2f}'.format(produto_servico.fcp_percentual or 0) # Percentual FCP - etree.SubElement(icms_item, 'vFCP').text = '{:.2f}'.format(produto_servico.fcp_valor or 0) # Valor Fundo Combate a Pobreza + etree.SubElement(icms_item, 'pFCP').text = '{:.2f}'.format(produto_servico.fcp_percentual or 0) # Percentual FCP + etree.SubElement(icms_item, 'vFCP').text = '{:.2f}'.format(produto_servico.fcp_valor or 0) # Valor Fundo Combate a Pobreza # Impostos não implementados else: raise NotImplementedError @@ -604,14 +605,14 @@ class SerializacaoXML(Serializacao): etree.SubElement(lacres, 'nLacre').text = lacre.numero_lacre # Pagamento - """ Obrigatório o preenchimento do Grupo Informações de Pagamento para NF-e e NFC-e. + """ Obrigatório o preenchimento do Grupo Informações de Pagamento para NF-e e NFC-e. Para as notas com finalidade de Ajuste ou Devolução o campo Forma de Pagamento deve ser preenchido com 90=Sem Pagamento. """ pag = etree.SubElement(raiz, 'pag') detpag = etree.SubElement(pag, 'detPag') if nota_fiscal.finalidade_emissao == '3' or nota_fiscal.finalidade_emissao == '4': etree.SubElement(detpag, 'tPag').text = '90' etree.SubElement(detpag, 'vPag').text = '{:.2f}'.format(0) - else: + else: etree.SubElement(detpag, 'tPag').text = str(nota_fiscal.tipo_pagamento).zfill(2) etree.SubElement(detpag, 'vPag').text = '{:.2f}'.format(nota_fiscal.totais_icms_total_nota) if nota_fiscal.tipo_pagamento == 3 or nota_fiscal.tipo_pagamento == 4: @@ -673,7 +674,7 @@ class SerializacaoXML(Serializacao): class SerializacaoQrcode(object): """ 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,qrcode_emissao="1"): """ Classe para gerar url do qrcode da NFC-e """ # Procura atributos no xml ns = {'ns':NAMESPACE_NFE} @@ -699,22 +700,60 @@ class SerializacaoQrcode(object): 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() - data = base64.b16encode(data).decode() - digest = base64.b16encode(digest).decode() - 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) + 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) + + + + #VERSAO_QRCODE =2 + + if qrcode_emissao == "1": + #versão online + + url = '{}|{}|{}|{}'.format( + chave,VERSAO_QRCODE,tpamb,token + ) + 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 = url + '&cHashQRCode=' + url_hash.upper() + url_formatacao = "p=" + url = url_formatacao + url + "|" + url_hash + + + + + #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) + #else: + # url = 'chNFe={}&nVersao={}&tpAmb={}&cDest={}&dhEmi={}&vNF={}&vICMS={}&digVal={}&cIdToken={}'.format( + # chave, VERSAO_QRCODE, tpamb, cpf, data.lower(), total, icms, digest.lower(), token) + + #url_hash = hashlib.sha1(url.encode()+csc.encode()).digest() + #url_hash = base64.b16encode(url_hash).decode() + + #url = url + '&cHashQRCode=' + url_hash.upper() + # 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 lista_uf_padrao = ['PR', 'CE', 'RS', 'RJ', 'RO'] if uf.upper() in lista_uf_padrao: @@ -734,7 +773,7 @@ class SerializacaoQrcode(object): 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: if tpamb == '1': qrcode = NFCE[uf.upper()]['HTTPS'] + NFCE[uf.upper()]['QR'] + url @@ -753,6 +792,9 @@ class SerializacaoQrcode(object): .replace('\n','').replace('<','<').replace('>','>').replace('amp;','') nfe = etree.fromstring(tnfe) # retorna nfe com o qrcode incluido NT2015/002 e qrcode + + + if return_qr: return nfe, qrcode.strip() # retorna apenas nfe com o qrcode incluido NT2015/002 diff --git a/pynfe/utils/flags.py b/pynfe/utils/flags.py index 7c1db9e..084389d 100644 --- a/pynfe/utils/flags.py +++ b/pynfe/utils/flags.py @@ -12,7 +12,7 @@ NAMESPACE_BETHA = 'http://www.betha.com.br/e-nota-contribuinte-ws' VERSAO_PADRAO = '4.00' -VERSAO_QRCODE = '100' +VERSAO_QRCODE = '2' TIPOS_DOCUMENTO = ( 'CNPJ', @@ -40,7 +40,7 @@ ICMS_TIPOS_TRIBUTACAO = ( ('ST', 'ICMS ST - Grupo de informação do ICMS ST devido para a UF de destino, nas operações interestaduais de produtos que tiveram retenção antecipada de ICMS por ST na UF do remetente. Repasse via Substituto Tributário.') ) -ICMS_ORIGENS = ( +ICMS_ORIGENS = ( (0, 'Nacional, exceto as indicadas nos códigos 3, 4, 5 e 8. '), (1, 'Estrangeira - Importação direta, exceto a indicada no código 6.'), (2, 'Estrangeira - Adquirida no mercado interno, exceto a indicada no código 7.'), @@ -49,7 +49,7 @@ ICMS_ORIGENS = ( (5, 'Nacional, mercadoria ou bem com Conteúdo de Importação inferior ou igual a 40%. '), (6, 'Estrangeira - Importação direta, sem similar nacional, constante em lista da CAMEX e gás natural. '), (7, 'Estrangeira - Adquirida no mercado interno, sem similar nacional, constante em lista da CAMEX e gás natural.'), - (8, 'Nacional, mercadoria ou bem com Conteúdo de Importação superior a 70%.') + (8, 'Nacional, mercadoria ou bem com Conteúdo de Importação superior a 70%.') ) ICMS_MODALIDADES = ( @@ -147,7 +147,7 @@ IPI_TIPOS_CALCULO = ( PIS_TIPOS_TRIBUTACAO = ( ('01', 'PIS 01 - Operação Tributável - Base de cálculo = valor da operação alíquota normal (cumulativo/não cumulativo)'), - ('02', 'PIS 02 - Operação Tributável - Base de cálculo = valor da operação (alíquota diferenciada)'), + ('02', 'PIS 02 - Operação Tributável - Base de cálculo = valor da operação (alíquota diferenciada)'), ('03', 'PIS 03 - Operacao Tributavel - Base de cálculo = quantidade vendida x alíquota por unidade de produto)'), ('04', 'PIS 04 - Operacao Tributavel - Tributacao Monofasica - (Aliquota Zero)'), ('06', 'PIS 06 - Operacao Tributavel - Aliquota Zero'), @@ -184,7 +184,7 @@ PIS_TIPOS_CALCULO = IPI_TIPOS_CALCULO COFINS_TIPOS_TRIBUTACAO = ( ('01', 'COFINS 01 - Operação Tributável - Base de cálculo = valor da operação alíquota normal (cumulativo/não cumulativo)'), - ('02', 'COFINS 02 - Operação Tributável - Base de cálculo = valor da operação (alíquota diferenciada)'), + ('02', 'COFINS 02 - Operação Tributável - Base de cálculo = valor da operação (alíquota diferenciada)'), ('03', 'COFINS 03 - Operacao Tributavel - Base de cálculo = quantidade vendida x alíquota por unidade de produto)'), ('04', 'COFINS 04 - Operacao Tributavel - Tributacao Monofasica - (Aliquota Zero)'), ('06', 'COFINS 06 - Operacao Tributavel - Aliquota Zero'), diff --git a/qrCode2Teste.py b/qrCode2Teste.py new file mode 100644 index 0000000..b69597b --- /dev/null +++ b/qrCode2Teste.py @@ -0,0 +1,33 @@ +from pynfe.processamento.serializacao import SerializacaoQrcode +from pynfe.processamento.assinatura import AssinaturaA1 +uf = 'pr' +homologacao = 'True' +certificado = "certificado/lam.pfx" +senha = '1234' + + +from lxml import etree +nfe = '2900000151VENDA652532018-09-03T14:06:20-03:0011291840741321110KYAN VERSAO 3.021011279000260DONDON COM. VAREJISTA DE CALC. LTDA MEMUNDI SHOES SHOPPINGRODOVIA LOMANTO JUNIORS NSHOPP.JUA GARDEN 1-BJOAO XXIII2918407JUAZEIROBA489003651058BRASIL74361485671469617421001 0205 622-23SEM GTINNOTA FISCAL EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL6404190028038005102PAR1.000078.9078.90SEM GTINPAR1.000078.9010102990.00000.00000.00990.00000.00000.000.000.000.000.000.000.000.000.000.000.000.0078.900.000.000.000.000.000.000.000.000.0078.900.0090178.90' + + +nfe = etree.fromstring(nfe) + +# # assinatura +a1 = AssinaturaA1(certificado, senha) +xml = a1.assinar(nfe) + + + +# # token de homologacao +token = '000001' + +# # # csc de homologação +csc = '5AB5F679-EA09-42CA-803B-6625B6107E2E' + + + + +# # # gera e adiciona o qrcode no xml NT2015/003 +xml_com_qrcode = SerializacaoQrcode().gerar_qrcode(token, csc, xml,qrcode_emissao="1") + +print(etree.tostring(xml_com_qrcode, encoding='unicode').replace('\n','').replace('<','<').replace('>','>').replace('amp;','')) From 16f73b8255e4ecc9cc082f09ad329f9283c911c4 Mon Sep 17 00:00:00 2001 From: erikseyti <31254342+erikseyti@users.noreply.github.com> Date: Mon, 24 Sep 2018 14:10:54 -0300 Subject: [PATCH 04/33] Arquivo de Teste do QrCode 2 Removido --- qrCode2Teste.py | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 qrCode2Teste.py diff --git a/qrCode2Teste.py b/qrCode2Teste.py deleted file mode 100644 index b69597b..0000000 --- a/qrCode2Teste.py +++ /dev/null @@ -1,33 +0,0 @@ -from pynfe.processamento.serializacao import SerializacaoQrcode -from pynfe.processamento.assinatura import AssinaturaA1 -uf = 'pr' -homologacao = 'True' -certificado = "certificado/lam.pfx" -senha = '1234' - - -from lxml import etree -nfe = '2900000151VENDA652532018-09-03T14:06:20-03:0011291840741321110KYAN VERSAO 3.021011279000260DONDON COM. VAREJISTA DE CALC. LTDA MEMUNDI SHOES SHOPPINGRODOVIA LOMANTO JUNIORS NSHOPP.JUA GARDEN 1-BJOAO XXIII2918407JUAZEIROBA489003651058BRASIL74361485671469617421001 0205 622-23SEM GTINNOTA FISCAL EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL6404190028038005102PAR1.000078.9078.90SEM GTINPAR1.000078.9010102990.00000.00000.00990.00000.00000.000.000.000.000.000.000.000.000.000.000.000.0078.900.000.000.000.000.000.000.000.000.0078.900.0090178.90' - - -nfe = etree.fromstring(nfe) - -# # assinatura -a1 = AssinaturaA1(certificado, senha) -xml = a1.assinar(nfe) - - - -# # token de homologacao -token = '000001' - -# # # csc de homologação -csc = '5AB5F679-EA09-42CA-803B-6625B6107E2E' - - - - -# # # gera e adiciona o qrcode no xml NT2015/003 -xml_com_qrcode = SerializacaoQrcode().gerar_qrcode(token, csc, xml,qrcode_emissao="1") - -print(etree.tostring(xml_com_qrcode, encoding='unicode').replace('\n','').replace('<','<').replace('>','>').replace('amp;','')) From c6e620104d2ff42481f4c42f054c10f6e3e8a939 Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 24 Sep 2018 14:51:41 -0300 Subject: [PATCH 05/33] =?UTF-8?q?[fix]=20corre=C3=A7=C3=B5es=20e=20ajustes?= =?UTF-8?q?=20no=20merge=20qrcode=202.00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/processamento/serializacao.py | 42 ++++++------------------------------- pynfe/utils/webservices.py | 4 ++-- 2 files changed, 8 insertions(+), 38 deletions(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 0e520bf..19d9570 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -256,7 +256,7 @@ class SerializacaoXML(Serializacao): # Lei da transparencia # Tributos aprox por item 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 = etree.SubElement(imposto, 'ICMS') @@ -674,7 +674,7 @@ class SerializacaoXML(Serializacao): class SerializacaoQrcode(object): """ Classe que gera e serializa o qrcode de NFC-e no xml """ - def gerar_qrcode(self, token, csc, xml, return_qr=False,qrcode_emissao="1"): + def gerar_qrcode(self, token, csc, xml, return_qr=False, online=True): """ Classe para gerar url do qrcode da NFC-e """ # Procura atributos no xml ns = {'ns':NAMESPACE_NFE} @@ -697,30 +697,19 @@ class SerializacaoQrcode(object): except IndexError: cpf = None 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() - 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) - - #VERSAO_QRCODE =2 - - if qrcode_emissao == "1": + if online: #versão online - - url = '{}|{}|{}|{}'.format( - chave,VERSAO_QRCODE,tpamb,token - ) - + url = '{}|{}|{}|{}'.format(chave,VERSAO_QRCODE, tpamb, token) else: #versão offline digest = digest.lower() @@ -734,23 +723,7 @@ class SerializacaoQrcode(object): url_hash = hashlib.sha1(url_complementar.encode()).digest() url_hash = base64.b16encode(url_hash).decode() - url_formatacao = "p=" - url = url_formatacao + url + "|" + url_hash - - - - - #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) - #else: - # url = 'chNFe={}&nVersao={}&tpAmb={}&cDest={}&dhEmi={}&vNF={}&vICMS={}&digVal={}&cIdToken={}'.format( - # chave, VERSAO_QRCODE, tpamb, cpf, data.lower(), total, icms, digest.lower(), token) - - #url_hash = hashlib.sha1(url.encode()+csc.encode()).digest() - #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. # Informar a URL da “Consulta por chave de acesso da NFC-e”. @@ -792,9 +765,6 @@ class SerializacaoQrcode(object): .replace('\n','').replace('<','<').replace('>','>').replace('amp;','') nfe = etree.fromstring(tnfe) # retorna nfe com o qrcode incluido NT2015/002 e qrcode - - - if return_qr: return nfe, qrcode.strip() # retorna apenas nfe com o qrcode incluido NT2015/002 diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 270d40c..fd026bf 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -199,7 +199,7 @@ NFCE = { 'INUTILIZACAO': 'nfce.fazenda.sp.gov.br/ws/NFeInutilizacao4.asmx', 'EVENTOS': 'nfce.fazenda.sp.gov.br/ws/NFeRecepcaoEvento4.asmx', '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://', 'HOMOLOGACAO': 'https://homologacao.' }, @@ -212,7 +212,7 @@ NFCE = { 'EVENTOS': 'nfce.sefa.pr.gov.br/nfce/NFeRecepcaoEvento4?wsdl', 'CADASTRO': 'nfce.sefa.pr.gov.br/nfce/CadConsultaCadastro4?wsdl', 'QR': 'http://www.fazenda.pr.gov.br/nfce/qrcode?', - 'URL': 'http://www.fazenda.pr.gov.br', + 'URL': 'www.fazenda.pr.gov.br/nfce/consulta', 'HTTPS': 'https://', 'HOMOLOGACAO': 'https://homologacao.' }, From 52dccdbae140b6851c7343971fb733a0771241d1 Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 24 Sep 2018 15:45:32 -0300 Subject: [PATCH 06/33] [fix] url consulta qrcode PR --- pynfe/utils/webservices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index fd026bf..0be010f 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -212,7 +212,7 @@ NFCE = { 'EVENTOS': 'nfce.sefa.pr.gov.br/nfce/NFeRecepcaoEvento4?wsdl', 'CADASTRO': 'nfce.sefa.pr.gov.br/nfce/CadConsultaCadastro4?wsdl', 'QR': 'http://www.fazenda.pr.gov.br/nfce/qrcode?', - 'URL': 'www.fazenda.pr.gov.br/nfce/consulta', + 'URL': 'http://www.fazenda.pr.gov.br/nfce/consulta', 'HTTPS': 'https://', 'HOMOLOGACAO': 'https://homologacao.' }, From d3eca6b0103d584d0718dd86037e625c05261772 Mon Sep 17 00:00:00 2001 From: juniortada Date: Thu, 1 Nov 2018 11:20:54 -0200 Subject: [PATCH 07/33] [fix] atualizado url NFCE PE --- pynfe/processamento/comunicacao.py | 2 +- pynfe/utils/webservices.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index 7674511..960a545 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -418,7 +418,7 @@ class ComunicacaoSefaz(Comunicacao): # limpa xml com caracteres bugados para infNFeSupl em NFC-e xml = re.sub( '(.*?)', - lambda x: x.group(0).replace('<', '<').replace('>', '>').replace('amp;', ''), + lambda x: x.group(0).replace('<', '<').replace('>', '>').replace('&', ''), etree.tostring(xml, encoding='unicode').replace('\n', '') ) xml = xml_declaration + xml diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 270d40c..0443aa5 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -125,10 +125,10 @@ NFCE = { 'CHAVE': '', 'INUTILIZACAO': '', 'EVENTOS': '', - 'QR': 'sefaz.pe.gov.br/nfce-web/consultarNFCe?', + 'QR': 'sefaz.pe.gov.br/nfce/consulta', 'HTTPS': 'http://nfce.', - 'HOMOLOGACAO': 'http://nfcehomolog.', - 'URL': 'sefaz.pe.gov.br/nfce-web/consultarNFCe' + 'HOMOLOGACAO': 'http://nfce.', + 'URL': 'sefaz.pe.gov.br/nfce/consulta' }, 'AL': { 'STATUS': '', From 549b484135fbec5772e0649b0e43d9b620630b92 Mon Sep 17 00:00:00 2001 From: juniortada Date: Thu, 1 Nov 2018 11:23:02 -0200 Subject: [PATCH 08/33] =?UTF-8?q?[fix]=20corre=C3=A7=C3=A3o=20na=20nova=20?= =?UTF-8?q?url=20NFCE=20PE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/utils/webservices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 2c29b95..433a582 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -125,7 +125,7 @@ NFCE = { 'CHAVE': '', 'INUTILIZACAO': '', 'EVENTOS': '', - 'QR': 'sefaz.pe.gov.br/nfce/consulta', + 'QR': 'sefaz.pe.gov.br/nfce/consulta?', 'HTTPS': 'http://nfce.', 'HOMOLOGACAO': 'http://nfce.', 'URL': 'sefaz.pe.gov.br/nfce/consulta' From 59b6cdae02dfa170f5f3e74de782e8b3e699dfca Mon Sep 17 00:00:00 2001 From: lmandala Date: Tue, 6 Nov 2018 11:16:48 -0300 Subject: [PATCH 09/33] consulta distribuicao por chave e metodo de descompactar gzip --- pynfe/processamento/comunicacao.py | 23 ++++++++++++++--------- pynfe/utils/descompactar.py | 30 ++++++++++++++++++++++++++++++ tests/consulta_distribuicao.txt | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 pynfe/utils/descompactar.py create mode 100644 tests/consulta_distribuicao.txt diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index 960a545..fa975ff 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -17,6 +17,7 @@ from pynfe.utils.flags import ( from pynfe.utils.webservices import NFE, NFCE, NFSE from pynfe.entidades.certificado import CertificadoA1 from .assinatura import AssinaturaA1 +from pynfe.utils.descompactar import DescompactaGzip class Comunicacao(object): @@ -167,7 +168,7 @@ class ComunicacaoSefaz(Comunicacao): # url url = self._get_url_an(consulta='DISTRIBUICAO') # 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) if self.uf: etree.SubElement(raiz, 'cUFAutor').text = CODIGOS_ESTADOS[self.uf.upper()] @@ -175,15 +176,19 @@ class ComunicacaoSefaz(Comunicacao): etree.SubElement(raiz, 'CNPJ').text = cnpj else: etree.SubElement(raiz, 'CPF').text = cpf - distNSU = etree.SubElement(raiz, 'distNSU') - etree.SubElement(distNSU, 'ultNSU').text = str(nsu).zfill(15) - # if chave: - # consChNFe = etree.SubElement(raiz, 'consChNFe') - # etree.SubElement(consChNFe, 'chNFe').text = chave - # Monta XML para envio da requisição + if not chave: + distNSU = etree.SubElement(raiz, 'distNSU') + etree.SubElement(distNSU, 'ultNSU').text = str(nsu).zfill(15) + if chave: + consChNFe = etree.SubElement(raiz, 'consChNFe') + etree.SubElement(consChNFe, 'chNFe').text = chave + #Monta XML para envio da requisição xml = self._construir_xml_soap('NFeDistribuicaoDFe', raiz) - # print(url) - # print(etree.tostring(xml)) + #print(url) + #print(etree.tostring(xml)) + #print('\n\n') + + return self._post(url, xml) def consulta_cadastro(self, modelo, cnpj): diff --git a/pynfe/utils/descompactar.py b/pynfe/utils/descompactar.py new file mode 100644 index 0000000..ab4e1ea --- /dev/null +++ b/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) diff --git a/tests/consulta_distribuicao.txt b/tests/consulta_distribuicao.txt new file mode 100644 index 0000000..8016f73 --- /dev/null +++ b/tests/consulta_distribuicao.txt @@ -0,0 +1,38 @@ +from pynfe.processamento.comunicacao import ComunicacaoSefaz +from pynfe.utils.descompactar import DescompactaGzip +from pynfe.utils.flags import NAMESPACE_NFE +from lxml import etree + +CNPJ = 'CPNJ_DA_EMPRESA' +CHAVE = 'CHAVE_DA_NOTA_DA_CONSULTA' +certificado = "/certs/cert.pfx" +senha = '1234' +uf = 'pi' +homologacao = False +con = ComunicacaoSefaz(uf, certificado, senha, homologacao) +xml = con.consulta_distribuicao(cnpj=CNPJ,chave=CHAVE) +#print('\n\n Retorno:') +#print(xml.text) + +print('Descompactado \n\n') + +# exemplo de leitura da resposta +ns = {'ns': NAMESPACE_NFE} +#esse retorno precisa ser melhorado + +resposta = etree.fromstring(xml.content) + +#desconpactando a mensagem + +zip_resposta = resposta.xpath('//ns:retDistDFeInt/ns:loteDistDFeInt/ns:docZip', namespaces=ns)[0].text + +des_resposta = DescompactaGzip.descompacta(zip_resposta) + +#recuperando valores do resultado da descompactacao + +chave = des_resposta.xpath('//ns:resNFe/ns:chNFe',namespaces=ns)[0].text + +valor = des_resposta.xpath('//ns:resNFe/ns:vNF',namespaces=ns)[0].text + + +print('chave:{}\nvalor:{}'.format(chave,valor)) \ No newline at end of file From b0b0af3af01e0159e78277036eaeb6d0b31aa9a1 Mon Sep 17 00:00:00 2001 From: juniortada Date: Fri, 7 Dec 2018 00:36:33 -0200 Subject: [PATCH 10/33] [fix] corrigido url webservice nfe sp e nfce pe --- pynfe/processamento/comunicacao.py | 2 +- pynfe/utils/webservices.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index 960a545..43a5e70 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -286,7 +286,7 @@ class ComunicacaoSefaz(Comunicacao): 'uf': uf, 'ano': ano, 'cnpj': cnpj, - 'modelo': '55', + 'modelo': '55' if modelo == 'nfe' else '65', # 55=NF-e; 65=NFC-e; 'serie': serie.zfill(3), 'num_ini': str(numero_inicial).zfill(9), 'num_fin': str(numero_final).zfill(9), diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 433a582..342aa0b 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -127,7 +127,7 @@ NFCE = { 'EVENTOS': '', 'QR': 'sefaz.pe.gov.br/nfce/consulta?', 'HTTPS': 'http://nfce.', - 'HOMOLOGACAO': 'http://nfce.', + 'HOMOLOGACAO': 'http://nfcehomolog.', 'URL': 'sefaz.pe.gov.br/nfce/consulta' }, 'AL': { @@ -351,7 +351,7 @@ NFE = { 'STATUS': 'nfe.fazenda.sp.gov.br/ws/NFeStatusServico4.asmx', 'AUTORIZACAO': 'nfe.fazenda.sp.gov.br/ws/nfeautorizacao4.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', 'EVENTOS': 'nfe.fazenda.sp.gov.br/ws/nferecepcaoevento4.asmx', 'CADASTRO': 'nfe.fazenda.sp.gov.br/ws/cadconsultacadastro4.asmx', From 958a51b1928de2aacca1755c6704bc87090f03f8 Mon Sep 17 00:00:00 2001 From: erikseyti Date: Fri, 7 Dec 2018 16:20:04 -0200 Subject: [PATCH 11/33] [fix] corrigido url do webservice de status em nfe sp --- pynfe/utils/webservices.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 342aa0b..420b480 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -107,7 +107,7 @@ NFCE = { 'QR': 'http://nfce.set.rn.gov.br/consultarNFCe.aspx?', 'HTTPS': '', 'HOMOLOGACAO': '' - + }, 'PB': { 'STATUS': '', @@ -155,7 +155,7 @@ NFCE = { 'HTTPS': 'http://nfe.', 'HOMOLOGACAO': 'http://hnfe.', 'URL': 'http://hinternet.sefaz.ba.gov.br/nfce/consulta' - }, + }, 'MG': { 'STATUS': '', 'AUTORIZACAO': '', @@ -181,16 +181,16 @@ NFCE = { 'CHAVE': '', 'INUTILIZACAO': '', 'EVENTOS': '', - 'QR': 'http://www4.fazenda.rj.gov.br/consultaNFCe/QRCode?', + 'QR': 'http://www4.fazenda.rj.gov.br/consultaNFCe/QRCode?', 'URL': 'www.nfce.fazenda.rj.gov.br/consulta' }, - # Os Web Services de homologação da NFC-e 4.00 são: - # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeAutorizacao4.asmx - # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeStatusServico4.asmx - # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeConsultaProtocolo4.asmx - # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeRetAutorizacao4.asmx - # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeRecepcaoEvento4.asmx - # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeInutilizacao4.asmx + # Os Web Services de homologação da NFC-e 4.00 são: + # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeAutorizacao4.asmx + # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeStatusServico4.asmx + # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeConsultaProtocolo4.asmx + # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeRetAutorizacao4.asmx + # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeRecepcaoEvento4.asmx + # https://homologacao.nfce.fazenda.sp.gov.br/ws/NFeInutilizacao4.asmx 'SP': { 'STATUS': 'nfce.fazenda.sp.gov.br/ws/NFeStatusServico4.asmx', 'AUTORIZACAO': 'nfce.fazenda.sp.gov.br/ws/NFeAutorizacao4.asmx', @@ -335,7 +335,7 @@ NFE = { 'CADASTRO': 'nfe.sefaz.ba.gov.br/webservices/CadConsultaCadastro4/CadConsultaCadastro4.asmx', 'HTTPS': 'https://', 'HOMOLOGACAO': 'https://h' - }, + }, 'MG': { 'STATUS': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeStatusServico4', 'AUTORIZACAO': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeAutorizacao4', @@ -348,7 +348,7 @@ NFE = { 'HOMOLOGACAO': 'https://h' }, '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', 'RECIBO': 'nfe.fazenda.sp.gov.br/ws/nferetautorizacao4.asmx', 'CHAVE': 'nfe.fazenda.sp.gov.br/ws/nfeconsultaprotocolo4.asmx', @@ -461,7 +461,7 @@ NFE = { # Nfs-e NFSE = { - # + # 'BETHA': { 'AUTORIZACAO':'GerarNfse', 'CANCELAR':'CancelarNfse', @@ -485,4 +485,4 @@ NFSE = { 'HTTPS':'https://producao.ginfes.com.br/ServiceGinfesImpl?wsdl', 'HOMOLOGACAO':'https://homologacao.ginfes.com.br/ServiceGinfesImpl?wsdl' } -} \ No newline at end of file +} From e62e9e3ecfb2346d759eefbac06cfdea13c153b9 Mon Sep 17 00:00:00 2001 From: erikseyti Date: Fri, 7 Dec 2018 16:27:14 -0200 Subject: [PATCH 12/33] [fix] corrigido url webservice nfe mt --- pynfe/utils/webservices.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 420b480..d5e62fd 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -395,13 +395,13 @@ NFE = { 'HOMOLOGACAO': 'https://homologacao.' }, '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': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeStatusServico4?wsdl', + 'AUTORIZACAO': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeAutorizacao4?wsdl', + 'RECIBO': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeRetAutorizacao4?wsdl', + 'CHAVE': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeConsulta4?wsdl', + 'INUTILIZACAO': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeInutilizacao4?wsdl', + 'EVENTOS': 'nfe.sefaz.mt.gov.br/nfews/v2/services/RecepcaoEvento4?wsdl', + 'CADASTRO': 'nfe.sefaz.mt.gov.br/nfews/v2/services/CadConsultaCadastro4?wsdl', 'HTTPS': 'https://nfe.', 'HOMOLOGACAO': 'https://homologacao.' }, From 4c521b00cea20fba3e98b988d4723643006860d5 Mon Sep 17 00:00:00 2001 From: erikseyti Date: Mon, 10 Dec 2018 16:40:42 -0200 Subject: [PATCH 13/33] [fix] corrigido url webservice nfe --- pynfe/utils/webservices.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index d5e62fd..4e7713c 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -26,12 +26,12 @@ NFCE = { 'AM': { # csc_homologacao = '0123456789' # 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?', 'URL': 'sefaz.am.gov.br/nfceweb/formConsulta.do', 'HTTPS': 'http://sistemas.', @@ -289,12 +289,12 @@ NFE = { 'HOMOLOGACAO': 'https://hom' }, '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', 'HTTPS': 'https://', 'HOMOLOGACAO': 'https://hom' @@ -309,7 +309,7 @@ NFE = { 'CHAVE': 'sefaz.ce.gov.br/nfe4/services/NFeConsultaProtocolo4?WSDL', 'INUTILIZACAO': 'sefaz.ce.gov.br/nfe4/services/NFeInutilizacao4?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', 'HTTPS': 'https://nfe.', 'HOMOLOGACAO': 'https://nfeh.' @@ -342,7 +342,7 @@ NFE = { 'RECIBO': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeRetAutorizacao4', 'CHAVE': 'nfe.fazenda.mg.gov.br/nfe2/services/NFeConsulta4', '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', 'HTTPS': 'https://', 'HOMOLOGACAO': 'https://h' @@ -377,7 +377,7 @@ NFE = { 'CHAVE': 'sefazrs.rs.gov.br/ws/NfeConsulta/NfeConsulta4.asmx', 'INUTILIZACAO': 'sefazrs.rs.gov.br/ws/nfeinutilizacao/nfeinutilizacao4.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', 'DESTINADAS': 'sefazrs.rs.gov.br/ws/nfeConsultaDest/nfeConsultaDest.asmx', 'HTTPS': 'https://nfe.', @@ -390,7 +390,7 @@ NFE = { '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', + 'CADASTRO': 'nfe.sefaz.ms.gov.br/ws/CadConsultaCadastro4', 'HTTPS': 'https://', 'HOMOLOGACAO': 'https://homologacao.' }, From 549f0ae33f93b5284de95edd41f190c7a0dc7511 Mon Sep 17 00:00:00 2001 From: lmandala Date: Fri, 14 Dec 2018 08:19:30 -0300 Subject: [PATCH 14/33] removendo prints de logs e arqui de teste pessoal --- pynfe/processamento/comunicacao.py | 3 --- tests/consulta_distribuicao.txt | 38 -------------------------------------- 2 files changed, 41 deletions(-) delete mode 100644 tests/consulta_distribuicao.txt diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index fa975ff..ee88f54 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -184,9 +184,6 @@ class ComunicacaoSefaz(Comunicacao): etree.SubElement(consChNFe, 'chNFe').text = chave #Monta XML para envio da requisição xml = self._construir_xml_soap('NFeDistribuicaoDFe', raiz) - #print(url) - #print(etree.tostring(xml)) - #print('\n\n') return self._post(url, xml) diff --git a/tests/consulta_distribuicao.txt b/tests/consulta_distribuicao.txt deleted file mode 100644 index 8016f73..0000000 --- a/tests/consulta_distribuicao.txt +++ /dev/null @@ -1,38 +0,0 @@ -from pynfe.processamento.comunicacao import ComunicacaoSefaz -from pynfe.utils.descompactar import DescompactaGzip -from pynfe.utils.flags import NAMESPACE_NFE -from lxml import etree - -CNPJ = 'CPNJ_DA_EMPRESA' -CHAVE = 'CHAVE_DA_NOTA_DA_CONSULTA' -certificado = "/certs/cert.pfx" -senha = '1234' -uf = 'pi' -homologacao = False -con = ComunicacaoSefaz(uf, certificado, senha, homologacao) -xml = con.consulta_distribuicao(cnpj=CNPJ,chave=CHAVE) -#print('\n\n Retorno:') -#print(xml.text) - -print('Descompactado \n\n') - -# exemplo de leitura da resposta -ns = {'ns': NAMESPACE_NFE} -#esse retorno precisa ser melhorado - -resposta = etree.fromstring(xml.content) - -#desconpactando a mensagem - -zip_resposta = resposta.xpath('//ns:retDistDFeInt/ns:loteDistDFeInt/ns:docZip', namespaces=ns)[0].text - -des_resposta = DescompactaGzip.descompacta(zip_resposta) - -#recuperando valores do resultado da descompactacao - -chave = des_resposta.xpath('//ns:resNFe/ns:chNFe',namespaces=ns)[0].text - -valor = des_resposta.xpath('//ns:resNFe/ns:vNF',namespaces=ns)[0].text - - -print('chave:{}\nvalor:{}'.format(chave,valor)) \ No newline at end of file From 94d989ac6c615b572b10100e9173406c78b2f5c7 Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 17 Dec 2018 11:41:57 -0200 Subject: [PATCH 15/33] =?UTF-8?q?[new]=20add=20DF=20SVRS,=20removido=20imp?= =?UTF-8?q?ort=20desnecess=C3=A1rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/processamento/comunicacao.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index cb40536..fb52751 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -17,7 +17,6 @@ from pynfe.utils.flags import ( from pynfe.utils.webservices import NFE, NFCE, NFSE from pynfe.entidades.certificado import CertificadoA1 from .assinatura import AssinaturaA1 -from pynfe.utils.descompactar import DescompactaGzip class Comunicacao(object): @@ -354,7 +353,7 @@ class ComunicacaoSefaz(Comunicacao): raise Exception('Modelo não encontrado! Defina modelo="nfe" ou "nfce"') # Estados que utilizam outros ambientes else: - lista_svrs = ['AC', 'RJ', 'RN', 'PB', 'SC', 'SE', 'PI'] + lista_svrs = ['AC', 'RJ', 'RN', 'PB', 'SC', 'SE', 'PI', 'DF'] lista_svan = ['MA','PA'] if self.uf.upper() in lista_svrs: if self._ambiente == 1: From aad0dcd9b8692ddee3731b09a8b2eedfb8f1a9fe Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 17 Dec 2018 11:53:39 -0200 Subject: [PATCH 16/33] [fix] add url para qrcode nfce DF --- pynfe/processamento/serializacao.py | 2 +- pynfe/utils/webservices.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 19d9570..96f4579 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -728,7 +728,7 @@ class SerializacaoQrcode(object): # 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”. # 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: qrcode = NFCE[uf.upper()]['QR'] + url url_chave = NFCE[uf.upper()]['URL'] diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 342aa0b..25b02d7 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -263,6 +263,10 @@ NFCE = { 'HTTPS': 'http://nfe.', 'HOMOLOGACAO': 'http://homolog.' }, + '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 'SVRS': { 'STATUS': 'svrs.rs.gov.br/ws/NfeStatusServico/NfeStatusServico4.asmx', From 26a5f4433a73e4039e82cbe4ea5012a124ab5472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20de=20=C3=81vila=20Rodrigues?= Date: Wed, 19 Dec 2018 10:03:21 -0200 Subject: [PATCH 17/33] =?UTF-8?q?Corrige=20espa=C3=A7o=20adicional=20nas?= =?UTF-8?q?=20tags=20vBCST,=20pICMSST,=20vICMSST=20na=20modalidade=2010=20?= =?UTF-8?q?do=20BC=20ICMS=20ST?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/processamento/serializacao.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 96f4579..077bbb2 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -305,9 +305,9 @@ class SerializacaoXML(Serializacao): etree.SubElement(icms_item, 'modBCST').text = str(produto_servico.icms_st_modalidade_determinacao_bc) etree.SubElement(icms_item, 'pMVAST').text = str(produto_servico.icms_st_percentual_adicional) # Percentual da margem de valor Adicionado do ICMS ST etree.SubElement(icms_item, 'pRedBCST').text = str(produto_servico.icms_st_percentual_reducao_bc) # APercentual da Redução de BC do ICMS ST - etree.SubElement(icms_item, 'vBCST ').text = str(produto_servico.icms_st_valor_base_calculo) - etree.SubElement(icms_item, 'pICMSST ').text = str(produto_servico.icms_st_aliquota) - etree.SubElement(icms_item, 'vICMSST ').text = str(produto_servico.icms_st_valor) + etree.SubElement(icms_item, 'vBCST').text = str(produto_servico.icms_st_valor_base_calculo) + etree.SubElement(icms_item, 'pICMSST').text = str(produto_servico.icms_st_aliquota) + etree.SubElement(icms_item, 'vICMSST').text = str(produto_servico.icms_st_valor) # 20=Com redução de base de cálculo elif produto_servico.icms_modalidade == '20': etree.SubElement(icms_item, 'pRedBC').text = '{:.2f}'.format(produto_servico.icms_percentual_reducao_bc or 0) # Percentual da Redução de BC From 205e825b6490cad13f64aed320f912e5b679e3eb Mon Sep 17 00:00:00 2001 From: juniortada Date: Wed, 9 Jan 2019 19:43:42 -0200 Subject: [PATCH 18/33] [fix] add ES SVRS, atualizado url NFC-e ES --- pynfe/processamento/comunicacao.py | 2 +- pynfe/utils/webservices.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index fb52751..0cfdeb2 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -353,7 +353,7 @@ class ComunicacaoSefaz(Comunicacao): raise Exception('Modelo não encontrado! Defina modelo="nfe" ou "nfce"') # Estados que utilizam outros ambientes else: - lista_svrs = ['AC', 'RJ', 'RN', 'PB', 'SC', 'SE', 'PI', 'DF'] + lista_svrs = ['AC', 'RJ', 'RN', 'PB', 'SC', 'SE', 'PI', 'DF', 'ES'] lista_svan = ['MA','PA'] if self.uf.upper() in lista_svrs: if self._ambiente == 1: diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index 25b02d7..abeb0e3 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -172,7 +172,10 @@ NFCE = { 'CHAVE': '', 'INUTILIZACAO': '', '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': { 'STATUS': '', From 90e98191da94ab38e96b94749e93e22af4db17b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vyo=20Henrique?= Date: Wed, 22 May 2019 13:53:18 -0300 Subject: [PATCH 19/33] =?UTF-8?q?Corre=C3=A7=C3=A3o=20URL=20estado=20de=20?= =?UTF-8?q?Goi=C3=A1s.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A Sefaz GO agora usa https e não http. Adicionado o parâmetro URL necessário para emissão da NFC-e --- pynfe/utils/webservices.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index bf08aeb..c120805 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -263,8 +263,9 @@ NFCE = { 'EVENTOS': 'sefaz.go.gov.br/nfe/services/NFeRecepcaoEvento4?wsdl', 'QR': 'sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe?', '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?', From 274235231e28c8c46c53692e6eb79fc652a75e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vyo=20Henrique?= Date: Wed, 22 May 2019 13:57:58 -0300 Subject: [PATCH 20/33] =?UTF-8?q?Corre=C3=A7=C3=A3o=20para=20emiss=C3=A3o?= =?UTF-8?q?=20estado=20de=20GO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O retorno do estado de GO vem com a tag header, com isso, ao tentar ler o status do lote não dava certo pois tentava realizar a leitura em um indice que não existe. --- pynfe/processamento/comunicacao.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pynfe/processamento/comunicacao.py b/pynfe/processamento/comunicacao.py index 0cfdeb2..5b915ea 100644 --- a/pynfe/processamento/comunicacao.py +++ b/pynfe/processamento/comunicacao.py @@ -82,7 +82,12 @@ class ComunicacaoSefaz(Comunicacao): if ind_sinc == 1: try: # Protocolo com envio OK - inf_prot = prot[0][0] # root protNFe + try: + 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 processado if lote_status == '104': From ce85d97e5d32bc3709588ea4dda85e8d4b1c6338 Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 3 Jun 2019 09:02:52 -0300 Subject: [PATCH 21/33] NT 2018/003 Responsavel tecnico --- pynfe/entidades/notafiscal.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pynfe/entidades/notafiscal.py b/pynfe/entidades/notafiscal.py index c2fc6ac..3c994c0 100644 --- a/pynfe/entidades/notafiscal.py +++ b/pynfe/entidades/notafiscal.py @@ -355,6 +355,7 @@ class NotaFiscal(Entidade): self.duplicatas = [] self.observacoes_contribuinte = [] self.processos_referenciados = [] + self.responsavel_tecnico = [] super(NotaFiscal, self).__init__(*args, **kwargs) @@ -417,11 +418,17 @@ class NotaFiscal(Entidade): return obj def adicionar_processo_referenciado(self, **kwargs): - u"""Adiciona uma instancia de Processo Referenciado""" + """Adiciona uma instancia de Processo Referenciado""" obj = NotaFiscalProcessoReferenciado(**kwargs) self.processos_referenciados.append(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): self.codigo_numerico_aleatorio = str(random.randint(0, 99999999)).zfill(8) return self.codigo_numerico_aleatorio @@ -1003,3 +1010,11 @@ class NotaFiscalServico(Entidade): def __str__(self): return ' '.join([str(self.identificador)]) + +class NotaFiscalResponsavelTecnico(Entidade): + # NT 2018/003 + cnpj = str() + contato = str() + email = str() + fone = str() + csrt = str() From e10381968f886ff029927f5f09c43316dddafe8f Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 3 Jun 2019 09:23:00 -0300 Subject: [PATCH 22/33] =?UTF-8?q?serializa=C3=A7=C3=A3o=20xml=20respons?= =?UTF-8?q?=C3=A1vel=20tecnico=20NT2018/003?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/processamento/serializacao.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 077bbb2..9f623ad 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -410,6 +410,18 @@ class SerializacaoXML(Serializacao): else: 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): raiz = etree.Element(tag_raiz, versao=self._versao) @@ -636,6 +648,13 @@ class SerializacaoXML(Serializacao): if 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: + for resp_tec in nota_fiscal.responsavel_tecnico: + raiz.append(self._serializar_responsavel_tecnico(resp_tec, returna_string=False)) + return + + if retorna_string: return etree.tostring(raiz, encoding="unicode", pretty_print=True) else: From 7411d225e0d3f05127efb64c0de4d21c834ddda2 Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 3 Jun 2019 09:25:38 -0300 Subject: [PATCH 23/33] [fix] erro retorna_string --- pynfe/processamento/serializacao.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 9f623ad..e43decc 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -651,7 +651,7 @@ class SerializacaoXML(Serializacao): # Responsavel Tecnico NT2018/003 if nota_fiscal.responsavel_tecnico: for resp_tec in nota_fiscal.responsavel_tecnico: - raiz.append(self._serializar_responsavel_tecnico(resp_tec, returna_string=False)) + raiz.append(self._serializar_responsavel_tecnico(resp_tec, retorna_string=False)) return From 5b42dea7b04df5b64b9f9c75fb0aa2eb52897ccc Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 3 Jun 2019 09:40:44 -0300 Subject: [PATCH 24/33] [fix] add um responsavel quando existir (uf am, ms, pe, pr, sc e to) --- pynfe/processamento/serializacao.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index e43decc..c6e56e9 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -650,9 +650,8 @@ class SerializacaoXML(Serializacao): # Responsavel Tecnico NT2018/003 if nota_fiscal.responsavel_tecnico: - for resp_tec in nota_fiscal.responsavel_tecnico: - raiz.append(self._serializar_responsavel_tecnico(resp_tec, retorna_string=False)) - return + raiz.append(self._serializar_responsavel_tecnico( + nota_fiscal.responsavel_tecnico[0], retorna_string=False)) if retorna_string: From 9bfc52c5cb4de3b6127b9ec031b5734c4b10bc24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vyo=20Henrique?= Date: Mon, 3 Jun 2019 16:07:40 -0300 Subject: [PATCH 25/33] =?UTF-8?q?Corre=C3=A7=C3=A3o=20no=20valor=20total?= =?UTF-8?q?=20da=20nota?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alterado o valor total da nota para considerar os outros itens que fazem parte da somatória do total seguindo o manual do contribuinte e utilizando apenas os campos que estão sendo utilizadas no projeto. --- pynfe/entidades/notafiscal.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pynfe/entidades/notafiscal.py b/pynfe/entidades/notafiscal.py index 3c994c0..92f555f 100644 --- a/pynfe/entidades/notafiscal.py +++ b/pynfe/entidades/notafiscal.py @@ -387,7 +387,6 @@ class NotaFiscal(Entidade): self.totais_icms_pis += obj.pis_valor self.totais_icms_cofins += obj.cofins_valor 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) self.totais_fcp += obj.fcp_valor self.totais_fcp_destino += obj.fcp_destino_valor @@ -397,6 +396,13 @@ class NotaFiscal(Entidade): self.totais_icms_inter_remetente += obj.icms_inter_remetente_valor ## TODO calcular impostos aproximados #self.totais_tributos_aproximado += obj.tributos + + # self.totais_icms_total_nota = total + 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 def adicionar_transporte_volume(self, **kwargs): From 4d54ea301cc4830fc484fc0ebfb3b66309e2269f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vyo=20Henrique?= Date: Mon, 3 Jun 2019 16:10:14 -0300 Subject: [PATCH 26/33] Adicionado desconto por item Adicionado tag de desconto no item --- pynfe/processamento/serializacao.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index c6e56e9..aa0d0f0 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -236,6 +236,10 @@ class SerializacaoXML(Serializacao): etree.SubElement(prod, 'uTrib').text = produto_servico.unidade_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) + + 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) 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) From 6736ff6a8b82ee5822fd4065b6cf43137536d1b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vyo=20Henrique?= Date: Mon, 3 Jun 2019 16:12:33 -0300 Subject: [PATCH 27/33] =?UTF-8?q?Retirado=20coment=C3=A1rio=20desnecess?= =?UTF-8?q?=C3=A1rio.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/entidades/notafiscal.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pynfe/entidades/notafiscal.py b/pynfe/entidades/notafiscal.py index 92f555f..ed001bf 100644 --- a/pynfe/entidades/notafiscal.py +++ b/pynfe/entidades/notafiscal.py @@ -397,7 +397,6 @@ class NotaFiscal(Entidade): ## TODO calcular impostos aproximados #self.totais_tributos_aproximado += obj.tributos - # self.totais_icms_total_nota = total self.totais_icms_total_nota += obj.valor_total_bruto - obj.desconto + \ obj.icms_desonerado + obj.icms_st_valor + \ obj.total_frete + obj.total_seguro + \ From 2fa301b6d5f56a614e285b8998f237025454e2dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vyo=20Henrique?= Date: Tue, 4 Jun 2019 18:00:01 -0300 Subject: [PATCH 28/33] =?UTF-8?q?Corre=C3=A7=C3=A3o=20na=20serializa=C3=A7?= =?UTF-8?q?=C3=A3o=20do=20pis=20e=20confins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alguns campos decimais do pis e confins não estavam sendo convertidos para string na hora da serialização. --- pynfe/processamento/serializacao.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index aa0d0f0..c87074a 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -353,7 +353,7 @@ class SerializacaoXML(Serializacao): elif produto_servico.pis_modalidade == '03': pis_item = etree.SubElement(pis, 'PISQtde') 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, 'vPIS').text = '{:.2f}'.format(produto_servico.pis_valor_base_calculo or 0) else: @@ -362,7 +362,7 @@ class SerializacaoXML(Serializacao): 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) 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, 'vPIS').text = '{:.2f}'.format(produto_servico.pis_valor_base_calculo or 0) @@ -389,9 +389,9 @@ class SerializacaoXML(Serializacao): elif produto_servico.cofins_modalidade == '03': cofins_item = etree.SubElement(cofins, 'COFINSQtde') 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: cofins_item = etree.SubElement(cofins, 'COFINSOutr') etree.SubElement(cofins_item, 'CST').text = produto_servico.cofins_modalidade From d47dac721ea38517ad1ee16ef1c6e09d33b74235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vyo=20Henrique?= Date: Thu, 6 Jun 2019 13:15:15 -0300 Subject: [PATCH 29/33] Corrigido problema de recursividade. Ao usar o debug estava gerando erro de recursividade por falta do metodo __str__ --- pynfe/entidades/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pynfe/entidades/base.py b/pynfe/entidades/base.py index 9f82806..1704944 100644 --- a/pynfe/entidades/base.py +++ b/pynfe/entidades/base.py @@ -16,6 +16,9 @@ class Entidade(object): self._fonte_dados.adicionar_objeto(self) + def __str__(self): + return self.__class__.__name__ + def __repr__(self): return '<%s %s>'%(self.__class__.__name__, str(self)) From f0955b8287d69bb0a59f9d48b893ac22c40438b4 Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 17 Jun 2019 18:04:08 -0300 Subject: [PATCH 30/33] [fix] Corrigido url nfe MT #66 --- pynfe/utils/webservices.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index c120805..f58e8d1 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -403,13 +403,13 @@ NFE = { 'HOMOLOGACAO': 'https://homologacao.' }, 'MT': { - 'STATUS': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeStatusServico4?wsdl', - 'AUTORIZACAO': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeAutorizacao4?wsdl', - 'RECIBO': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeRetAutorizacao4?wsdl', - 'CHAVE': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeConsulta4?wsdl', - 'INUTILIZACAO': 'nfe.sefaz.mt.gov.br/nfews/v2/services/NfeInutilizacao4?wsdl', - 'EVENTOS': 'nfe.sefaz.mt.gov.br/nfews/v2/services/RecepcaoEvento4?wsdl', - 'CADASTRO': 'nfe.sefaz.mt.gov.br/nfews/v2/services/CadConsultaCadastro4?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.', 'HOMOLOGACAO': 'https://homologacao.' }, From 371fc47a25df37f23e1bfe9fabbbdd478e0c233d Mon Sep 17 00:00:00 2001 From: Patrick Acioli Date: Tue, 18 Jun 2019 20:51:09 -0300 Subject: [PATCH 31/33] Add specific version of PyXB --- requirements-nfse.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-nfse.txt b/requirements-nfse.txt index a203ffa..582da17 100644 --- a/requirements-nfse.txt +++ b/requirements-nfse.txt @@ -1,3 +1,3 @@ # Opcional para NFS-e suds-jurko -pyxb +pyxb=1.2.4 From 52f4fef0edeb329229215dff18301eee5fc87fa2 Mon Sep 17 00:00:00 2001 From: erikseyti Date: Wed, 19 Jun 2019 16:10:46 -0300 Subject: [PATCH 32/33] [fix] Corrigido url nfe MS --- pynfe/utils/webservices.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index f58e8d1..d3c58af 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -392,15 +392,15 @@ NFE = { 'HOMOLOGACAO': 'https://nfe-homologacao.' }, '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', + '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://', - 'HOMOLOGACAO': 'https://homologacao.' + 'HOMOLOGACAO': 'https://hom.' }, 'MT': { 'STATUS': 'sefaz.mt.gov.br/nfews/v2/services/NfeStatusServico4?wsdl', From d37c46ff30205c10b16b5f29eefcbdf5db15e21b Mon Sep 17 00:00:00 2001 From: juniortada Date: Mon, 1 Jul 2019 21:18:04 -0300 Subject: [PATCH 33/33] [new] add NFC-e MG #69 --- pynfe/processamento/serializacao.py | 4 ++-- pynfe/utils/webservices.py | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index c87074a..6cbec9b 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -757,10 +757,10 @@ class SerializacaoQrcode(object): elif uf.upper() == 'SP': if tpamb == '1': 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: 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': diff --git a/pynfe/utils/webservices.py b/pynfe/utils/webservices.py index d3c58af..51dc74b 100644 --- a/pynfe/utils/webservices.py +++ b/pynfe/utils/webservices.py @@ -157,13 +157,17 @@ NFCE = { 'URL': 'http://hinternet.sefaz.ba.gov.br/nfce/consulta' }, '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': { 'STATUS': '',