pytrustnfe3
Advanced tools
+268
| Metadata-Version: 2.1 | ||
| Name: pytrustnfe3 | ||
| Version: 2.0.0 | ||
| Summary: PyTrustNFe é uma biblioteca para envio de NF-e | ||
| Home-page: https://github.com/danimaribeiro/PyTrustNFe | ||
| Author: Danimar Ribeiro | ||
| Author-email: danimaribeiro@gmail.com | ||
| License: LGPL-v2.1+ | ||
| Keywords: nfe,mdf-e | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
| Classifier: Environment :: Plugins | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+) | ||
| Classifier: Operating System :: OS Independent | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Programming Language :: Python :: 3.6 | ||
| Classifier: Programming Language :: Python :: 3.5 | ||
| Classifier: Programming Language :: Python :: 3.4 | ||
| Classifier: Topic :: Software Development :: Libraries :: Python Modules | ||
| Description-Content-Type: text/markdown | ||
| License-File: LICENSE.txt | ||
| # PyTrustNFe | ||
| Biblioteca Python que tem por objetivo enviar NFe, NFCe e NFSe no Brasil | ||
| [](https://coveralls.io/r/danimaribeiro/PyTrustNFe?branch=master3) | ||
| [](https://travis-ci.org/danimaribeiro/PyTrustNFe) | ||
| [](https://badge.fury.io/py/PyTrustNFe3) | ||
| Pacotes necessários para instalação: | ||
| ```apt-get install --no-install-recommends python3-pip python3-wheel python3-setuptools python3-openssl python3-lxml``` | ||
| Dependências: | ||
| * PyXmlSec | ||
| * lxml | ||
| * signxml | ||
| * suds-jurko | ||
| * suds-jurko-requests | ||
| * reportlab | ||
| * Jinja2 | ||
| NFSe - Cidades atendidas | ||
| ----------------------------- | ||
| * **Paulistana** - São Paulo/SP | ||
| * **Nota Carioca** - Rio de Janeiro/RJ | ||
| * **Imperial** - Petrópolis/RH | ||
| * **Goiânia** - Goiânia/GO | ||
| * [Susesu](cidades/susesu.md) - 3 cidades atendidas | ||
| * [Simpliss](cidades/simpliss.md) - 18 cidade atendidas | ||
| * [GINFES](cidades/ginfes.md) - 79 cidades atendidas | ||
| * [DSF](cidades/dsf.md) - 7 cidades atendidas | ||
| Roadmap | ||
| -------------- | ||
| Teste unitários | ||
| Implementar novos provedores de NFSe | ||
| * [Betha](cidades/betha.md) - 81 cidades atendidas WIP | ||
| * [WebISS](cidades/webiss.md) - 51 cidades atendidas | ||
| * [ISSIntel](cidades/issintel.md) - 32 cidades atendidas | ||
| * [ISSNET](cidades/issnet.md) - 32 cidades atendidas | ||
| * [Saatri](cidades/saatri.md) - 31 cidades atendidas | ||
| Exemplos de uso da NFe | ||
| ----------------------------- | ||
| Consulta Cadastro por CNPJ: | ||
| ```python | ||
| from pytrustnfe.nfe import consulta_cadastro | ||
| from pytrustnfe.certificado import Certificado | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| obj = {'cnpj': '12345678901234', 'estado': '42'} | ||
| resposta = consulta_cadastro(certificado, obj=obj, ambiente=1, estado='42') | ||
| ``` | ||
| Consulta Distribuição NF-e sem Validação de Esquema: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| # Gerando xml e enviado consulta por Ultimo NSU | ||
| response1 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| ultimo_nsu='123456789101213' | ||
| ) | ||
| # Gerando xml e enviado consulta por Chave | ||
| response2 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| chave_nfe='012345678901234567890123456789012345678912' | ||
| ) | ||
| # Gerando xml e enviado consulta por NSU | ||
| response3 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| nsu='123456789101213' | ||
| ) | ||
| ``` | ||
| Consulta Distribuição NF-e com Validação de Esquema: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe | ||
| from pytrustnfe.xml.validate import valida_nfe, SCHEMA_DFE | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| # Gerando XML para Consulta por Ultimo NSU | ||
| xml1 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| ultimo_nsu='123456789101213' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml1, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Gerando XML para Consulta por Chave | ||
| xml2 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| chave_nfe='012345678901234567890123456789012345678912' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml2, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Gerando XML para Consulta por NSU | ||
| xml3 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| nsu='123456789101213' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml3, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Enviando xml de consulta para sefaz | ||
| response = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| xml=xml1 | ||
| ) | ||
| ``` | ||
| Exemplo de uso da NFSe Paulistana | ||
| --------------------------------- | ||
| Envio de RPS por lote | ||
| ```python | ||
| certificado = open('/path/certificado.pfx', 'r').read() | ||
| certificado = Certificado(certificado, '123456') | ||
| # Necessário criar um dicionário com os dados, validação dos dados deve | ||
| # ser feita pela aplicação que está utilizando a lib | ||
| rps = [ | ||
| { | ||
| 'assinatura': '123', | ||
| 'serie': '1', | ||
| 'numero': '1', | ||
| 'data_emissao': '2016-08-29', | ||
| 'codigo_atividade': '07498', | ||
| 'valor_servico': '2.00', | ||
| 'valor_deducao': '3.00', | ||
| 'prestador': { | ||
| 'inscricao_municipal': '123456' | ||
| }, | ||
| 'tomador': { | ||
| 'tipo_cpfcnpj': '1', | ||
| 'cpf_cnpj': '12345678923256', | ||
| 'inscricao_municipal': '123456', | ||
| 'razao_social': 'Trustcode', | ||
| 'tipo_logradouro': '1', | ||
| 'logradouro': 'Vinicius de Moraes, 42', | ||
| 'numero': '42', | ||
| 'bairro': 'Corrego', | ||
| 'cidade': '4205407', # Código da cidade, de acordo com o IBGE | ||
| 'uf': 'SC', | ||
| 'cep': '88037240', | ||
| }, | ||
| 'codigo_atividade': '07498', | ||
| 'aliquota_atividade': '5.00', | ||
| 'descricao': 'Venda de servico' | ||
| } | ||
| ] | ||
| nfse = { | ||
| 'cpf_cnpj': '12345678901234', | ||
| 'data_inicio': '2016-08-29', | ||
| 'data_fim': '2016-08-29', | ||
| 'total_servicos': '2.00', | ||
| 'total_deducoes': '3.00', | ||
| 'lista_rps': rps | ||
| } | ||
| retorno = envio_lote_rps(certificado, nfse=nfse) | ||
| # retorno é um dicionário { 'received_xml':'', 'sent_xml':'', 'object': object() } | ||
| print retorno['received_xml'] | ||
| print retorno['sent_xml'] | ||
| # retorno['object'] é um objeto python criado apartir do xml de resposta | ||
| print retorno['object'].Cabecalho.Sucesso | ||
| print retorno['object'].ChaveNFeRPS.ChaveNFe.NumeroNFe | ||
| print retorno['object'].ChaveNFeRPS.ChaveRPS.NumeroRPS | ||
| ``` | ||
| Cancelamento de NFSe: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfse.paulistana import cancelamento_nfe | ||
| certificado = open('/path/certificado.pfx', 'r').read() | ||
| certificado = Certificado(certificado, '123456') | ||
| cancelamento = { | ||
| 'cnpj_remetente': '123', | ||
| 'assinatura': 'assinatura', | ||
| 'numero_nfse': '456', | ||
| 'inscricao_municipal': '654', | ||
| 'codigo_verificacao': '789', | ||
| } | ||
| retorno = cancelamento_nfe(certificado, cancelamento=cancelamento) | ||
| # retorno é um dicionário { 'received_xml':'', 'sent_xml':'', 'object': object() } | ||
| print retorno['received_xml'] | ||
| print retorno['sent_xml'] | ||
| # retorno['object'] é um objeto python criado apartir do xml de resposta | ||
| print retorno['object'].Cabecalho.Sucesso | ||
| if not retorno['object'].Cabecalho.Sucesso: # Cancelamento com erro | ||
| print retorno['object'].Erro.Codigo | ||
| print retorno['object'].Erro.Descricao | ||
| ``` |
| Metadata-Version: 2.1 | ||
| Name: pytrustnfe3 | ||
| Version: 2.0.0 | ||
| Summary: PyTrustNFe é uma biblioteca para envio de NF-e | ||
| Home-page: https://github.com/danimaribeiro/PyTrustNFe | ||
| Author: Danimar Ribeiro | ||
| Author-email: danimaribeiro@gmail.com | ||
| License: LGPL-v2.1+ | ||
| Keywords: nfe,mdf-e | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
| Classifier: Environment :: Plugins | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+) | ||
| Classifier: Operating System :: OS Independent | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Programming Language :: Python :: 3.6 | ||
| Classifier: Programming Language :: Python :: 3.5 | ||
| Classifier: Programming Language :: Python :: 3.4 | ||
| Classifier: Topic :: Software Development :: Libraries :: Python Modules | ||
| Description-Content-Type: text/markdown | ||
| License-File: LICENSE.txt | ||
| # PyTrustNFe | ||
| Biblioteca Python que tem por objetivo enviar NFe, NFCe e NFSe no Brasil | ||
| [](https://coveralls.io/r/danimaribeiro/PyTrustNFe?branch=master3) | ||
| [](https://travis-ci.org/danimaribeiro/PyTrustNFe) | ||
| [](https://badge.fury.io/py/PyTrustNFe3) | ||
| Pacotes necessários para instalação: | ||
| ```apt-get install --no-install-recommends python3-pip python3-wheel python3-setuptools python3-openssl python3-lxml``` | ||
| Dependências: | ||
| * PyXmlSec | ||
| * lxml | ||
| * signxml | ||
| * suds-jurko | ||
| * suds-jurko-requests | ||
| * reportlab | ||
| * Jinja2 | ||
| NFSe - Cidades atendidas | ||
| ----------------------------- | ||
| * **Paulistana** - São Paulo/SP | ||
| * **Nota Carioca** - Rio de Janeiro/RJ | ||
| * **Imperial** - Petrópolis/RH | ||
| * **Goiânia** - Goiânia/GO | ||
| * [Susesu](cidades/susesu.md) - 3 cidades atendidas | ||
| * [Simpliss](cidades/simpliss.md) - 18 cidade atendidas | ||
| * [GINFES](cidades/ginfes.md) - 79 cidades atendidas | ||
| * [DSF](cidades/dsf.md) - 7 cidades atendidas | ||
| Roadmap | ||
| -------------- | ||
| Teste unitários | ||
| Implementar novos provedores de NFSe | ||
| * [Betha](cidades/betha.md) - 81 cidades atendidas WIP | ||
| * [WebISS](cidades/webiss.md) - 51 cidades atendidas | ||
| * [ISSIntel](cidades/issintel.md) - 32 cidades atendidas | ||
| * [ISSNET](cidades/issnet.md) - 32 cidades atendidas | ||
| * [Saatri](cidades/saatri.md) - 31 cidades atendidas | ||
| Exemplos de uso da NFe | ||
| ----------------------------- | ||
| Consulta Cadastro por CNPJ: | ||
| ```python | ||
| from pytrustnfe.nfe import consulta_cadastro | ||
| from pytrustnfe.certificado import Certificado | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| obj = {'cnpj': '12345678901234', 'estado': '42'} | ||
| resposta = consulta_cadastro(certificado, obj=obj, ambiente=1, estado='42') | ||
| ``` | ||
| Consulta Distribuição NF-e sem Validação de Esquema: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| # Gerando xml e enviado consulta por Ultimo NSU | ||
| response1 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| ultimo_nsu='123456789101213' | ||
| ) | ||
| # Gerando xml e enviado consulta por Chave | ||
| response2 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| chave_nfe='012345678901234567890123456789012345678912' | ||
| ) | ||
| # Gerando xml e enviado consulta por NSU | ||
| response3 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| nsu='123456789101213' | ||
| ) | ||
| ``` | ||
| Consulta Distribuição NF-e com Validação de Esquema: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe | ||
| from pytrustnfe.xml.validate import valida_nfe, SCHEMA_DFE | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| # Gerando XML para Consulta por Ultimo NSU | ||
| xml1 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| ultimo_nsu='123456789101213' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml1, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Gerando XML para Consulta por Chave | ||
| xml2 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| chave_nfe='012345678901234567890123456789012345678912' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml2, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Gerando XML para Consulta por NSU | ||
| xml3 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| nsu='123456789101213' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml3, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Enviando xml de consulta para sefaz | ||
| response = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| xml=xml1 | ||
| ) | ||
| ``` | ||
| Exemplo de uso da NFSe Paulistana | ||
| --------------------------------- | ||
| Envio de RPS por lote | ||
| ```python | ||
| certificado = open('/path/certificado.pfx', 'r').read() | ||
| certificado = Certificado(certificado, '123456') | ||
| # Necessário criar um dicionário com os dados, validação dos dados deve | ||
| # ser feita pela aplicação que está utilizando a lib | ||
| rps = [ | ||
| { | ||
| 'assinatura': '123', | ||
| 'serie': '1', | ||
| 'numero': '1', | ||
| 'data_emissao': '2016-08-29', | ||
| 'codigo_atividade': '07498', | ||
| 'valor_servico': '2.00', | ||
| 'valor_deducao': '3.00', | ||
| 'prestador': { | ||
| 'inscricao_municipal': '123456' | ||
| }, | ||
| 'tomador': { | ||
| 'tipo_cpfcnpj': '1', | ||
| 'cpf_cnpj': '12345678923256', | ||
| 'inscricao_municipal': '123456', | ||
| 'razao_social': 'Trustcode', | ||
| 'tipo_logradouro': '1', | ||
| 'logradouro': 'Vinicius de Moraes, 42', | ||
| 'numero': '42', | ||
| 'bairro': 'Corrego', | ||
| 'cidade': '4205407', # Código da cidade, de acordo com o IBGE | ||
| 'uf': 'SC', | ||
| 'cep': '88037240', | ||
| }, | ||
| 'codigo_atividade': '07498', | ||
| 'aliquota_atividade': '5.00', | ||
| 'descricao': 'Venda de servico' | ||
| } | ||
| ] | ||
| nfse = { | ||
| 'cpf_cnpj': '12345678901234', | ||
| 'data_inicio': '2016-08-29', | ||
| 'data_fim': '2016-08-29', | ||
| 'total_servicos': '2.00', | ||
| 'total_deducoes': '3.00', | ||
| 'lista_rps': rps | ||
| } | ||
| retorno = envio_lote_rps(certificado, nfse=nfse) | ||
| # retorno é um dicionário { 'received_xml':'', 'sent_xml':'', 'object': object() } | ||
| print retorno['received_xml'] | ||
| print retorno['sent_xml'] | ||
| # retorno['object'] é um objeto python criado apartir do xml de resposta | ||
| print retorno['object'].Cabecalho.Sucesso | ||
| print retorno['object'].ChaveNFeRPS.ChaveNFe.NumeroNFe | ||
| print retorno['object'].ChaveNFeRPS.ChaveRPS.NumeroRPS | ||
| ``` | ||
| Cancelamento de NFSe: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfse.paulistana import cancelamento_nfe | ||
| certificado = open('/path/certificado.pfx', 'r').read() | ||
| certificado = Certificado(certificado, '123456') | ||
| cancelamento = { | ||
| 'cnpj_remetente': '123', | ||
| 'assinatura': 'assinatura', | ||
| 'numero_nfse': '456', | ||
| 'inscricao_municipal': '654', | ||
| 'codigo_verificacao': '789', | ||
| } | ||
| retorno = cancelamento_nfe(certificado, cancelamento=cancelamento) | ||
| # retorno é um dicionário { 'received_xml':'', 'sent_xml':'', 'object': object() } | ||
| print retorno['received_xml'] | ||
| print retorno['sent_xml'] | ||
| # retorno['object'] é um objeto python criado apartir do xml de resposta | ||
| print retorno['object'].Cabecalho.Sucesso | ||
| if not retorno['object'].Cabecalho.Sucesso: # Cancelamento com erro | ||
| print retorno['object'].Erro.Codigo | ||
| print retorno['object'].Erro.Descricao | ||
| ``` |
| xmlsec>=1.3.13 | ||
| lxml>=4.2.1 | ||
| cryptography>=3.4.8 | ||
| pyOpenSSL>=17.5.0 | ||
| certifi>=2018.1.18 | ||
| urllib3 | ||
| Jinja2 | ||
| suds-community | ||
| suds-requests4 | ||
| reportlab | ||
| pytz | ||
| zeep |
| LICENSE.txt | ||
| README.md | ||
| setup.py | ||
| pytrustnfe/Servidores.py | ||
| pytrustnfe/__init__.py | ||
| pytrustnfe/certificado.py | ||
| pytrustnfe/client.py | ||
| pytrustnfe/exceptions.py | ||
| pytrustnfe/urls.py | ||
| pytrustnfe/utils.py | ||
| pytrustnfe/nfe/__init__.py | ||
| pytrustnfe/nfe/assinatura.py | ||
| pytrustnfe/nfe/danfce.py | ||
| pytrustnfe/nfe/danfe.py | ||
| pytrustnfe/nfe/patch.py | ||
| pytrustnfe/nfe/fonts/NimbusSanL Bold.ttf | ||
| pytrustnfe/nfe/fonts/NimbusSanL Regular.ttf | ||
| pytrustnfe/nfe/templates/NFeDistribuicaoDFe.xml | ||
| pytrustnfe/nfe/templates/NfeAutorizacao.xml | ||
| pytrustnfe/nfe/templates/NfeConsultaCadastro.xml | ||
| pytrustnfe/nfe/templates/NfeConsultaDest.xml | ||
| pytrustnfe/nfe/templates/NfeConsultaProtocolo.xml | ||
| pytrustnfe/nfe/templates/NfeInutilizacao.xml | ||
| pytrustnfe/nfe/templates/NfeRetAutorizacao.xml | ||
| pytrustnfe/nfe/templates/NfeStatusServico.xml | ||
| pytrustnfe/nfe/templates/RecepcaoEvento.xml | ||
| pytrustnfe/nfe/templates/RecepcaoEventoManifesto.xml | ||
| pytrustnfe/nfse/__init__.py | ||
| pytrustnfe/nfse/assinatura.py | ||
| pytrustnfe/nfse/aparecida/__init__.py | ||
| pytrustnfe/nfse/aparecida/templates/Rps.xml | ||
| pytrustnfe/nfse/aparecida/templates/cancelarNfse.xml | ||
| pytrustnfe/nfse/aparecida/templates/consultarLoteRps.xml | ||
| pytrustnfe/nfse/aparecida/templates/recepcionarLoteRps.xml | ||
| pytrustnfe/nfse/betha/__init__.py | ||
| pytrustnfe/nfse/betha/templates/CancelarNfse.xml | ||
| pytrustnfe/nfse/betha/templates/ConsultarLoteRps.xml | ||
| pytrustnfe/nfse/betha/templates/ConsultarNfseFaixa.xml | ||
| pytrustnfe/nfse/betha/templates/ConsultarNfsePorRps.xml | ||
| pytrustnfe/nfse/betha/templates/ConsultarNfseServicoPrestado.xml | ||
| pytrustnfe/nfse/betha/templates/ConsultarNfseServicoTomado.xml | ||
| pytrustnfe/nfse/betha/templates/GerarNfse.xml | ||
| pytrustnfe/nfse/betha/templates/RecepcionarLoteRps.xml | ||
| pytrustnfe/nfse/betha/templates/RecepcionarLoteRpsSincrono.xml | ||
| pytrustnfe/nfse/betha/templates/Rps.xml | ||
| pytrustnfe/nfse/betha/templates/SubstituirNfse.xml | ||
| pytrustnfe/nfse/bh/__init__.py | ||
| pytrustnfe/nfse/bh/assinatura.py | ||
| pytrustnfe/nfse/bh/templates/CancelarNfse.xml | ||
| pytrustnfe/nfse/bh/templates/GerarNfse.xml | ||
| pytrustnfe/nfse/bh/templates/Rps.xml | ||
| pytrustnfe/nfse/carioca/__init__.py | ||
| pytrustnfe/nfse/carioca/templates/CancelarNfse.xml | ||
| pytrustnfe/nfse/carioca/templates/GerarNfse.xml | ||
| pytrustnfe/nfse/carioca/templates/Rps.xml | ||
| pytrustnfe/nfse/dsf/__init__.py | ||
| pytrustnfe/nfse/dsf/templates/cancelar.xml | ||
| pytrustnfe/nfse/dsf/templates/consulta_notas.xml | ||
| pytrustnfe/nfse/dsf/templates/consultarLote.xml | ||
| pytrustnfe/nfse/dsf/templates/consultarNFSeRps.xml | ||
| pytrustnfe/nfse/dsf/templates/enviar.xml | ||
| pytrustnfe/nfse/dsf/templates/soap_header.xml | ||
| pytrustnfe/nfse/floripa/__init__.py | ||
| pytrustnfe/nfse/floripa/templates/cancelar_nota.xml | ||
| pytrustnfe/nfse/floripa/templates/processar_nota.xml | ||
| pytrustnfe/nfse/ginfes/__init__.py | ||
| pytrustnfe/nfse/ginfes/templates/CancelarNfseV3.xml | ||
| pytrustnfe/nfse/ginfes/templates/ConsultarLoteRpsV3.xml | ||
| pytrustnfe/nfse/ginfes/templates/ConsultarNfsePorRpsV3.xml | ||
| pytrustnfe/nfse/ginfes/templates/ConsultarNfseV3.xml | ||
| pytrustnfe/nfse/ginfes/templates/ConsultarSituacaoLoteRpsV3.xml | ||
| pytrustnfe/nfse/ginfes/templates/RecepcionarLoteRpsV3.xml | ||
| pytrustnfe/nfse/ginfes/templates/Rps.xml | ||
| pytrustnfe/nfse/goiania/__init__.py | ||
| pytrustnfe/nfse/goiania/assinatura.py | ||
| pytrustnfe/nfse/imperial/__init__.py | ||
| pytrustnfe/nfse/imperial/templates/CancelarNota.xml | ||
| pytrustnfe/nfse/imperial/templates/GerarNota.xml | ||
| pytrustnfe/nfse/issintel/__init__.py | ||
| pytrustnfe/nfse/issnet/__init__.py | ||
| pytrustnfe/nfse/mga/__init__.py | ||
| pytrustnfe/nfse/mga/assinatura.py | ||
| pytrustnfe/nfse/mga/templates/CancelarNfse.xml | ||
| pytrustnfe/nfse/mga/templates/GerarNfse.xml | ||
| pytrustnfe/nfse/mga/templates/Rps.xml | ||
| pytrustnfe/nfse/natal/__init__.py | ||
| pytrustnfe/nfse/paulistana/__init__.py | ||
| pytrustnfe/nfse/paulistana/templates/CancelamentoNFe.xml | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaCNPJ.xml | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaInformacoesLote.xml | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaLote.xml | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaNFe.xml | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaNFeEmitidas.xml | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaNFeRecebidas.xml | ||
| pytrustnfe/nfse/paulistana/templates/EnvioLoteRPS.xml | ||
| pytrustnfe/nfse/paulistana/templates/EnvioRPS.xml | ||
| pytrustnfe/nfse/saatri/__init__.py | ||
| pytrustnfe/nfse/simpliss/__init__.py | ||
| pytrustnfe/nfse/simpliss/templates/CancelarNfse.xml | ||
| pytrustnfe/nfse/simpliss/templates/ConsultarLoteRps.xml | ||
| pytrustnfe/nfse/simpliss/templates/ConsultarNfse.xml | ||
| pytrustnfe/nfse/simpliss/templates/ConsultarNfsePorRps.xml | ||
| pytrustnfe/nfse/simpliss/templates/ConsultarSituacaoLoteRps.xml | ||
| pytrustnfe/nfse/simpliss/templates/GerarNfse.xml | ||
| pytrustnfe/nfse/simpliss/templates/RecepcionarLoteRps.xml | ||
| pytrustnfe/nfse/simpliss/templates/Rps.xml | ||
| pytrustnfe/nfse/simpliss/templates/SoapRequest.xml | ||
| pytrustnfe/nfse/susesu/__init__.py | ||
| pytrustnfe/nfse/susesu/templates/EnviarNota.xml | ||
| pytrustnfe/nfse/susesu/templates/EnviarNotaRetornaurlNota.xml | ||
| pytrustnfe/nfse/susesu/templates/Nota.xml | ||
| pytrustnfe/nfse/webiss/__init__.py | ||
| pytrustnfe/xml/__init__.py | ||
| pytrustnfe/xml/filters.py | ||
| pytrustnfe/xml/validate.py | ||
| pytrustnfe/xml/schemas/distDFeInt_v1.01.xsd | ||
| pytrustnfe/xml/schemas/enviNFe_v4.00.xsd | ||
| pytrustnfe/xml/schemas/leiauteNFe_v4.00.xsd | ||
| pytrustnfe/xml/schemas/nfe_v4.00.xsd | ||
| pytrustnfe/xml/schemas/tiposBasico_v4.00.xsd | ||
| pytrustnfe/xml/schemas/xmldsig-core-schema_v1.01.xsd | ||
| pytrustnfe3.egg-info/PKG-INFO | ||
| pytrustnfe3.egg-info/SOURCES.txt | ||
| pytrustnfe3.egg-info/dependency_links.txt | ||
| pytrustnfe3.egg-info/requires.txt | ||
| pytrustnfe3.egg-info/top_level.txt | ||
| tests/test_assinatura.py | ||
| tests/test_certificado.py | ||
| tests/test_danfe.py | ||
| tests/test_ginfes.py | ||
| tests/test_nfse_paulistana.py | ||
| tests/test_nfse_paulistana_email_tomador.py | ||
| tests/test_nfse_paulistana_endereco_tomador.py | ||
| tests/test_nfse_paulistana_para_lote.py | ||
| tests/test_nfse_paulistana_tipo_cpfcnpj.py | ||
| tests/test_nfse_paulistana_valores_default.py | ||
| tests/test_servidores.py | ||
| tests/test_utils.py | ||
| tests/test_xml.py | ||
| tests/test_xml_serializacao.py |
| pytrustnfe |
+246
| # PyTrustNFe | ||
| Biblioteca Python que tem por objetivo enviar NFe, NFCe e NFSe no Brasil | ||
| [](https://coveralls.io/r/danimaribeiro/PyTrustNFe?branch=master3) | ||
| [](https://travis-ci.org/danimaribeiro/PyTrustNFe) | ||
| [](https://badge.fury.io/py/PyTrustNFe3) | ||
| Pacotes necessários para instalação: | ||
| ```apt-get install --no-install-recommends python3-pip python3-wheel python3-setuptools python3-openssl python3-lxml``` | ||
| Dependências: | ||
| * PyXmlSec | ||
| * lxml | ||
| * signxml | ||
| * suds-jurko | ||
| * suds-jurko-requests | ||
| * reportlab | ||
| * Jinja2 | ||
| NFSe - Cidades atendidas | ||
| ----------------------------- | ||
| * **Paulistana** - São Paulo/SP | ||
| * **Nota Carioca** - Rio de Janeiro/RJ | ||
| * **Imperial** - Petrópolis/RH | ||
| * **Goiânia** - Goiânia/GO | ||
| * [Susesu](cidades/susesu.md) - 3 cidades atendidas | ||
| * [Simpliss](cidades/simpliss.md) - 18 cidade atendidas | ||
| * [GINFES](cidades/ginfes.md) - 79 cidades atendidas | ||
| * [DSF](cidades/dsf.md) - 7 cidades atendidas | ||
| Roadmap | ||
| -------------- | ||
| Teste unitários | ||
| Implementar novos provedores de NFSe | ||
| * [Betha](cidades/betha.md) - 81 cidades atendidas WIP | ||
| * [WebISS](cidades/webiss.md) - 51 cidades atendidas | ||
| * [ISSIntel](cidades/issintel.md) - 32 cidades atendidas | ||
| * [ISSNET](cidades/issnet.md) - 32 cidades atendidas | ||
| * [Saatri](cidades/saatri.md) - 31 cidades atendidas | ||
| Exemplos de uso da NFe | ||
| ----------------------------- | ||
| Consulta Cadastro por CNPJ: | ||
| ```python | ||
| from pytrustnfe.nfe import consulta_cadastro | ||
| from pytrustnfe.certificado import Certificado | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| obj = {'cnpj': '12345678901234', 'estado': '42'} | ||
| resposta = consulta_cadastro(certificado, obj=obj, ambiente=1, estado='42') | ||
| ``` | ||
| Consulta Distribuição NF-e sem Validação de Esquema: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| # Gerando xml e enviado consulta por Ultimo NSU | ||
| response1 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| ultimo_nsu='123456789101213' | ||
| ) | ||
| # Gerando xml e enviado consulta por Chave | ||
| response2 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| chave_nfe='012345678901234567890123456789012345678912' | ||
| ) | ||
| # Gerando xml e enviado consulta por NSU | ||
| response3 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| nsu='123456789101213' | ||
| ) | ||
| ``` | ||
| Consulta Distribuição NF-e com Validação de Esquema: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe | ||
| from pytrustnfe.xml.validate import valida_nfe, SCHEMA_DFE | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| # Gerando XML para Consulta por Ultimo NSU | ||
| xml1 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| ultimo_nsu='123456789101213' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml1, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Gerando XML para Consulta por Chave | ||
| xml2 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| chave_nfe='012345678901234567890123456789012345678912' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml2, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Gerando XML para Consulta por NSU | ||
| xml3 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| nsu='123456789101213' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml3, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Enviando xml de consulta para sefaz | ||
| response = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| xml=xml1 | ||
| ) | ||
| ``` | ||
| Exemplo de uso da NFSe Paulistana | ||
| --------------------------------- | ||
| Envio de RPS por lote | ||
| ```python | ||
| certificado = open('/path/certificado.pfx', 'r').read() | ||
| certificado = Certificado(certificado, '123456') | ||
| # Necessário criar um dicionário com os dados, validação dos dados deve | ||
| # ser feita pela aplicação que está utilizando a lib | ||
| rps = [ | ||
| { | ||
| 'assinatura': '123', | ||
| 'serie': '1', | ||
| 'numero': '1', | ||
| 'data_emissao': '2016-08-29', | ||
| 'codigo_atividade': '07498', | ||
| 'valor_servico': '2.00', | ||
| 'valor_deducao': '3.00', | ||
| 'prestador': { | ||
| 'inscricao_municipal': '123456' | ||
| }, | ||
| 'tomador': { | ||
| 'tipo_cpfcnpj': '1', | ||
| 'cpf_cnpj': '12345678923256', | ||
| 'inscricao_municipal': '123456', | ||
| 'razao_social': 'Trustcode', | ||
| 'tipo_logradouro': '1', | ||
| 'logradouro': 'Vinicius de Moraes, 42', | ||
| 'numero': '42', | ||
| 'bairro': 'Corrego', | ||
| 'cidade': '4205407', # Código da cidade, de acordo com o IBGE | ||
| 'uf': 'SC', | ||
| 'cep': '88037240', | ||
| }, | ||
| 'codigo_atividade': '07498', | ||
| 'aliquota_atividade': '5.00', | ||
| 'descricao': 'Venda de servico' | ||
| } | ||
| ] | ||
| nfse = { | ||
| 'cpf_cnpj': '12345678901234', | ||
| 'data_inicio': '2016-08-29', | ||
| 'data_fim': '2016-08-29', | ||
| 'total_servicos': '2.00', | ||
| 'total_deducoes': '3.00', | ||
| 'lista_rps': rps | ||
| } | ||
| retorno = envio_lote_rps(certificado, nfse=nfse) | ||
| # retorno é um dicionário { 'received_xml':'', 'sent_xml':'', 'object': object() } | ||
| print retorno['received_xml'] | ||
| print retorno['sent_xml'] | ||
| # retorno['object'] é um objeto python criado apartir do xml de resposta | ||
| print retorno['object'].Cabecalho.Sucesso | ||
| print retorno['object'].ChaveNFeRPS.ChaveNFe.NumeroNFe | ||
| print retorno['object'].ChaveNFeRPS.ChaveRPS.NumeroRPS | ||
| ``` | ||
| Cancelamento de NFSe: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfse.paulistana import cancelamento_nfe | ||
| certificado = open('/path/certificado.pfx', 'r').read() | ||
| certificado = Certificado(certificado, '123456') | ||
| cancelamento = { | ||
| 'cnpj_remetente': '123', | ||
| 'assinatura': 'assinatura', | ||
| 'numero_nfse': '456', | ||
| 'inscricao_municipal': '654', | ||
| 'codigo_verificacao': '789', | ||
| } | ||
| retorno = cancelamento_nfe(certificado, cancelamento=cancelamento) | ||
| # retorno é um dicionário { 'received_xml':'', 'sent_xml':'', 'object': object() } | ||
| print retorno['received_xml'] | ||
| print retorno['sent_xml'] | ||
| # retorno['object'] é um objeto python criado apartir do xml de resposta | ||
| print retorno['object'].Cabecalho.Sucesso | ||
| if not retorno['object'].Cabecalho.Sucesso: # Cancelamento com erro | ||
| print retorno['object'].Erro.Codigo | ||
| print retorno['object'].Erro.Descricao | ||
| ``` |
| [egg_info] | ||
| tag_build = | ||
| tag_date = 0 | ||
+69
| # coding=utf-8 | ||
| from setuptools import setup, find_packages | ||
| VERSION = "2.0.0" | ||
| setup( | ||
| name="pytrustnfe3", | ||
| version=VERSION, | ||
| author="Danimar Ribeiro", | ||
| author_email="danimaribeiro@gmail.com", | ||
| keywords=["nfe", "mdf-e"], | ||
| classifiers=[ | ||
| "Development Status :: 5 - Production/Stable", | ||
| "Environment :: Plugins", | ||
| "Intended Audience :: Developers", | ||
| "License :: OSI Approved :: GNU Lesser General Public License v2 or \ | ||
| later (LGPLv2+)", | ||
| "Operating System :: OS Independent", | ||
| "Programming Language :: Python", | ||
| "Programming Language :: Python :: 3.6", | ||
| "Programming Language :: Python :: 3.5", | ||
| "Programming Language :: Python :: 3.4", | ||
| "Topic :: Software Development :: Libraries :: Python Modules", | ||
| ], | ||
| packages=find_packages(exclude=["*test*"]), | ||
| package_data={ | ||
| "pytrustnfe": [ | ||
| "nfe/templates/*xml", | ||
| "nfe/fonts/*ttf", | ||
| "nfse/paulistana/templates/*xml", | ||
| "nfse/dsf/templates/*xml", | ||
| "nfse/ginfes/templates/*xml", | ||
| "nfse/simpliss/templates/*xml", | ||
| "nfse/betha/templates/*xml", | ||
| "nfse/susesu/templates/*xml", | ||
| "nfse/imperial/templates/*xml", | ||
| "nfse/floripa/templates/*xml", | ||
| "nfse/carioca/templates/*xml", | ||
| "nfse/bh/templates/*xml", | ||
| "nfse/mga/templates/*xml", | ||
| "nfse/aparecida/templates/*xml", | ||
| "xml/schemas/*xsd", | ||
| ] | ||
| }, | ||
| url="https://github.com/danimaribeiro/PyTrustNFe", | ||
| license="LGPL-v2.1+", | ||
| description="PyTrustNFe é uma biblioteca para envio de NF-e", | ||
| long_description=open("README.md", "r").read(), | ||
| long_description_content_type="text/markdown", | ||
| install_requires=[ | ||
| 'xmlsec >= 1.3.13', # apt update;apt install libxmlsec1-dev pkg-config -y | ||
| 'lxml >= 4.2.1', | ||
| 'cryptography >= 3.4.8', | ||
| 'pyOpenSSL >= 17.5.0', | ||
| 'certifi >= 2018.1.18', | ||
| 'urllib3', | ||
| 'Jinja2', | ||
| 'suds-community', | ||
| 'suds-requests4', | ||
| 'reportlab', | ||
| 'pytz', | ||
| 'zeep', | ||
| ], | ||
| tests_require=[ | ||
| 'pytest', | ||
| ], | ||
| ) |
| # coding=utf-8 | ||
| """ | ||
| Created on Jun 14, 2015 | ||
| @author: danimar | ||
| """ | ||
| import os | ||
| import os.path | ||
| import unittest | ||
| from lxml import etree | ||
| from pytrustnfe.nfe.assinatura import Assinatura | ||
| XML_ASSINAR = ( | ||
| '<Envelope xmlns="urn:envelope">' | ||
| ' <Data Id="NFe43150602261542000143550010000000761792265342">' | ||
| " Hello, World!" | ||
| " </Data>" | ||
| "</Envelope>" | ||
| ) | ||
| XML_ERRADO = ( | ||
| '<Envelope xmlns="urn:envelope">' | ||
| ' <Data Id="NFe">' | ||
| " Hello, World!" | ||
| " </Data>" | ||
| "</Envelope>" | ||
| ) | ||
| class test_assinatura(unittest.TestCase): | ||
| caminho = os.path.dirname(__file__) | ||
| def test_assinar_xml_senha_invalida(self): | ||
| pfx = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| signer = Assinatura(pfx, "123") | ||
| self.assertRaises( | ||
| Exception, | ||
| signer.assina_xml, | ||
| signer, | ||
| etree.fromstring(XML_ASSINAR), | ||
| "NFe43150602261542000143550010000000761792265342", | ||
| ) | ||
| def test_assinar_xml_invalido(self): | ||
| pfx = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| signer = Assinatura(pfx, "123456") | ||
| self.assertRaises( | ||
| Exception, | ||
| signer.assina_xml, | ||
| signer, | ||
| etree.fromstring(XML_ERRADO), | ||
| "NFe43150602261542000143550010000000761792265342", | ||
| ) | ||
| @unittest.skip | ||
| def test_assinar_xml_valido(self): | ||
| pfx = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| signer = Assinatura(pfx, "123456") | ||
| xml = signer.assina_xml( | ||
| etree.fromstring(XML_ASSINAR), | ||
| "NFe43150602261542000143550010000000761792265342", | ||
| ) | ||
| xml_assinado = open( | ||
| os.path.join(self.caminho, "xml_valido_assinado.xml"), "r" | ||
| ).read() | ||
| self.assertEqual(xml_assinado, xml, "Xml assinado é inválido") |
| # coding=utf-8 | ||
| """ | ||
| Created on Jun 14, 2015 | ||
| @author: danimar | ||
| """ | ||
| import unittest | ||
| import os | ||
| import os.path | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.certificado import save_cert_key | ||
| from pytrustnfe.certificado import extract_cert_and_key_from_pfx | ||
| CHAVE = ( | ||
| "-----BEGIN PRIVATE KEY-----\n" | ||
| "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJONRp6l1y2ojgv8\n" | ||
| "tP3AOLW0vjWQqiPseBLM7YAxbzz5R7LYlWHC0ZJ4uIvd4Cvc6AuoNJoeuhzFcwHx\n" | ||
| "PL0TcFuW+5up1ktUohwaJ+/zKrMODCKt0gvif302yqasMnwLh9mGZQIkLkHPOX8p\n" | ||
| "ZQDC4dlqwOyYDi0f+bRd5C7aWx3RAgMBAAECgYADqASP+dwTLZIXifOSNikxl4D/\n" | ||
| "Is6UhU+UZ6+a9Z6kDClSrTtGaOV4k7U/AgiEDb1STKDBEPHbtKjc63Vt2gV2teem\n" | ||
| "ohU0Giv+gD42uuwy2DM31OfYrpR46mzOK9JrpQc78b36ealL3AWJ1gyBbbcOWbAb\n" | ||
| "KmP742V7pcD07EEp4QJBAM/e7M8VdLgOyaQzH9KHekU6fJlI4vy1UwgRUwx3/1W6\n" | ||
| "zlBYo1qXfc7NSVG8ZaSrJwW4rPn393u31CpXv+oc/OMCQQC1txS6nxM9+p/641HX\n" | ||
| "CHXiWJRn0Wv7rT1FyF2dHO+OQOkCCnHCsGDMf3bacTNb7iyaPbXEDac8od5uF/3h\n" | ||
| "aUy7AkBDPGoAeYItXqseL2Mlp6iG5+oRcp/o+YWH4IKqT84JHslI98KutL1+vKvw\n" | ||
| "gi2mW63djeR1Xh1wqP85SvTKduHdAkAIJLlIF8Lr/yRWQQO06EsoJqIX+Pmm4L+j\n" | ||
| "NfSECvztWhlXHxK0D+V2pKu15GbR0t2q1+Micx4wiGyIcIjPJkHrAkAvlbXGFcGT\n" | ||
| "pk9bQ8nl7EYqlvVn1TejzTLfBhBYOse/xT/NI4Kwjkan9R+EJ1cOc9EE8gm1W3jv\n" | ||
| "fMw/Bh2wC5kj\n" | ||
| "-----END PRIVATE KEY-----\n" | ||
| ) | ||
| CERTIFICADO = ( | ||
| "-----BEGIN CERTIFICATE-----\n" | ||
| "MIICMTCCAZqgAwIBAgIQfYOsIEVuAJ1FwwcTrY0t1DANBgkqhkiG9w0BAQUFADBX\n" | ||
| "MVUwUwYDVQQDHkwAewA1ADkARgAxAEUANAA2ADEALQBEAEQARQA1AC0ANABEADIA\n" | ||
| "RgAtAEEAMAAxAEEALQA4ADMAMwAyADIAQQA5AEUAQgA4ADMAOAB9MB4XDTE1MDYx\n" | ||
| "NTA1NDc1N1oXDTE2MDYxNDExNDc1N1owVzFVMFMGA1UEAx5MAHsANQA5AEYAMQBF\n" | ||
| "ADQANgAxAC0ARABEAEUANQAtADQARAAyAEYALQBBADAAMQBBAC0AOAAzADMAMgAy\n" | ||
| "AEEAOQBFAEIAOAAzADgAfTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAk41G\n" | ||
| "nqXXLaiOC/y0/cA4tbS+NZCqI+x4EsztgDFvPPlHstiVYcLRkni4i93gK9zoC6g0\n" | ||
| "mh66HMVzAfE8vRNwW5b7m6nWS1SiHBon7/Mqsw4MIq3SC+J/fTbKpqwyfAuH2YZl\n" | ||
| "AiQuQc85fyllAMLh2WrA7JgOLR/5tF3kLtpbHdECAwEAATANBgkqhkiG9w0BAQUF\n" | ||
| "AAOBgQArdh+RyT6VxKGsXk1zhHsgwXfToe6GpTF4W8PHI1+T0WIsNForDhvst6nm\n" | ||
| "QtgAhuZM9rxpOJuNKc+pM29EixpAiZZiRMCSWEItNyEVdUIi+YnKBcAHd88TwO86\n" | ||
| "d126MWQ2O8cu5W1VoDp7hYBYKOnLbYi11/StO+0rzK+oPYAvIw==\n" | ||
| "-----END CERTIFICATE-----\n" | ||
| ) | ||
| class test_assinatura(unittest.TestCase): | ||
| caminho = os.path.dirname(__file__) | ||
| def test_preparar_pfx(self): | ||
| dir_pfx = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| cert, key = extract_cert_and_key_from_pfx(dir_pfx, "123456") | ||
| self.assertEqual(key, CHAVE, "Chave gerada inválida") | ||
| self.assertEqual(cert, CERTIFICADO, "Certificado inválido") | ||
| def test_save_pfx(self): | ||
| pfx_source = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| pfx = Certificado(pfx_source, "123") | ||
| path = pfx.save_pfx() | ||
| saved = open(path, "rb").read() | ||
| self.assertEqual( | ||
| pfx_source, saved, "Arquivo pfx salvo não bate com arquivo lido" | ||
| ) | ||
| def test_save_cert_and_key(self): | ||
| dir_pfx = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| cert, key = extract_cert_and_key_from_pfx(dir_pfx, "123456") | ||
| cert_path, key_path = save_cert_key(cert, key) | ||
| cert_saved = open(cert_path, "r").read() | ||
| key_saved = open(key_path, "r").read() | ||
| self.assertEqual(cert, cert_saved, "Certificado não corresponde ao original") | ||
| self.assertEqual(key, key_saved, "Chave não corresponde ao original") | ||
| def test_pfx_nao_existe(self): | ||
| self.assertRaises( | ||
| Exception, extract_cert_and_key_from_pfx, "file.pfx", "123456" | ||
| ) | ||
| def test_pfx_senha_invalida(self): | ||
| dir_pfx = os.path.join(self.caminho, "teste.pfx") | ||
| self.assertRaises(Exception, extract_cert_and_key_from_pfx, dir_pfx, "123") |
| # coding=utf-8 | ||
| import tempfile | ||
| import os.path | ||
| import unittest | ||
| from lxml import etree | ||
| from pytrustnfe.nfe.danfe import danfe | ||
| class test_danfe(unittest.TestCase): | ||
| caminho = os.path.dirname(__file__) | ||
| def test_can_generate_danfe(self): | ||
| path = os.path.join(os.path.dirname(__file__), "XMLs") | ||
| xml_string = open(os.path.join(path, "NFe00000857.xml"), "r").read() | ||
| # xml_string = open('/home/danimar/Downloads/NFe (5).xml', "r").read() | ||
| xml_element = etree.fromstring(xml_string) | ||
| oDanfe = danfe(list_xml=[xml_element]) | ||
| # Para testar localmente o Danfe | ||
| # with open('/home/danimar/danfe.pdf', 'w') as oFile: | ||
| with tempfile.TemporaryFile(mode="wb") as oFile: | ||
| oDanfe.writeto_pdf(oFile) |
| # -*- coding: utf-8 -*- | ||
| # © 2016 Danimar Ribeiro, Trustcode | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
| import os.path | ||
| import unittest | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfse.ginfes import consultar_situacao_lote | ||
| class test_nfse_ginfes(unittest.TestCase): | ||
| caminho = os.path.dirname(__file__) | ||
| @unittest.skip | ||
| def test_consulta_situacao_lote(self): | ||
| pfx_source = open("/home/danimar/Downloads/machado.pfx", "rb").read() | ||
| pfx = Certificado(pfx_source, "123456789") | ||
| dados = {"ambiente": "homologacao"} | ||
| retorno = consultar_situacao_lote(pfx, consulta=dados, ambiente="homologacao") | ||
| self.assertNotEqual(retorno["received_xml"], "") | ||
| self.assertEqual(retorno["object"].Cabecalho.Sucesso, True) |
| # coding=utf-8 | ||
| import unittest | ||
| from pytrustnfe.xml import render_xml, sanitize_response | ||
| from tests.const import NFSE, DEFAULT_RPS | ||
| template_path = 'pytrustnfe/nfse/paulistana/templates' | ||
| def _get_nfse(lista_rps): | ||
| nfse = NFSE | ||
| nfse['lista_rps'] = lista_rps | ||
| return nfse | ||
| def get_objects(nfse): | ||
| xml_rps = render_xml(template_path, 'EnvioRPS.xml', False, nfse=nfse) | ||
| _, obj_rps = sanitize_response(xml_rps) | ||
| xml_lote_rps = render_xml(template_path, 'EnvioLoteRPS.xml', False, nfse=nfse) | ||
| _, obj_lote_rps = sanitize_response(xml_lote_rps) | ||
| return obj_rps, obj_lote_rps | ||
| class test_nfse_paulistana_email_tomador(unittest.TestCase): | ||
| def test_rps_sem_email(self): | ||
| nfse = _get_nfse(DEFAULT_RPS) | ||
| obj_rps, obj_lote_rps = get_objects(nfse) | ||
| self.assertFalse(hasattr(obj_rps.RPS, 'EmailTomador')) | ||
| self.assertFalse(hasattr(obj_lote_rps.RPS, 'EmailTomador')) | ||
| # coding=utf-8 | ||
| import unittest | ||
| from pytrustnfe.xml import render_xml, sanitize_response | ||
| from tests.const import NFSE, DEFAULT_RPS | ||
| attrs = ['TipoLogradouro', 'Logradouro', 'NumeroEndereco', 'ComplementoEndereco', 'Bairro', 'CEP'] | ||
| template_path = 'pytrustnfe/nfse/paulistana/templates' | ||
| def _get_nfse(lista_rps): | ||
| nfse = NFSE | ||
| nfse['lista_rps'] = lista_rps | ||
| return nfse | ||
| def get_objects(nfse): | ||
| xml_rps = render_xml(template_path, 'EnvioRPS.xml', False, nfse=nfse) | ||
| _, obj_rps = sanitize_response(xml_rps) | ||
| xml_lote_rps = render_xml(template_path, 'EnvioLoteRPS.xml', False, nfse=nfse) | ||
| _, obj_lote_rps = sanitize_response(xml_lote_rps) | ||
| return obj_rps, obj_lote_rps | ||
| class test_nfse_paulistana_endereco_tomador(unittest.TestCase): | ||
| def test_rps_sem_cidade(self): | ||
| nfse = _get_nfse(DEFAULT_RPS) | ||
| obj_rps, obj_lote_rps = get_objects(nfse) | ||
| self.assertFalse(hasattr(obj_rps.RPS, 'EnderecoTomador')) | ||
| self.assertFalse(hasattr(obj_lote_rps.RPS, 'EnderecoTomador')) | ||
| def test_rps_sem_dados_endereco(self): | ||
| lista_rps = DEFAULT_RPS | ||
| for rps in lista_rps: | ||
| rps['tomador']['cidade'] = 'Florianópolis' | ||
| nfse = _get_nfse(lista_rps) | ||
| obj_rps, obj_lote_rps = get_objects(nfse) | ||
| self.assertTrue(hasattr(obj_rps.RPS, 'EnderecoTomador')) | ||
| self.assertTrue(hasattr(obj_lote_rps.RPS, 'EnderecoTomador')) | ||
| for attr in attrs: | ||
| self.assertFalse(hasattr(obj_rps.RPS.EnderecoTomador, attr)) | ||
| self.assertFalse(hasattr(obj_lote_rps.RPS.EnderecoTomador, attr)) |
| # coding=utf-8 | ||
| import os.path | ||
| import unittest | ||
| from pytrustnfe.xml import render_xml, sanitize_response | ||
| from tests.const import LOTE_RPS, NFSE | ||
| def _get_nfse(): | ||
| nfse = NFSE | ||
| nfse['lista_rps'] = LOTE_RPS | ||
| return nfse | ||
| class test_nfse_paulistana_para_lote(unittest.TestCase): | ||
| xml_path = os.path.join(os.path.dirname(__file__), 'XMLs') | ||
| template_path = 'pytrustnfe/nfse/paulistana/templates' | ||
| BATCH_SIZE = len(LOTE_RPS) | ||
| def test_envio_nfse(self): | ||
| nfse = _get_nfse() | ||
| xml_send = render_xml(self.template_path, 'EnvioLoteRPS.xml', False, nfse=nfse) | ||
| expected_xml = open(os.path.join(self.xml_path, 'xml_send_rps_batch_to_paulistana.xml'), 'r').read() | ||
| _, obj = sanitize_response(xml_send) | ||
| self.assertEqual(obj.Cabecalho.QtdRPS, self.BATCH_SIZE) | ||
| # f = open(os.path.join(self.xml_path, 'xml_send_rps_batch_to_paulistana.xml'), 'w') | ||
| # f.write(xml_send) | ||
| # f.close() | ||
| self.assertEqual(xml_send, expected_xml) |
| # coding=utf-8 | ||
| import os.path | ||
| import unittest | ||
| from pytrustnfe.xml import render_xml, sanitize_response | ||
| from tests.const import DEFAULT_RPS, NFSE | ||
| template_path = 'pytrustnfe/nfse/paulistana/templates' | ||
| def _get_nfse(tipo_cpfcnpj): | ||
| nfse = NFSE | ||
| lista_rps = DEFAULT_RPS | ||
| for rps in lista_rps: | ||
| rps['tomador']['tipo_cpfcnpj'] = tipo_cpfcnpj | ||
| rps['tomador']['cpf_cnpj'] = '12345678923256' | ||
| nfse['lista_rps'] = lista_rps | ||
| return nfse | ||
| def get_objects(nfse): | ||
| xml_rps = render_xml(template_path, 'EnvioRPS.xml', False, nfse=nfse) | ||
| _, obj_rps = sanitize_response(xml_rps) | ||
| xml_lote_rps = render_xml(template_path, 'EnvioLoteRPS.xml', False, nfse=nfse) | ||
| _, obj_lote_rps = sanitize_response(xml_lote_rps) | ||
| return obj_rps, obj_lote_rps | ||
| class test_nfse_paulistana_tipo_cpfcnpj(unittest.TestCase): | ||
| def test_tipo_cpfcnpj_1(self): | ||
| nfse = _get_nfse(tipo_cpfcnpj=1) | ||
| obj_rps, obj_lote_rps = get_objects(nfse) | ||
| self.assertTrue(hasattr(obj_rps.RPS, 'CPFCNPJTomador')) | ||
| self.assertTrue(hasattr(obj_rps.RPS.CPFCNPJTomador, 'CPF')) | ||
| self.assertTrue(hasattr(obj_lote_rps.RPS, 'CPFCNPJTomador')) | ||
| self.assertTrue(hasattr(obj_lote_rps.RPS.CPFCNPJTomador, 'CPF')) | ||
| def test_tipo_cpfcnpj_2(self): | ||
| nfse = _get_nfse(tipo_cpfcnpj=2) | ||
| obj_rps, obj_lote_rps = get_objects(nfse) | ||
| self.assertTrue(hasattr(obj_rps.RPS, 'CPFCNPJTomador')) | ||
| self.assertTrue(hasattr(obj_rps.RPS.CPFCNPJTomador, 'CNPJ')) | ||
| self.assertTrue(hasattr(obj_lote_rps.RPS, 'CPFCNPJTomador')) | ||
| self.assertTrue(hasattr(obj_lote_rps.RPS.CPFCNPJTomador, 'CNPJ')) | ||
| def test_tipo_cpfcnpj_3(self): | ||
| nfse = _get_nfse(tipo_cpfcnpj=3) | ||
| obj_rps, obj_lote_rps = get_objects(nfse) | ||
| self.assertFalse(hasattr(obj_rps.RPS, 'CPFCNPJTomador')) |
| # coding=utf-8 | ||
| import os.path | ||
| import unittest | ||
| from pytrustnfe.xml import render_xml, sanitize_response | ||
| from tests.const import DEFAULT_RPS, NFSE | ||
| default_values = { | ||
| 'TipoRPS': 'RPS', | ||
| 'TributacaoRPS': 'T', | ||
| 'ValorCOFINS': 0.0, | ||
| 'ValorINSS': 0.0, | ||
| 'ValorIR': 0.0, | ||
| 'ValorPIS': 0.0, | ||
| 'ValorCSLL': 0.0, | ||
| 'ISSRetido': False | ||
| } | ||
| attrs = ['TipoRPS', 'TributacaoRPS', 'ValorPIS', 'ValorCOFINS', 'ValorINSS', 'ValorIR', 'ValorCSLL', 'ISSRetido'] | ||
| def _get_nfse(): | ||
| nfse = NFSE | ||
| nfse['lista_rps'] = DEFAULT_RPS | ||
| return nfse | ||
| class test_nfse_paulistana_valores_default(unittest.TestCase): | ||
| template_path = 'pytrustnfe/nfse/paulistana/templates' | ||
| xml_path = os.path.join(os.path.dirname(__file__), 'XMLs') | ||
| nfse = _get_nfse() | ||
| def test_rps_sem_valores(self): | ||
| xml_rps = render_xml(self.template_path, 'EnvioRPS.xml', False, nfse=self.nfse) | ||
| _, obj = sanitize_response(xml_rps) | ||
| for attr in attrs: | ||
| self.assertEqual(getattr(obj.RPS, attr), default_values[attr]) | ||
| def test_lote_rps_sem_valores(self): | ||
| xml_lote_rps = render_xml(self.template_path, 'EnvioLoteRPS.xml', False, nfse=self.nfse) | ||
| _, obj = sanitize_response(xml_lote_rps) | ||
| for attr in attrs: | ||
| self.assertEqual(getattr(obj.RPS, attr), default_values[attr]) |
| # coding=utf-8 | ||
| from unittest import mock | ||
| import os.path | ||
| import unittest | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfse.paulistana import envio_lote_rps | ||
| from pytrustnfe.nfse.paulistana import cancelamento_nfe | ||
| class test_nfse_paulistana(unittest.TestCase): | ||
| caminho = os.path.dirname(__file__) | ||
| def _get_nfse(self): | ||
| rps = [ | ||
| { | ||
| "assinatura": "123", | ||
| "serie": "1", | ||
| "numero": "1", | ||
| "data_emissao": "2016-08-29", | ||
| "codigo_atividade": "07498", | ||
| "total_servicos": "2.00", | ||
| "total_deducoes": "3.00", | ||
| "prestador": {"inscricao_municipal": "123456"}, | ||
| "tomador": { | ||
| "tipo_cpfcnpj": "1", | ||
| "cpf_cnpj": "12345678923256", | ||
| "inscricao_municipal": "123456", | ||
| "razao_social": "Trustcode", | ||
| "tipo_logradouro": "1", | ||
| "logradouro": "Vinicius de Moraes, 42", | ||
| "numero": "42", | ||
| "bairro": "Corrego", | ||
| "cidade": "Floripa", | ||
| "uf": "SC", | ||
| "cep": "88037240", | ||
| }, | ||
| "codigo_atividade": "07498", | ||
| "aliquota_atividade": "5.00", | ||
| "descricao": "Venda de servico", | ||
| } | ||
| ] | ||
| nfse = { | ||
| "cpf_cnpj": "12345678901234", | ||
| "data_inicio": "2016-08-29", | ||
| "data_fim": "2016-08-29", | ||
| "lista_rps": rps, | ||
| } | ||
| return nfse | ||
| def test_envio_nfse(self): | ||
| pfx_source = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| pfx = Certificado(pfx_source, "123456") | ||
| nfse = self._get_nfse() | ||
| path = os.path.join(os.path.dirname(__file__), "XMLs") | ||
| xml_return = open(os.path.join(path, "paulistana_resultado.xml"), "r").read() | ||
| with mock.patch( | ||
| "pytrustnfe.nfse.paulistana.get_authenticated_client" | ||
| ) as client: | ||
| retorno = mock.MagicMock() | ||
| client.return_value = retorno | ||
| retorno.service.EnvioLoteRPS.return_value = xml_return | ||
| retorno = envio_lote_rps(pfx, nfse=nfse) | ||
| self.assertEqual(retorno["received_xml"], xml_return) | ||
| self.assertEqual(retorno["object"].Cabecalho.Sucesso, True) | ||
| self.assertEqual(retorno["object"].ChaveNFeRPS.ChaveNFe.NumeroNFe, 446) | ||
| self.assertEqual(retorno["object"].ChaveNFeRPS.ChaveRPS.NumeroRPS, 6) | ||
| def test_nfse_signature(self): | ||
| pfx_source = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| pfx = Certificado(pfx_source, "123456") | ||
| nfse = self._get_nfse() | ||
| path = os.path.join(os.path.dirname(__file__), "XMLs") | ||
| xml_sent = open(os.path.join(path, "paulistana_signature.xml"), "r").read() | ||
| with mock.patch( | ||
| "pytrustnfe.nfse.paulistana.get_authenticated_client" | ||
| ) as client: | ||
| retorno = mock.MagicMock() | ||
| client.return_value = retorno | ||
| retorno.service.EnvioLoteRPS.return_value = "<xml></xml>" | ||
| retorno = envio_lote_rps(pfx, nfse=nfse) | ||
| # f = open(os.path.join(path, "paulistana_signature.xml"), "w") | ||
| # f.write(retorno["sent_xml"]) | ||
| # f.close() | ||
| self.assertEqual(retorno["sent_xml"], xml_sent) | ||
| def _get_cancelamento(self): | ||
| return { | ||
| "cnpj_remetente": "123", | ||
| "assinatura": "assinatura", | ||
| "numero_nfse": "456", | ||
| "inscricao_municipal": "654", | ||
| "codigo_verificacao": "789", | ||
| } | ||
| def test_cancelamento_nfse_ok(self): | ||
| pfx_source = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| pfx = Certificado(pfx_source, "123456") | ||
| cancelamento = self._get_cancelamento() | ||
| path = os.path.join(os.path.dirname(__file__), "XMLs") | ||
| xml_return = open(os.path.join(path, "paulistana_canc_ok.xml"), "r").read() | ||
| with mock.patch( | ||
| "pytrustnfe.nfse.paulistana.get_authenticated_client" | ||
| ) as client: | ||
| retorno = mock.MagicMock() | ||
| client.return_value = retorno | ||
| retorno.service.CancelamentoNFe.return_value = xml_return | ||
| retorno = cancelamento_nfe(pfx, cancelamento=cancelamento) | ||
| self.assertEqual(retorno["received_xml"], xml_return) | ||
| self.assertEqual(retorno["object"].Cabecalho.Sucesso, True) | ||
| def test_cancelamento_nfse_com_erro(self): | ||
| pfx_source = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() | ||
| pfx = Certificado(pfx_source, "123456") | ||
| cancelamento = self._get_cancelamento() | ||
| path = os.path.join(os.path.dirname(__file__), "XMLs") | ||
| xml_return = open(os.path.join(path, "paulistana_canc_errado.xml"), "r").read() | ||
| with mock.patch( | ||
| "pytrustnfe.nfse.paulistana.get_authenticated_client" | ||
| ) as client: | ||
| retorno = mock.MagicMock() | ||
| client.return_value = retorno | ||
| retorno.service.CancelamentoNFe.return_value = xml_return | ||
| retorno = cancelamento_nfe(pfx, cancelamento=cancelamento) | ||
| self.assertEqual(retorno["received_xml"], xml_return) | ||
| self.assertEqual(retorno["object"].Cabecalho.Sucesso, False) | ||
| self.assertEqual(retorno["object"].Erro.ChaveNFe.NumeroNFe, 446) |
| # coding=utf-8 | ||
| """ | ||
| Created on Jun 14, 2015 | ||
| @author: danimar | ||
| """ | ||
| import unittest | ||
| from pytrustnfe.Servidores import localizar_url, localizar_qrcode | ||
| url_ba = "https://nfe.sefaz.ba.gov.br/webservices/NFeAutorizacao4/NFeAutoriza\ | ||
| cao4.asmx?wsdl" | ||
| url_sp = "https://nfe.fazenda.sp.gov.br/ws/nfeautorizacao4.asmx?wsdl" | ||
| url_qrcode_homologacao_sp = "https://homologacao.nfce.fazenda.sp.gov.br/NFCEConsultaPublica/Paginas/ConstultaQRCode.aspx" | ||
| url_sc = "https://nfe.svrs.rs.gov.br/ws/NfeAutorizacao/NFeAutorizacao4.asmx?wsdl" | ||
| url_rs = "https://nfe.sefazrs.rs.gov.br/ws/NfeAutorizacao/NFeAutorizacao4.asmx?wsdl" | ||
| url_cad_rs = "https://cad.sefazrs.rs.gov.br/ws/cadconsultacadastro/cadconsultacadastro4.asmx?wsdl" | ||
| url_cad_sc = "https://cad.svrs.rs.gov.br/ws/cadconsultacadastro/cadconsulta\ | ||
| cadastro4.asmx?wsdl" | ||
| class test_servidores(unittest.TestCase): | ||
| def test_localizar_url(self): | ||
| url = localizar_url("NfeAutorizacao", "29", ambiente=1) | ||
| self.assertEqual(url, url_ba) | ||
| url = localizar_url("NfeAutorizacao", "35", ambiente=1) | ||
| self.assertEqual(url, url_sp) | ||
| url = localizar_url("NfeAutorizacao", "42", ambiente=1) | ||
| self.assertEqual(url, url_sc) | ||
| url = localizar_url("NfeAutorizacao", "43", ambiente=1) | ||
| self.assertEqual(url, url_rs) | ||
| url = localizar_url("NfeConsultaCadastro", "43", ambiente=2) | ||
| self.assertEqual(url, url_cad_rs) | ||
| url = localizar_url("NfeConsultaCadastro", "42", ambiente=2) | ||
| self.assertEqual(url, url_cad_sc) | ||
| def test_localizar_qrcode(self): | ||
| url = localizar_qrcode("35") | ||
| self.assertEqual(url, url_qrcode_homologacao_sp) |
| # coding=utf-8 | ||
| """ | ||
| Created on Jun 16, 2015 | ||
| @author: danimar | ||
| """ | ||
| import unittest | ||
| import datetime | ||
| from pytrustnfe.utils import date_tostring, datetime_tostring, gerar_chave | ||
| from pytrustnfe.utils import ChaveNFe | ||
| class test_utils(unittest.TestCase): | ||
| kwargs = { | ||
| "cnpj": "33009911002506", | ||
| "estado": "52", | ||
| "emissao": "0604", | ||
| "modelo": "55", | ||
| "serie": "012", | ||
| "numero": 780, | ||
| "tipo": 0, | ||
| "codigo": "26730161", | ||
| } | ||
| def test_date_tostring(self): | ||
| hoje = datetime.date.today() | ||
| data = date_tostring(hoje) | ||
| self.assertEqual(data, hoje.strftime("%d-%m-%y"), "Não convertido corretamente") | ||
| self.assertRaises(Exception, date_tostring, "Not a date") | ||
| def test_datetime_tostring(self): | ||
| hoje = datetime.datetime.now() | ||
| data = datetime_tostring(hoje) | ||
| self.assertEqual( | ||
| data, hoje.strftime("%d-%m-%y %H:%M:%S"), "Não convertido corretamente" | ||
| ) | ||
| self.assertRaises(Exception, datetime_tostring, "Not a date") | ||
| def test_geracao_chave(self): | ||
| chave = ChaveNFe(**self.kwargs) | ||
| str_chave = gerar_chave(chave) | ||
| chave_correta = "52060433009911002506550120000007800267301615" | ||
| self.assertEqual(str_chave, chave_correta, "Geração de chave nf-e incorreta") | ||
| str_chave = gerar_chave(chave, prefix="NFe") | ||
| chave_correta = "NFe52060433009911002506550120000007800267301615" | ||
| self.assertEqual( | ||
| str_chave, chave_correta, "Geração de chave nf-e com prefixo incorreta" | ||
| ) | ||
| self.assertRaises(Exception, gerar_chave, "Not a ChaveNFe object") | ||
| self.assertRaises(Exception, gerar_chave, "Not a ChaveNFe object") | ||
| def test_chave_nfe(self): | ||
| chave = ChaveNFe(**self.kwargs) | ||
| with self.assertRaises(AssertionError) as cm: | ||
| chave.cnpj = "" | ||
| chave.validar() | ||
| chave.cnpj = "1234567891011" | ||
| self.assertEqual( | ||
| "CNPJ necessário para criar chave NF-e", | ||
| str(cm.exception), | ||
| "Validação da chave nf-e incorreta", | ||
| ) | ||
| with self.assertRaises(AssertionError) as cm: | ||
| chave.estado = "" | ||
| chave.validar() | ||
| chave.estado = "42" | ||
| self.assertEqual( | ||
| "Estado necessário para criar chave NF-e", | ||
| str(cm.exception), | ||
| "Validação da chave nf-e incorreta", | ||
| ) | ||
| with self.assertRaises(AssertionError) as cm: | ||
| chave.emissao = "" | ||
| chave.validar() | ||
| chave.emissao = "0" | ||
| self.assertEqual( | ||
| "Emissão necessário para criar chave NF-e", | ||
| str(cm.exception), | ||
| "Validação da chave nf-e incorreta", | ||
| ) | ||
| with self.assertRaises(AssertionError) as cm: | ||
| chave.modelo = "" | ||
| chave.validar() | ||
| chave.modelo = "55" | ||
| self.assertEqual( | ||
| "Modelo necessário para criar chave NF-e", | ||
| str(cm.exception), | ||
| "Validação da chave nf-e incorreta", | ||
| ) | ||
| with self.assertRaises(AssertionError) as cm: | ||
| chave.serie = "" | ||
| chave.validar() | ||
| chave.serie = "012" | ||
| self.assertEqual( | ||
| "Série necessária para criar chave NF-e", | ||
| str(cm.exception), | ||
| "Validação da chave nf-e incorreta", | ||
| ) | ||
| with self.assertRaises(AssertionError) as cm: | ||
| chave.numero = "" | ||
| chave.validar() | ||
| chave.numero = "000000780" | ||
| self.assertEqual( | ||
| "Número necessário para criar chave NF-e", | ||
| str(cm.exception), | ||
| "Validação da chave nf-e incorreta", | ||
| ) | ||
| with self.assertRaises(AssertionError) as cm: | ||
| chave.tipo = "" | ||
| chave.validar() | ||
| chave.tipo = "42" | ||
| self.assertEqual( | ||
| "Tipo necessário para criar chave NF-e", | ||
| str(cm.exception), | ||
| "Validação da chave nf-e incorreta", | ||
| ) | ||
| with self.assertRaises(AssertionError) as cm: | ||
| chave.codigo = "" | ||
| chave.validar() | ||
| self.assertEqual( | ||
| "Código necessário para criar chave NF-e", | ||
| str(cm.exception), | ||
| "Validação da chave nf-e incorreta", | ||
| ) |
| # coding=utf-8 | ||
| import os.path | ||
| import unittest | ||
| from lxml import etree | ||
| from pytrustnfe.xml import render_xml | ||
| from pytrustnfe.xml import sanitize_response | ||
| class test_xml_serializacao(unittest.TestCase): | ||
| def test_serializacao_default(self): | ||
| path = os.path.join(os.path.dirname(__file__), "XMLs") | ||
| xml = render_xml( | ||
| path, "jinja_template.xml", False, tag1="oi", tag2="ola", tag3="comovai" | ||
| ) | ||
| result = open(os.path.join(path, "jinja_result.xml"), "r").read() | ||
| self.assertEqual(xml + "\n", result) | ||
| def test_serializacao_remove_empty(self): | ||
| path = os.path.join(os.path.dirname(__file__), "XMLs") | ||
| xmlElem = render_xml( | ||
| path, "jinja_template.xml", True, tag1="oi", tag2="ola", tag3="comovai" | ||
| ) | ||
| xml = etree.tostring(xmlElem, encoding=str) | ||
| result = open(os.path.join(path, "jinja_remove_empty.xml"), "r").read() | ||
| self.assertEqual(xml + "\n", result) | ||
| def test_sanitize_response(self): | ||
| path = os.path.join(os.path.dirname(__file__), "XMLs") | ||
| xml_to_clear = open(os.path.join(path, "jinja_result.xml"), "r").read() | ||
| xml, obj = sanitize_response(xml_to_clear) | ||
| self.assertEqual(xml, xml_to_clear) | ||
| self.assertEqual(obj.tpAmb, "oi") | ||
| self.assertEqual(obj.CNPJ, "ola") | ||
| self.assertEqual(obj.indNFe, "") | ||
| self.assertEqual(obj.indEmi, "comovai") |
| # coding=utf-8 | ||
| """ | ||
| Created on Jun 14, 2015 | ||
| @author: danimar | ||
| """ | ||
| import unittest | ||
| from datetime import datetime | ||
| from pytrustnfe.xml.filters import normalize_str | ||
| from pytrustnfe.xml.filters import strip_line_feed | ||
| from pytrustnfe.xml.filters import format_percent | ||
| from pytrustnfe.xml.filters import format_date | ||
| from pytrustnfe.xml.filters import format_datetime | ||
| class test_xmlfilters(unittest.TestCase): | ||
| def test_xmlfilters(self): | ||
| word = normalize_str("ação café pó pá veêm") | ||
| self.assertEqual(word, "acao cafe po pa veem") | ||
| self.assertEqual(1.5, format_percent(150)) | ||
| self.assertEqual("aa", format_date("aa")) | ||
| self.assertEqual("aa", format_datetime("aa")) | ||
| dt = datetime(2016, 9, 17, 12, 12, 12) | ||
| self.assertEqual("2016-09-17", format_date(dt.date())) | ||
| self.assertEqual("2016-09-17T12:12:12", format_datetime(dt)) | ||
| word = strip_line_feed("olá\ncomo vai\r senhor ") | ||
| self.assertEqual(word, "olá como vai senhor") |
@@ -23,3 +23,3 @@ # -*- coding: utf-8 -*- | ||
| def extract_cert_and_key_from_pfx(pfx, password): | ||
| pfx = crypto.load_pkcs12(pfx, password) | ||
| pfx = crypto.load_pkcs12(pfx, password.encode()) | ||
| # PEM formatted private key | ||
@@ -26,0 +26,0 @@ key = crypto.dump_privatekey(crypto.FILETYPE_PEM, pfx.get_privatekey()) |
@@ -71,112 +71,2 @@ # -*- coding: utf-8 -*- | ||
| def gerar_qrcode(id_csc: int, csc: str, xml_send: str, cert = False) -> str: | ||
| xml = etree.fromstring(xml_send) | ||
| signature = xml.find( | ||
| ".//{http://www.w3.org/2000/09/xmldsig#}Signature") | ||
| id = xml.find( | ||
| ".//{http://www.portalfiscal.inf.br/nfe}infNFe").get('Id') | ||
| if id is None: | ||
| raise Exception("XML Invalido - Sem o ID") | ||
| chave = id.replace('NFe', '') | ||
| emit_uf = chave[:2] | ||
| tp_amb = xml.find(".//{http://www.portalfiscal.inf.br/nfe}tpAmb") | ||
| if tp_amb is None: | ||
| raise Exception("XML Invalido - Sem o tipo de ambiente") | ||
| dh_emi = xml.find(".//{http://www.portalfiscal.inf.br/nfe}dhEmi") | ||
| if dh_emi is None: | ||
| raise Exception("XML Invalido - Sem data de Emissao") | ||
| dh_emi = dh_emi.text.split("-")[2].split("T")[0] | ||
| tp_emis = xml.find(".//{http://www.portalfiscal.inf.br/nfe}tpEmis") | ||
| if tp_emis is None: | ||
| raise Exception("XML Invalido - Sem tipo de emissao") | ||
| v_nf = xml.find(".//{http://www.portalfiscal.inf.br/nfe}vNF") | ||
| if v_nf is None: | ||
| raise Exception("XML Invalido - Sem o valor da NFe") | ||
| url_qrcode_str = url_qrcode( | ||
| estado=emit_uf, | ||
| ambiente=tp_amb.text) | ||
| url_qrcode_exibicao_str = url_qrcode_exibicao( | ||
| estado=emit_uf, | ||
| ambiente=tp_amb.text) | ||
| if tp_emis != 1: | ||
| if signature is None: | ||
| if cert is not False: | ||
| signer = Assinatura(certificado.pfx, certificado.password) | ||
| xml_send = signer.assina_xml(xmlElem_send, id) | ||
| else: | ||
| raise Exception("XML Invalido - Sem assinatura e não " | ||
| "foi enviado o certificado nos parametros") | ||
| digest_value = xml.find( | ||
| ".//{http://www.w3.org/2000/09/xmldsig#}DigestValue") | ||
| c_hash_qr_code = \ | ||
| "{ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \ | ||
| "{v_nf}|{dig_val}|{id_csc}|{csc}".format( | ||
| ch_acesso=chave, | ||
| versao=2, | ||
| tp_amb=tp_amb.text, | ||
| dh_emi=dh_emi, | ||
| v_nf=float(v_nf.text), | ||
| dig_val=digest_value.text, | ||
| id_csc=int(id_csc), | ||
| csc=csc | ||
| ) | ||
| c_hash_qr_code = hashlib.sha1(c_hash_qr_code.encode()). \ | ||
| hexdigest() | ||
| qr_code_url = 'p={ch_acesso}|{versao}|{tp_amb}|{dh_emi}|" \ | ||
| "{v_nf}|{dig_val}|{id_csc}|{hash}'.format( | ||
| ch_acesso=chave, | ||
| versao=2, | ||
| tp_amb=tp_amb.text, | ||
| dh_emi=dh_emi, | ||
| v_nf=float(v_nf.text), | ||
| dig_val=digest_value.text, | ||
| id_csc=int(id_csc), | ||
| hash=c_hash_qr_code | ||
| ) | ||
| qrcode = url_qrcode_str + qr_code_url | ||
| url_consulta = url_qrcode_exibicao_str | ||
| qrCode = xml.find( | ||
| './/{http://www.portalfiscal.inf.br/nfe}qrCode').text = \ | ||
| qrcode | ||
| urlChave = xml.find( | ||
| './/{http://www.portalfiscal.inf.br/nfe}urlChave').text = \ | ||
| url_consulta | ||
| else: | ||
| c_hash_qr_code = \ | ||
| "{ch_acesso}|{versao}|{tp_amb}|{id_csc}|{csc}".format( | ||
| ch_acesso=chave, | ||
| versao=2, | ||
| tp_amb=tp_amb.text, | ||
| id_csc=int(id_csc), | ||
| csc=csc | ||
| ) | ||
| c_hash_qr_code = hashlib.sha1(c_hash_qr_code.encode()).hexdigest() | ||
| qr_code_url = "p={ch_acesso}|{versao}|{tp_amb}|{id_csc}|" \ | ||
| "{hash}".\ | ||
| format( | ||
| ch_acesso=chave, | ||
| versao=2, | ||
| tp_amb=tp_amb.text, | ||
| id_csc=int(id_csc), | ||
| hash=c_hash_qr_code | ||
| ) | ||
| qrcode = url_qrcode_str + qr_code_url | ||
| url_consulta = url_qrcode_exibicao_str | ||
| qrCode = xml.find( | ||
| './/{http://www.portalfiscal.inf.br/nfe}qrCode').text = \ | ||
| qrcode | ||
| urlChave = xml.find( | ||
| './/{http://www.portalfiscal.inf.br/nfe}urlChave').text = \ | ||
| url_consulta | ||
| return etree.tostring(xml) | ||
| def _get_session(certificado): | ||
@@ -183,0 +73,0 @@ cert, key = extract_cert_and_key_from_pfx(certificado.pfx, certificado.password) |
@@ -11,2 +11,7 @@ # -*- coding: utf-8 -*- | ||
| class XMLSignerWithSHA1(XMLSigner): | ||
| def check_deprecated_methods(self): | ||
| pass | ||
| class Assinatura(object): | ||
@@ -24,3 +29,3 @@ def __init__(self, arquivo, senha): | ||
| signer = XMLSigner( | ||
| signer = XMLSignerWithSHA1( | ||
| method=signxml.methods.enveloped, | ||
@@ -35,2 +40,3 @@ signature_algorithm="rsa-sha1", | ||
| signer.namespaces = ns | ||
| signer.excise_empty_xmlns_declarations = True | ||
@@ -37,0 +43,0 @@ ref_uri = ("#%s" % reference) if reference else None |
@@ -87,5 +87,3 @@ # -*- coding: utf-8 -*- | ||
| if cNumber: | ||
| # Vírgula para a separação de milhar e 2f para 2 casas decimais | ||
| cNumber = "{:,.2f}".format(float(cNumber)) | ||
| return cNumber.replace(",", "X").replace(".", ",").replace("X", ".") | ||
| return cNumber.replace(",", "X").replace("X", ".").replace(".", ",") | ||
| return "" | ||
@@ -92,0 +90,0 @@ |
@@ -16,10 +16,10 @@ # -*- coding: utf-8 -*- | ||
| def sign_tag(certificado, **kwargs): | ||
| pkcs12 = crypto.load_pkcs12(certificado.pfx, certificado.password) | ||
| pkcs12 = crypto.load_pkcs12(certificado.pfx, certificado.password.encode()) | ||
| key = pkcs12.get_privatekey() | ||
| if "nfse" in kwargs: | ||
| for item in kwargs["nfse"]["lista_rps"]: | ||
| signed = crypto.sign(key, item["assinatura"], "SHA1") | ||
| signed = crypto.sign(key, item["assinatura"].encode(), "SHA1") | ||
| item["assinatura"] = b64encode(signed).decode() | ||
| if "cancelamento" in kwargs: | ||
| signed = crypto.sign(key, kwargs["cancelamento"]["assinatura"], "SHA1") | ||
| signed = crypto.sign(key, kwargs["cancelamento"]["assinatura"].encode(), "SHA1") | ||
| kwargs["cancelamento"]["assinatura"] = b64encode(signed).decode() | ||
@@ -26,0 +26,0 @@ |
@@ -20,4 +20,3 @@ # -*- coding: utf-8 -*- | ||
| nfe = recursively_normalize(nfe) | ||
| env = Environment(loader=FileSystemLoader( | ||
| path), extensions=["jinja2.ext.with_"]) | ||
| env = Environment(loader=FileSystemLoader(path)) | ||
| env.filters["normalize"] = filters.strip_line_feed | ||
@@ -24,0 +23,0 @@ env.filters["normalize_str"] = filters.normalize_str |
-282
| Metadata-Version: 2.1 | ||
| Name: pytrustnfe3 | ||
| Version: 1.0.61 | ||
| Summary: PyTrustNFe é uma biblioteca para envio de NF-e | ||
| Home-page: https://github.com/danimaribeiro/PyTrustNFe | ||
| Author: Danimar Ribeiro | ||
| Author-email: danimaribeiro@gmail.com | ||
| License: LGPL-v2.1+ | ||
| Keywords: nfe,mdf-e | ||
| Platform: UNKNOWN | ||
| Classifier: Development Status :: 5 - Production/Stable | ||
| Classifier: Environment :: Plugins | ||
| Classifier: Intended Audience :: Developers | ||
| Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+) | ||
| Classifier: Operating System :: OS Independent | ||
| Classifier: Programming Language :: Python | ||
| Classifier: Programming Language :: Python :: 3.6 | ||
| Classifier: Programming Language :: Python :: 3.5 | ||
| Classifier: Programming Language :: Python :: 3.4 | ||
| Classifier: Topic :: Software Development :: Libraries :: Python Modules | ||
| Description-Content-Type: text/markdown | ||
| License-File: LICENSE.txt | ||
| Requires-Dist: urllib3 (>=1.22) | ||
| Requires-Dist: xmlsec (>=1.3.3) | ||
| Requires-Dist: Jinja2 (>=2.8) | ||
| Requires-Dist: pyOpenSSL (<18,>=16.0.0) | ||
| Requires-Dist: signxml (>=2.4.0) | ||
| Requires-Dist: lxml (<5,>=3.5.0) | ||
| Requires-Dist: suds-jurko (>=0.6) | ||
| Requires-Dist: suds-jurko-requests (>=1.2) | ||
| Requires-Dist: reportlab | ||
| Requires-Dist: pytz | ||
| Requires-Dist: zeep | ||
| # PyTrustNFe | ||
| Biblioteca Python que tem por objetivo enviar NFe, NFCe e NFSe no Brasil | ||
| [](https://coveralls.io/r/danimaribeiro/PyTrustNFe?branch=master3) | ||
| [](https://travis-ci.org/danimaribeiro/PyTrustNFe) | ||
| [](https://badge.fury.io/py/PyTrustNFe3) | ||
| Pacotes necessários para instalação: | ||
| ```apt-get install --no-install-recommends python3-pip python3-wheel python3-setuptools python3-openssl python3-lxml``` | ||
| Dependências: | ||
| * PyXmlSec | ||
| * lxml | ||
| * signxml | ||
| * suds-jurko | ||
| * suds-jurko-requests | ||
| * reportlab | ||
| * Jinja2 | ||
| NFSe - Cidades atendidas | ||
| ----------------------------- | ||
| * **Paulistana** - São Paulo/SP | ||
| * **Nota Carioca** - Rio de Janeiro/RJ | ||
| * **Imperial** - Petrópolis/RH | ||
| * **Goiânia** - Goiânia/GO | ||
| * [Susesu](cidades/susesu.md) - 3 cidades atendidas | ||
| * [Simpliss](cidades/simpliss.md) - 18 cidade atendidas | ||
| * [GINFES](cidades/ginfes.md) - 79 cidades atendidas | ||
| * [DSF](cidades/dsf.md) - 7 cidades atendidas | ||
| Roadmap | ||
| -------------- | ||
| Teste unitários | ||
| Implementar novos provedores de NFSe | ||
| * [Betha](cidades/betha.md) - 81 cidades atendidas WIP | ||
| * [WebISS](cidades/webiss.md) - 51 cidades atendidas | ||
| * [ISSIntel](cidades/issintel.md) - 32 cidades atendidas | ||
| * [ISSNET](cidades/issnet.md) - 32 cidades atendidas | ||
| * [Saatri](cidades/saatri.md) - 31 cidades atendidas | ||
| Exemplos de uso da NFe | ||
| ----------------------------- | ||
| Consulta Cadastro por CNPJ: | ||
| ```python | ||
| from pytrustnfe.nfe import consulta_cadastro | ||
| from pytrustnfe.certificado import Certificado | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| obj = {'cnpj': '12345678901234', 'estado': '42'} | ||
| resposta = consulta_cadastro(certificado, obj=obj, ambiente=1, estado='42') | ||
| ``` | ||
| Consulta Distribuição NF-e sem Validação de Esquema: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| # Gerando xml e enviado consulta por Ultimo NSU | ||
| response1 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| ultimo_nsu='123456789101213' | ||
| ) | ||
| # Gerando xml e enviado consulta por Chave | ||
| response2 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| chave_nfe='012345678901234567890123456789012345678912' | ||
| ) | ||
| # Gerando xml e enviado consulta por NSU | ||
| response3 = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| cnpj_cpf='12345678901234', | ||
| nsu='123456789101213' | ||
| ) | ||
| ``` | ||
| Consulta Distribuição NF-e com Validação de Esquema: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe | ||
| from pytrustnfe.xml.validate import valida_nfe, SCHEMA_DFE | ||
| certificado = open("/path/certificado.pfx", "r").read() | ||
| certificado = Certificado(certificado, 'senha_pfx') | ||
| # Gerando XML para Consulta por Ultimo NSU | ||
| xml1 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| ultimo_nsu='123456789101213' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml1, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Gerando XML para Consulta por Chave | ||
| xml2 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| chave_nfe='012345678901234567890123456789012345678912' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml2, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Gerando XML para Consulta por NSU | ||
| xml3 = xml_consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| cnpj_cpf='12345678901234', | ||
| nsu='123456789101213' | ||
| ) | ||
| # Validando o XML com Esquema | ||
| if valida_nfe(xml3, SCHEMA_DFE): | ||
| Warning("Erro na validação do esquema") | ||
| # Enviando xml de consulta para sefaz | ||
| response = consulta_distribuicao_nfe( | ||
| certificado, | ||
| ambiente=1, | ||
| estado='42', | ||
| modelo='55', | ||
| xml=xml1 | ||
| ) | ||
| ``` | ||
| Exemplo de uso da NFSe Paulistana | ||
| --------------------------------- | ||
| Envio de RPS por lote | ||
| ```python | ||
| certificado = open('/path/certificado.pfx', 'r').read() | ||
| certificado = Certificado(certificado, '123456') | ||
| # Necessário criar um dicionário com os dados, validação dos dados deve | ||
| # ser feita pela aplicação que está utilizando a lib | ||
| rps = [ | ||
| { | ||
| 'assinatura': '123', | ||
| 'serie': '1', | ||
| 'numero': '1', | ||
| 'data_emissao': '2016-08-29', | ||
| 'codigo_atividade': '07498', | ||
| 'valor_servico': '2.00', | ||
| 'valor_deducao': '3.00', | ||
| 'prestador': { | ||
| 'inscricao_municipal': '123456' | ||
| }, | ||
| 'tomador': { | ||
| 'tipo_cpfcnpj': '1', | ||
| 'cpf_cnpj': '12345678923256', | ||
| 'inscricao_municipal': '123456', | ||
| 'razao_social': 'Trustcode', | ||
| 'tipo_logradouro': '1', | ||
| 'logradouro': 'Vinicius de Moraes, 42', | ||
| 'numero': '42', | ||
| 'bairro': 'Corrego', | ||
| 'cidade': '4205407', # Código da cidade, de acordo com o IBGE | ||
| 'uf': 'SC', | ||
| 'cep': '88037240', | ||
| }, | ||
| 'codigo_atividade': '07498', | ||
| 'aliquota_atividade': '5.00', | ||
| 'descricao': 'Venda de servico' | ||
| } | ||
| ] | ||
| nfse = { | ||
| 'cpf_cnpj': '12345678901234', | ||
| 'data_inicio': '2016-08-29', | ||
| 'data_fim': '2016-08-29', | ||
| 'total_servicos': '2.00', | ||
| 'total_deducoes': '3.00', | ||
| 'lista_rps': rps | ||
| } | ||
| retorno = envio_lote_rps(certificado, nfse=nfse) | ||
| # retorno é um dicionário { 'received_xml':'', 'sent_xml':'', 'object': object() } | ||
| print retorno['received_xml'] | ||
| print retorno['sent_xml'] | ||
| # retorno['object'] é um objeto python criado apartir do xml de resposta | ||
| print retorno['object'].Cabecalho.Sucesso | ||
| print retorno['object'].ChaveNFeRPS.ChaveNFe.NumeroNFe | ||
| print retorno['object'].ChaveNFeRPS.ChaveRPS.NumeroRPS | ||
| ``` | ||
| Cancelamento de NFSe: | ||
| ```python | ||
| from pytrustnfe.certificado import Certificado | ||
| from pytrustnfe.nfse.paulistana import cancelamento_nfe | ||
| certificado = open('/path/certificado.pfx', 'r').read() | ||
| certificado = Certificado(certificado, '123456') | ||
| cancelamento = { | ||
| 'cnpj_remetente': '123', | ||
| 'assinatura': 'assinatura', | ||
| 'numero_nfse': '456', | ||
| 'inscricao_municipal': '654', | ||
| 'codigo_verificacao': '789', | ||
| } | ||
| retorno = cancelamento_nfe(certificado, cancelamento=cancelamento) | ||
| # retorno é um dicionário { 'received_xml':'', 'sent_xml':'', 'object': object() } | ||
| print retorno['received_xml'] | ||
| print retorno['sent_xml'] | ||
| # retorno['object'] é um objeto python criado apartir do xml de resposta | ||
| print retorno['object'].Cabecalho.Sucesso | ||
| if not retorno['object'].Cabecalho.Sucesso: # Cancelamento com erro | ||
| print retorno['object'].Erro.Codigo | ||
| print retorno['object'].Erro.Descricao | ||
| ``` | ||
-123
| pytrustnfe/Servidores.py,sha256=_bW07oVRc7TCCyf9VPvKUGTdD5OTdrhSS2fr9K23ibc,34097 | ||
| pytrustnfe/__init__.py,sha256=etnl5dN3OB1v-PamGFNV_HAbfpNYhJdi3_C6KMnwkbA,614 | ||
| pytrustnfe/certificado.py,sha256=1LECyV2HVFazSdkp5DMO0DBkSCYlXEpMjLHScJmL4y8,1143 | ||
| pytrustnfe/client.py,sha256=9buGWt-DZuwpiCpWPXOdk88aQNsYn88agBhXNnKMtlc,796 | ||
| pytrustnfe/exceptions.py,sha256=pLTdmhWVzjKCDq-Bb9ZgAOw-IwB0Cgt4N_X-U80cg0k,460 | ||
| pytrustnfe/urls.py,sha256=w1MglPKCtCbk_aZ_c5iA0pdZLHXBPGZicnqsBXW98oY,6384 | ||
| pytrustnfe/utils.py,sha256=17s_usf_ffb6OtZzsBuOyrkcNwhvafCp5Pxbs19kUl0,3484 | ||
| pytrustnfe/nfe/__init__.py,sha256=XYs8lRLxAUv6XTTxGlA0bPkFH77Qg65cW_vwrapZiYE,13459 | ||
| pytrustnfe/nfe/assinatura.py,sha256=jFRCTkF9YpVCAp9ZpL77lWWo-3fNFIr3RAnIdFcigMk,1837 | ||
| pytrustnfe/nfe/danfce.py,sha256=wW7wxIbTjTS0Ia5nSfcDcpcg930YgXw2KBkLLT6U2gA,18885 | ||
| pytrustnfe/nfe/danfe.py,sha256=RSyHWg2JeHRHUpJIwG-X1gtQqtoU7sLtoXypFO7Xrh4,50447 | ||
| pytrustnfe/nfe/patch.py,sha256=yMC3vm3xhwU8QrkHjw6RKAD_J3u_yDVdvh_318PCRmc,1264 | ||
| pytrustnfe/nfe/fonts/NimbusSanL Bold.ttf,sha256=pHC8_hfQdjtVOMBtuqb0pRrkMcqlu-fVidZ7M13uI18,49840 | ||
| pytrustnfe/nfe/fonts/NimbusSanL Regular.ttf,sha256=2CuNtw9sjCF2axmG-7PVAMqYK1KeGb6Wf4AU-sFAlu0,48304 | ||
| pytrustnfe/nfe/templates/NFeDistribuicaoDFe.xml,sha256=zkXTR1ZgHdMzWbjrenN0wb088_zCF_7sX7ACRs6gRaM,389 | ||
| pytrustnfe/nfe/templates/NfeAutorizacao.xml,sha256=40POldey7rg4CodK5sOP7ZCzLHqrL0eLAGf8ExKL1qs,51983 | ||
| pytrustnfe/nfe/templates/NfeConsultaCadastro.xml,sha256=GK6gLNzKBn1_742j0Ey0lbfnlQRo9NiHvYx4IpQVe1A,201 | ||
| pytrustnfe/nfe/templates/NfeConsultaDest.xml,sha256=AU_ufUN-aXhqy4nNtfAJnaf02pB65lLzSvj9fDiij9M,338 | ||
| pytrustnfe/nfe/templates/NfeConsultaProtocolo.xml,sha256=v0Bb5_uxWxcHMUeTgYCnVs8QKfCqK0Q-VUbXLNwJxRo,187 | ||
| pytrustnfe/nfe/templates/NfeInutilizacao.xml,sha256=ETcVpj4IeCMF3HuJVhCxDd9-d674hi_Z_hibnkZiK-Y,496 | ||
| pytrustnfe/nfe/templates/NfeRetAutorizacao.xml,sha256=JeMfuFozeuBKxrNcnZ6GRypl3Sp8TaZhENaAOhlAjDo,165 | ||
| pytrustnfe/nfe/templates/NfeStatusServico.xml,sha256=XoPGeRUvsN4z9QjoQFmD6W7iLrQwYbswj-q6N1hErt0,221 | ||
| pytrustnfe/nfe/templates/RecepcaoEvento.xml,sha256=yI0tQr9PAiqk9ZkVgPU9gtln0FuYE37so1CrjEpPHxE,971 | ||
| pytrustnfe/nfe/templates/RecepcaoEventoManifesto.xml,sha256=v0qbsuw101FjacA4tNhS8iQP30ELYDb8JiVIpqd1ZXw,787 | ||
| pytrustnfe/nfse/__init__.py,sha256=SEVyX-ZdaSpG7l5hRjjGxOm1ENc4Uorzio6hKBd7m80,130 | ||
| pytrustnfe/nfse/assinatura.py,sha256=bS7p0ufBDzShXZynDtl-niwd83ngtN-67KdXf87JuRM,1697 | ||
| pytrustnfe/nfse/aparecida/__init__.py,sha256=Pi7ZR6OOcjIk3yrNXhSoEcrl93B_AiVXs3PtpXQMk8E,2564 | ||
| pytrustnfe/nfse/aparecida/templates/Rps.xml,sha256=vNfzp7KLNvNl8DICqrze46dyL6-NpLEen7eZJKld5PU,4583 | ||
| pytrustnfe/nfse/aparecida/templates/cancelarNfse.xml,sha256=u4GfKWoqVk_MksiRlhu6TeyznwDzuI1myNgKPpSNAsM,703 | ||
| pytrustnfe/nfse/aparecida/templates/consultarLoteRps.xml,sha256=ZUGuOykpsRRRXc__4B0ePizGTklMXU6eXnb8ABHPSpo,310 | ||
| pytrustnfe/nfse/aparecida/templates/recepcionarLoteRps.xml,sha256=a-0PksD5KrJIXn0EWF4PRgxU2CTiKs_8oqbJ6SVzmxY,499 | ||
| pytrustnfe/nfse/betha/__init__.py,sha256=FiXf_2GWr2jXaXp9B1qNA4ZhF_D0Z_4pUB6NbPPeX80,3600 | ||
| pytrustnfe/nfse/betha/templates/CancelarNfse.xml,sha256=V4DNgPFITxs-6VGORVXVi8tYp1leJihpl78M6DojrmI,592 | ||
| pytrustnfe/nfse/betha/templates/ConsultarLoteRps.xml,sha256=KblM-QOB_X6MsGIydGqN30rs8gkzlOsZ7437HNJi6TA,265 | ||
| pytrustnfe/nfse/betha/templates/ConsultarNfseFaixa.xml,sha256=tn7nRaOPtrUQjC79HN1AiQnN8-sAFlsu9dmE_KWu0fY,431 | ||
| pytrustnfe/nfse/betha/templates/ConsultarNfsePorRps.xml,sha256=q__O-xZCCbfevdjlfBye9f-KmDSx0b4QJdaowB4XxJo,407 | ||
| pytrustnfe/nfse/betha/templates/ConsultarNfseServicoPrestado.xml,sha256=kkkO5aiVgxELB5H-wTfmmEBdI4AzTr8_tD4Cg-j82pM,437 | ||
| pytrustnfe/nfse/betha/templates/ConsultarNfseServicoTomado.xml,sha256=Y4zHH_6_VxViMWhg5GuzlVZ_JNR9ZxacXU4iXHpN7W8,751 | ||
| pytrustnfe/nfse/betha/templates/GerarNfse.xml,sha256=JWxe0Qqjd0ACN2tdZrhHGFuMTRy6907MqUlgmgnUhVw,123 | ||
| pytrustnfe/nfse/betha/templates/RecepcionarLoteRps.xml,sha256=lcalAEmhTdYblpkuyliCGIztGh5BmglOlUKCFudDlzY,458 | ||
| pytrustnfe/nfse/betha/templates/RecepcionarLoteRpsSincrono.xml,sha256=ufKDyFMGqd9-4FC1dqYpIS0lDQiEgpmykN16m6VbGgA,474 | ||
| pytrustnfe/nfse/betha/templates/Rps.xml,sha256=My32IWTSbCW05FKVZGQAVB73xCyV8sxuA3-OqfI9WjA,2998 | ||
| pytrustnfe/nfse/betha/templates/SubstituirNfse.xml,sha256=FPiHrVNU-BeeFJybivuAaJDBC1yt_I8jlBYXLBn_u_w,746 | ||
| pytrustnfe/nfse/bh/__init__.py,sha256=i4KGXQyniGG7gxuPk6PTeEvHnxSh8bonbO07PDaQLAA,2709 | ||
| pytrustnfe/nfse/bh/assinatura.py,sha256=wQQMZnIjjjz-7W4meocp8_IqKSIyMUD21k4mXNZHVeM,1644 | ||
| pytrustnfe/nfse/bh/templates/CancelarNfse.xml,sha256=EG0wEafAoVGPcoKCRpQCTTlzcXMeQL6nUy43ogcbzBM,692 | ||
| pytrustnfe/nfse/bh/templates/GerarNfse.xml,sha256=GAZC5QGaR00q2nzgOC5sHsUeR-juAAOzkND1MFnUWBw,499 | ||
| pytrustnfe/nfse/bh/templates/Rps.xml,sha256=VkPEifWA_GS4iK51NuYoPeUAtuXLuxf3zBTfLirv8QM,4626 | ||
| pytrustnfe/nfse/carioca/__init__.py,sha256=pNwlPZkK5Oli1IZxHhSTdA8lTIsFdPUXrB3qdzw1kgo,2405 | ||
| pytrustnfe/nfse/carioca/templates/CancelarNfse.xml,sha256=u8PxZfXQiRChrrTalFPSmX97Bt4hTm5tDs3-J30zPgI,662 | ||
| pytrustnfe/nfse/carioca/templates/GerarNfse.xml,sha256=AjxgY-B0IM62lydnrzJVqkBKngkir0n7KIUvz8Prozc,136 | ||
| pytrustnfe/nfse/carioca/templates/Rps.xml,sha256=r8f_d63gW4M4LwFww7PWw8aXyhdhqk5Jo3DwmXAiCzE,4639 | ||
| pytrustnfe/nfse/dsf/__init__.py,sha256=YJrtDJcfmOIfpRBN71PiQ9Pa4hP35PQV4O16IUtOnaY,3913 | ||
| pytrustnfe/nfse/dsf/templates/cancelar.xml,sha256=Tak-cAv68oo-RAjnwO8FrmZwFfxPZGYeb8BKkrnPKsw,899 | ||
| pytrustnfe/nfse/dsf/templates/consulta_notas.xml,sha256=9zGvSkq8H1dkeEnM0O1GOCE2qBaW8fxkzR_hdYXWqVA,709 | ||
| pytrustnfe/nfse/dsf/templates/consultarLote.xml,sha256=6_Z0NzOrl-4wB6HRQz3JQulpXAzwQQiJ2tbgXU6VTeE,505 | ||
| pytrustnfe/nfse/dsf/templates/consultarNFSeRps.xml,sha256=zRoeFkkKtDR6rMN9Xu4CQS3pGkiKswk4ZiYN808g9sA,1028 | ||
| pytrustnfe/nfse/dsf/templates/enviar.xml,sha256=KR57-hOde0Gm5Y2D3a17md4jhVPdz8mOSb5S1LaafZ8,5013 | ||
| pytrustnfe/nfse/dsf/templates/soap_header.xml,sha256=jsEk7jyKYqWGtZ7yCU4-tUcMjoy6ZNgMwAmzCFZHc8s,506 | ||
| pytrustnfe/nfse/floripa/__init__.py,sha256=y68KlAO3x-LdycmxFJXjsh3fhsTOZ9ccw005q87mKjE,4239 | ||
| pytrustnfe/nfse/floripa/templates/cancelar_nota.xml,sha256=z9pVDRKxVdJcciEiMuSFlxkvKeVux4mNefJmPcFeEVQ,317 | ||
| pytrustnfe/nfse/floripa/templates/processar_nota.xml,sha256=1w7kdCsJL3WN8C3XhL6poDvdzld2HyooDWE79Q8lHPg,2149 | ||
| pytrustnfe/nfse/ginfes/__init__.py,sha256=V7rUUY1xiUFfuAe7dQuLY0dg5ONeemQ9f-2Yyb58O88,4354 | ||
| pytrustnfe/nfse/ginfes/templates/CancelarNfseV3.xml,sha256=f676AqSHIMGDWYg1cdcXbXuYyZxzdW3gK3tyh9jUpxM,860 | ||
| pytrustnfe/nfse/ginfes/templates/ConsultarLoteRpsV3.xml,sha256=V_s3uCLAaPddfkA5sB9sgnrMP2reDy_AnzlpqGP_mrQ,427 | ||
| pytrustnfe/nfse/ginfes/templates/ConsultarNfsePorRpsV3.xml,sha256=TLglV1vNUduON2djlCagV3vHCQ0z2O_3rud2cLET9P0,599 | ||
| pytrustnfe/nfse/ginfes/templates/ConsultarNfseV3.xml,sha256=9Tm0P2mCc5SstOJasBx_uIva4kd0nZKIl3Y_yOha_sc,426 | ||
| pytrustnfe/nfse/ginfes/templates/ConsultarSituacaoLoteRpsV3.xml,sha256=JcU0bULSQZuHW2KjKrM4Ri8uZFin99vzXEJIai8SEv4,452 | ||
| pytrustnfe/nfse/ginfes/templates/RecepcionarLoteRpsV3.xml,sha256=mSwtwNrH5qgHs6jNboQWn0WVXvr2pGbsadv7_OFSCeA,718 | ||
| pytrustnfe/nfse/ginfes/templates/Rps.xml,sha256=vNfzp7KLNvNl8DICqrze46dyL6-NpLEen7eZJKld5PU,4583 | ||
| pytrustnfe/nfse/goiania/__init__.py,sha256=fm9W899KEBiMQ0EVdkE2XYwHtkGfBHUWuex9j7va2dA,1965 | ||
| pytrustnfe/nfse/goiania/assinatura.py,sha256=J7UM28nY5ggGpMC1SpkwDWowdmspnpa-teTlq0GY3KY,1356 | ||
| pytrustnfe/nfse/imperial/__init__.py,sha256=qFvgXZJtqjn2_zUvhzRMVC6OtabdnSk5iepyuXU1b3g,1722 | ||
| pytrustnfe/nfse/imperial/templates/CancelarNota.xml,sha256=znRfhD6g8hdhi30JQ6N1Uddk3NzUgV4nlemJHRxx2y0,555 | ||
| pytrustnfe/nfse/imperial/templates/GerarNota.xml,sha256=KRMpQ_OM-wpWy62oH_HbqdBzEuQL-8gfdV2M_mwpexQ,2451 | ||
| pytrustnfe/nfse/issintel/__init__.py,sha256=SEVyX-ZdaSpG7l5hRjjGxOm1ENc4Uorzio6hKBd7m80,130 | ||
| pytrustnfe/nfse/issnet/__init__.py,sha256=SEVyX-ZdaSpG7l5hRjjGxOm1ENc4Uorzio6hKBd7m80,130 | ||
| pytrustnfe/nfse/mga/__init__.py,sha256=2P7thx_top0JszDlSefTMR-VfDLlwkuYHRaPgUig-f0,2307 | ||
| pytrustnfe/nfse/mga/assinatura.py,sha256=yMHsn3iO0TiZ4Tpbr1nIYvSveIxDxIqr-4MzOnnzg4U,1646 | ||
| pytrustnfe/nfse/mga/templates/CancelarNfse.xml,sha256=C7TnVOApz2CXSbQguoXAiEEJzb2auzufySXuDcAE-fU,703 | ||
| pytrustnfe/nfse/mga/templates/GerarNfse.xml,sha256=4RJDf0H3SpyP-E20igxmgnHiR7_ZC-2oFaMjs5bHLRw,104 | ||
| pytrustnfe/nfse/mga/templates/Rps.xml,sha256=aqJfjodmpwjcd4J43ocUMxeYDOye1w3zi-3CjT6pAT4,4067 | ||
| pytrustnfe/nfse/natal/__init__.py,sha256=WX6pxoPPnreIWXZcScgCQ2oQBuPHTAKtdUqKwdcLQlY,3914 | ||
| pytrustnfe/nfse/paulistana/__init__.py,sha256=tVuMRRv5qpXuyA85TjiGQN0YuSex9EXkMzJgZDBNRDc,3402 | ||
| pytrustnfe/nfse/paulistana/templates/CancelamentoNFe.xml,sha256=eG46b6cr4Ws4VjhIk16OGJTTWNSZHq401-InbDBDGwY,686 | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaCNPJ.xml,sha256=_KrQxWrEqP9Om4tYNoXwuH-_CaaYD5cAp1A3T1-4XMs,349 | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaInformacoesLote.xml,sha256=B8ZmcPHWvqFm4iC-f7HfkZYsuiRHUy3KTtWOf2OMmq4,375 | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaLote.xml,sha256=_1IJK99X8gshZ-9IFoKzU8qsHDTu8sBWRwCuLjX36-A,285 | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaNFe.xml,sha256=xzAmIf_c27krje-UblKwgyJwTPGFcGO31cV3Dpw-7cA,928 | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaNFeEmitidas.xml,sha256=GprAfLUtl9YhN7VMhYurFpdcfomBI4c4jhkBFTjhjFE,882 | ||
| pytrustnfe/nfse/paulistana/templates/ConsultaNFeRecebidas.xml,sha256=GprAfLUtl9YhN7VMhYurFpdcfomBI4c4jhkBFTjhjFE,882 | ||
| pytrustnfe/nfse/paulistana/templates/EnvioLoteRPS.xml,sha256=oHRNB6udKpBKaDggMCSu7F7PUKDTQUz7lLRYUQPdDlE,3769 | ||
| pytrustnfe/nfse/paulistana/templates/EnvioRPS.xml,sha256=Lc_AdX92n4soiKMclj7YcH1d6orezdx1HbZ4X1f0RdQ,3387 | ||
| pytrustnfe/nfse/saatri/__init__.py,sha256=SEVyX-ZdaSpG7l5hRjjGxOm1ENc4Uorzio6hKBd7m80,130 | ||
| pytrustnfe/nfse/simpliss/__init__.py,sha256=pyTgYTyR_8qB1QIn4jg36f3bbjfXwqt24si8IHU2TrY,3802 | ||
| pytrustnfe/nfse/simpliss/templates/CancelarNfse.xml,sha256=dyenXZR5R7YAYkYBCQkh3mDsUVWei7fFiPAggxqV02Y,1027 | ||
| pytrustnfe/nfse/simpliss/templates/ConsultarLoteRps.xml,sha256=ibZyEwT7Dv3A7nuSjwHUPt3HlN3yqmzGT1AMTeBnt2s,735 | ||
| pytrustnfe/nfse/simpliss/templates/ConsultarNfse.xml,sha256=k4gB0XSvhHoSyv2MPDlIFfm6aAtFogoWk_pnlSH1Ndo,1422 | ||
| pytrustnfe/nfse/simpliss/templates/ConsultarNfsePorRps.xml,sha256=GRqSZmM9Sc9aViU3FtBdGrUltWQ2cKBVMXx7Vd9dhpA,788 | ||
| pytrustnfe/nfse/simpliss/templates/ConsultarSituacaoLoteRps.xml,sha256=Uyh6rQIMQ90se1Sv0itVrbGq0-0wxKyxx1DyTtDYWuE,767 | ||
| pytrustnfe/nfse/simpliss/templates/GerarNfse.xml,sha256=bFshVwyLz_7W_wURN03avJS8R71hOiwjSAAvm5iZ19w,5475 | ||
| pytrustnfe/nfse/simpliss/templates/RecepcionarLoteRps.xml,sha256=0aH4Az2-JSmUmRHTO7zzd35GMA3dDmD9AW2B76xt9Gk,881 | ||
| pytrustnfe/nfse/simpliss/templates/Rps.xml,sha256=ygwhffXdaVBMxqZrZ2qEyeW2yIUvgxzagFcnp3J7CJU,4865 | ||
| pytrustnfe/nfse/simpliss/templates/SoapRequest.xml,sha256=9ZbgpYH-kf7w6MapvadNSzWLiLbGznu7KSOJRt7U7RI,116 | ||
| pytrustnfe/nfse/susesu/__init__.py,sha256=qmX6_kQu02AnWGikjtIEco7yQ8bZT1N9yVs_57azCUc,1676 | ||
| pytrustnfe/nfse/susesu/templates/EnviarNota.xml,sha256=NyatsZnZnA19Pje9ceWDb43iGw-1_lhDJGhkL5ED1N8,486 | ||
| pytrustnfe/nfse/susesu/templates/EnviarNotaRetornaurlNota.xml,sha256=iJfSP7foKhKyRK7cl9dL1eO2fiVNpyq3cA6BU2QXB7A,468 | ||
| pytrustnfe/nfse/susesu/templates/Nota.xml,sha256=awaVdH39420UOwHzsBaqvBbvLymWAsmwRAYm78xgd54,1921 | ||
| pytrustnfe/nfse/webiss/__init__.py,sha256=SEVyX-ZdaSpG7l5hRjjGxOm1ENc4Uorzio6hKBd7m80,130 | ||
| pytrustnfe/xml/__init__.py,sha256=yv6hE-Oaof4np6Cf2n4MiWcGrPP_DwVg0-v5WJNPlOw,2519 | ||
| pytrustnfe/xml/filters.py,sha256=5_hO3RdSM0dqgksl34p6Bxih1tTfnpIYHnq0gTv7I24,1557 | ||
| pytrustnfe/xml/validate.py,sha256=0ytB1b4BhrB5wMx5GZhr3yhYjisAVO8-kBL5Zv4zD_s,615 | ||
| pytrustnfe/xml/schemas/distDFeInt_v1.01.xsd,sha256=3jeVU_zGZsJRkOyJhiUCmaypCEpi2uMBNSRaFZF0LqE,11587 | ||
| pytrustnfe/xml/schemas/enviNFe_v4.00.xsd,sha256=Kr_GGY7OeE56akvRCTAC0VE9Pb7NS1HZogfUroH_wu8,600 | ||
| pytrustnfe/xml/schemas/leiauteNFe_v4.00.xsd,sha256=2TSOn48V1QmDnIsKBiccH0k3UAkVgyFb0-VmS3uKqcs,305852 | ||
| pytrustnfe/xml/schemas/nfe_v4.00.xsd,sha256=CsnUwUa223efS2pTEEWJm5GdQuG7h-uW1vaSuxS4tkY,522 | ||
| pytrustnfe/xml/schemas/tiposBasico_v4.00.xsd,sha256=6kcK5DLmZixkR30ZNeZBzbInmrSH-L_abA6vzmwo2EA,21476 | ||
| pytrustnfe/xml/schemas/xmldsig-core-schema_v1.01.xsd,sha256=9WdEpfUcA_An3hPzn4aTBwkXganvHZGx6-FHGc4o4aw,3747 | ||
| pytrustnfe3-1.0.61.dist-info/LICENSE.txt,sha256=lWyqyST4jTn4XVBaaQpfZwoyXXa3DHw66K7nHVY6P_4,33893 | ||
| pytrustnfe3-1.0.61.dist-info/METADATA,sha256=Z7-o06zwCyIWD42yLofmxrTRLQICMBaI5khlw_yzw7g,8363 | ||
| pytrustnfe3-1.0.61.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 | ||
| pytrustnfe3-1.0.61.dist-info/top_level.txt,sha256=8qzOFGgNgSalbe42iXXfKIhTpZxoR6egXmnzenbdFko,11 | ||
| pytrustnfe3-1.0.61.dist-info/RECORD,, |
| pytrustnfe |
-5
| Wheel-Version: 1.0 | ||
| Generator: bdist_wheel (0.37.1) | ||
| Root-Is-Purelib: true | ||
| Tag: py3-none-any | ||
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
856396
Infinity%142
Infinity%4741
Infinity%