From 2765a09f26636b0ffc85119ca54686737e3b82db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Tue, 20 Mar 2018 03:24:26 -0300 Subject: [PATCH 01/28] examplo real, importando uma nota processada --- README.rst | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 84a1a7e2..15a7b09e 100644 --- a/README.rst +++ b/README.rst @@ -42,9 +42,50 @@ Como Usar # nfelib permite ler os dados de uma nota fiscal, por exemplo no formato 3.10: >>> from nfelib.v3_10 import leiauteNFe as leiauteNFe3 # você usaria from nfelib.v4_00 import leiauteNFe as leiauteNFe4 para usar a versão 4.00 do leiaute - >>> nota = leiauteNFe3.parse("/algum_caminho/alguma_nota.xml") - >>> nota.get_infNFe().get_emit().get_CPF() - '12345678901' + + # primeiro, temos que recortar a nota processada (tag rais nfeProc) no primeiro filho (tag NFe) + # pois para evitar ter uma biblioteca enorme, o parser so funciona para o elemento NFe: + >>> from lxml import etree + >>> tree = etree.parse("/algum_caminho/alguma_nota.xml") + >>> root = tree.getroot() + >>> import tempfile + >>> new_file, filename = tempfile.mkstemp() + >>> subtree = etree.ElementTree(root[0]) # exportamentos apenas o primeiro filho + >>> subtree.write(filename, encoding='utf-8') + + # agora vamos importar o XML da nota e transforma-lo em objeto Python: + >>> nota = leiauteNFe3.parse(filename) + # agora podemos trabalhar em cima do objeto e fazer operaçoes como: + >>> nota.get_infNFe().get_emit().get_CNPJ() + '03102552000172' + >>> len(nota.get_infNFe().get_det()) + 42 + # (a nota tem 42 linhas) + + # podemos tambem alterar os dados usandos os getters e setters... + + # e finalmente podemos exportar a nota num arquivo de novo por examplo + # com Python2, hoje para exportar num arquivo, temos que primeiro exportar num + # buffer StringIO e depois jogar ele dentro de um arquivo para poder garantir o encoding utf-8: + >>> import StringIO + >>> output = StringIO.StringIO() + >>> nota.export(output, 0) + >>> contents = output.getvalue() + >>> output.close() + + >>> new_file, filename = tempfile.mkstemp() + >>> with open(filename, 'w') as f: + ... write_txt = contents.encode('utf8') + ... f.write(write_txt) + + >>> print filename + # basta abrir o arquivo filename, e conferir que ele eh semelhante ao arquivo de entrada (apenas recortado e formatado) + + + # no Python3, o export é mais facil, basta fazer: + >>> new_file, filename = tempfile.mkstemp() + >>> nota.export(open(filename, 'w'), 0) + >>> print(filename) # nfelib também permite de montar o XML de uma nota fiscal com todas validações dos XSDs já nos objetos: @@ -98,6 +139,6 @@ Uso no ERP Odoo =============== Para cada documento eletrônico para o qual existe esquema XSD's, a Akretion fez um repo Github com uma lib desse tipo. -Mas fomos além: para cada repo existe uma branch 'generated_odoo' com o modelo de dados dos documento para o ERP livre Odoo. +Mas fomos além: para cada repo existe uma branch `'generated_odoo': ` com o modelo de dados dos documento para o ERP livre Odoo. Esses modelos são abstratos e podem ser injetados de forma inteligente no ERP Odoo para não ter que manter manualmente os campos fiscais e o mapeamento desses dados. Em breve a Akretion irá mostrar como fazer isso dentro de módulos da OCA. From 8b3223ab635b13599e1d4767f64d34c1410f1523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 03:36:11 -0300 Subject: [PATCH 02/28] better .gitignore for tests --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b1eda809..10cbad84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ led python files *.py[co] +tests/.cache +tests/.coverage +tests/.pytest_cache From d3052815b2e030d2310d16183ed8a0b5a5bbf343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 03:36:46 -0300 Subject: [PATCH 03/28] added basic input/output tests --- tests/__init__.py | 0 tests/nfe/__init__.py | 1 + tests/nfe/test_nfelib.py | 49 +++++++++++++++++++ ...4794000154550010000016871192213339-nfe.xml | 1 + ...2452000172550010000474281920007498-nfe.xml | 1 + ...2452000172550010000474491454651420-nfe.xml | 1 + ...2452000172550010000474501597356342-nfe.xml | 1 + ...2452000172550010000474641681223493-nfe.xml | 1 + ...2452000172550010000476051695511860-nfe.xml | 1 + ...2452000172550010000476121675985748-nfe.xml | 1 + ...2452000172550010000476491552806942-nfe.xml | 1 + ...2452000172550010000476711079516696-nfe.xml | 1 + ...2452000172550010000476781421693968-nfe.xml | 1 + ...2452000172550010000476861118934859-nfe.xml | 1 + ...000150550010000463201612756527-procNFe.xml | 1 + 15 files changed, 62 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/nfe/__init__.py create mode 100644 tests/nfe/test_nfelib.py create mode 100644 tests/nfe/v4_00/26180812984794000154550010000016871192213339-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000474281920007498-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000474491454651420-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000474501597356342-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000474641681223493-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000476051695511860-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000476121675985748-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000476491552806942-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000476711079516696-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000476781421693968-nfe.xml create mode 100644 tests/nfe/v4_00/35180803102452000172550010000476861118934859-nfe.xml create mode 100644 tests/nfe/v4_00/41170706117473000150550010000463201612756527-procNFe.xml diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/nfe/__init__.py b/tests/nfe/__init__.py new file mode 100644 index 00000000..33a2cf0f --- /dev/null +++ b/tests/nfe/__init__.py @@ -0,0 +1 @@ +from . import test_nfelib diff --git a/tests/nfe/test_nfelib.py b/tests/nfe/test_nfelib.py new file mode 100644 index 00000000..554070f2 --- /dev/null +++ b/tests/nfe/test_nfelib.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +import os +import sys +from os import path +try: + import StringIO +except ImportError: + from io import StringIO +from xmldiff import main +sys.path.append(path.join(path.dirname(__file__), '..', 'nfelib')) +from nfelib.v4_00 import leiauteNFe_sub as parser + + +def test_in_out(): + path = 'tests/nfe/v4_00' + for filename in os.listdir(path): + subtree = parser.parsexml_('%s/%s' % (path, filename,)) + inputfile = 'tests/input.xml' + subtree.write(inputfile, encoding='utf-8') + + # agora vamos importar o XML da nota e transforma-lo em objeto Python: + nota = parser.parse(inputfile)#'%s/%s' % (path, filename,)) + # agora podemos trabalhar em cima do objeto e fazer operaçoes como: + nota.infNFe.emit.CNPJ + + filename = 'tests/output.xml' + if sys.version_info.major == 2: # Python 2 + output = StringIO.StringIO() + nota.export(output, 0, name_='NFe', namespaceprefix_='', + namespacedef_='xmlns=\ + "http://www.portalfiscal.inf.br/nfe"') + contents = output.getvalue() + output.close() + + with open(filename, 'w') as f: + write_txt = contents#.encode('utf8') + f.write(write_txt) + else: # Python 3 + filename = 'tests/output.xml' + with open(filename, 'w') as f: + + nota.export(f, 0, name_='NFe', namespaceprefix_='', + namespacedef_='xmlns=\ + "http://www.portalfiscal.inf.br/nfe"') + + diff = main.diff_files('tests/input.xml', 'tests/output.xml') + print(diff) + assert len(diff) == 0 diff --git a/tests/nfe/v4_00/26180812984794000154550010000016871192213339-nfe.xml b/tests/nfe/v4_00/26180812984794000154550010000016871192213339-nfe.xml new file mode 100644 index 00000000..70391d9b --- /dev/null +++ b/tests/nfe/v4_00/26180812984794000154550010000016871192213339-nfe.xml @@ -0,0 +1 @@ +2619221333Venda55116872018-08-16T16:28:18-03:002018-08-16T16:28:18-03:0012261160611911000Odoo Brasil v875335849000115Teste Produtos Médicos Ltda - METeste Produtos Médicos Ltda - MEAvenida Manoel1Boa Vista2611606RecifePE500701231058Brasil0123456789306412330337148260000119MEDICOS, HOSP, IMP. E EXP. LTDAAv. Doutor Pedro1Sala 4Ponta da Praia3548500SantosSP110250121058Brasil999999991803879214167880945SEM GTINESPAÇADOR TEMPORARIO DE ACRILICO PARA QUADRIL COM GENTAMICINA902110106102UN1.00002490.00000002490.00SEM GTINUN1.00002490.000000010.00140999510707880930SEM GTINESPAÇADOR TEMPORARIO DE ACRILICO PARA QUADRIL COM GENTAMICINA902110106102UN1.00002490.00000002490.00SEM GTINUN1.00002490.000000010.00140999510707880200SEM GTINCIMENTO ACRÍLICO G 40G - APLICAÇÃO MANUAL COM GENTAMICINA300640206102UN4.0000200.0000000800.00SEM GTINUN4.0000200.000000010.001409995106060.000.000.000.000.000.000.000.005780.000.000.000.000.000.000.000.000.000.005780.00102012862002707LATAM LINHAS AEREAS S/A024673560PRACA MINISTRO SALGADO FILHO, S/N, IMBIRIBEIRARecifePE1CAIXA DE PAPELÃOS/ MARCA16875780.000.005780.000012018-09-252890.000022018-11-042890.00995780.00- NCM:9021.10.10 - Alíquotas da COFINS e do PIS Reduzidas a Zero pela Lei pela Lei 10.865/2004 ( Redação da Lei 12.058/2009 ) - Isento de ICMS pelo Convênio 126/2010.NCM:3006.40.20 - Isento de ICMS até 30/09/2019 pelos Convênios 01/99 e 049/2017 - Alíquotas da COFINS e do PIS Reduzidas a Zero pelo Decreto 6426/2008.x7gyL3XnoxBJdNazenJGuNwqRIQ=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1NFEPE_P_20.01.01.166261808129847940001545500100000168711922133392018-08-16T16:45:05-03:00126180042806970x7gyL3XnoxBJdNazenJGuNwqRIQ=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000474281920007498-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000474281920007498-nfe.xml new file mode 100644 index 00000000..5deb98c0 --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000474281920007498-nfe.xml @@ -0,0 +1 @@ +3592000749Venda551474282018-08-07T09:19:15-03:002018-08-07T09:19:15-03:0012354910211811100Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito III3549102Sao Joao da Boa VistaSP138771231058Brasil5519123456788038792141671015410878032368161525650FULANO DOS SANTOSRUA DA PAZ1Apto 1CALAFATE3106200Belo HorizonteMG304111231058Brasil912087897846902086QUINOA 100G (2X50G)100850906101UN6.00007.155000042.937897846902086UN6.00007.15500007.6710.00000050.6012.006.07999530142.930.650.280142.933.001.2961.710.0018.0012.0080.000.002.960.7412107897846902109QUINOA VEGETAIS 100G (2X50G)100850906101UN12.00007.155000085.867897846902109UN12.00007.155000015.3410.000000101.2012.0012.14999530185.860.650.560185.863.002.58123.410.0018.0012.0080.000.005.921.4812117897846902116QUINOA PICANTE 100G (2X50G)100850906101UN6.00007.155000042.937897846902116UN6.00007.15500007.6710.00000050.6012.006.07999530142.930.650.280142.933.001.2961.710.0018.0012.0080.000.002.960.7410787897846900785GRANOLA TRADICIONAL 250G1904100017030006101UN12.00004.658000055.907897846900785UN12.00004.65800009.9910.00000065.8912.007.91999510155.900.650.360155.903.001.6880.350.0018.0012.0080.000.003.860.96114778978469014788 GRAOS FUNGHI SECCHI C/ TOMATE SECO 250G100620206101UN6.00005.712000034.277897846901478UN6.00005.71200006.1210.00000040.3912.004.8599953060649.260.0018.0012.0080.000.002.370.5911787897846901782MATCHA FRUIT CRANBERRY 6G (#)0902100017097006101UN12.00002.728750032.757897846901782UN12.00002.72875005.8510.00000038.6012.004.63999510132.750.650.210132.753.000.9847.070.0018.0012.0080.000.002.260.56347.2841.670.0020.335.070.000.000.000.000.00294.6452.640.000.000.000.000.001.697.820.00347.28025663791000160TRANSP E ENCOMENDAS LTDA089981799688R GEN AUGUSTO, 683, 683, PQ. IND. LAGOINHARibeirao PretoSP16.9706.970347.28347.2847428/1-12018-08-24347.2815347.28VALORES TOTAIS DO ICMS INTERESTADUAL: DIFAL UF DESTINO R$ 20,33 + FCP 0,00: DIFAL UF ORIGEM: R$ 5,07XDmAGrL0Fox6w2ycVL7O8auPEjA=Mo79dXw7tMvvCzHvRvOBrH0mjrYGXVRa5yrruSyI8/tA2UGngDbDNpWrsrFtARa6XX1M4A8fL17TXFT34n6aLGf26ISletd990R0PRz0UPA9THCo0EiXaKQrVvAlFDlQ+tyLt6lDHLZWKrD4IREDQ1IZRQ2JzOv2tSLxjz8ExBeHYcXVlj+Vb3KShJppBk4xnTZ9/BWATu02jNB7NLkpn0or06VAUI6e86HJEKinXs261PWKffKbXogxx/5cV5N7wp8OZx1yiW1X3GgECMv8hplfmqTW7DNxomJyabdfSBvoFG0fHphO7fsY9ljRkBR4NJDZEyQs2egX4LmS/sgzFw==MIIICjCCBfKgAwIBAgIJASNcLwM+CESMMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMSYwJAYDVQQDEx1BQyBJbXByZW5zYSBPZmljaWFsIFNQIFJGQiBHNDAeFw0xODA1MDIxMTU0MTVaFw0xOTA1MDIxMTU0MTVaMIHgMQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDELMAkGA1UECBMCU1AxHjAcBgNVBAcTFVNhbyBKb2FvIGRhIEJvYSBWaXN0YTE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRYwFAYDVQQLEw1SRkIgZS1DTlBKIEExMREwDwYDVQQLEwhBUiBDSUVTUDEsMCoGA1UEAxMjR1JJTkdTIEUgRklMSE9TIExUREE6MDMxMDI0NTIwMDAxNzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiiposJ4cJarbtmdRQ59ODn/0eR/1zUQQIbvI1BLq7yMLNhTTC/STJfWrygfgJzspBnbARldUBAWSeqwGueoaE5Cqcrbzah/YFTZQ7qazf2HfGTUFlszg1AjHwJmthIwRRYYoWoLdIzlTSEprPSAGOOfw2JDBDpQzojWXrrK9PQN1CALM0O5w/VYAEJaTHfc4mTa6CHWYq51dInOiebbeHq9ux7G9Ur/mTFAQ/IAkJIYmY70KuuNKDJ03UeBMH9Ps8skkbxo1bGaJ3zFP+m8YbtgZdL/VQdNFyo29iMhljrzzS6vw4wPeXnzFPPtvms926EYCexEWM3TPVu2nVd8QHAgMBAAGjggMhMIIDHTAOBgNVHQ8BAf8EBAMCBeAwgacGCCsGAQUFBwEBBIGaMIGXMDcGCCsGAQUFBzABhitodHRwOi8vaW8tb2NzcC1pY3Bici5pbXByZW5zYW9maWNpYWwuY29tLmJyMFwGCCsGAQUFBzAChlBodHRwOi8vaW8tY29tLWljcGJyLmltcHJlbnNhb2ZpY2lhbC5jb20uYnIvcmVwb3NpdG9yaW8vSU1FU1BSRkIvQUNJTUVTUFJGQkc0LnA3YjAfBgNVHSMEGDAWgBR6VPzMnQaPeeMNRMnu5cO3TU3LojBiBgNVHSAEWzBZMFcGBmBMAQIBFDBNMEsGCCsGAQUFBwIBFj9odHRwOi8vaW8tY29tLWljcGJyLmltcHJlbnNhb2ZpY2lhbC5jb20uYnIvcmVwb3NpdG9yaW8vSU1FU1BSRkIwCQYDVR0TBAIwADCB9QYDVR0fBIHtMIHqMFagVKBShlBodHRwOi8vaW8tY29tLWljcGJyLmltcHJlbnNhb2ZpY2lhbC5jb20uYnIvcmVwb3NpdG9yaW8vSU1FU1BSRkIvQUNJTUVTUFJGQkc0LmNybDBKoEigRoZEaHR0cDovL3d3dy5kaWdpdGFsdHJ1c3QuY29tLmJyL3JlcG9zaXRvcmlvL0lNRVNQUkZCL0FDSU1FU1BSRkJHNC5jcmwwRKBCoECGPmh0dHA6Ly9yZXBvc2l0b3Jpby5pY3BicmFzaWwuZ292LmJyL2xjci9JTUVTUC9BQ0lNRVNQUkZCRzQuY3JsMIGtBgNVHREEgaUwgaKBFXN1cG9ydGVAZ3JpbmdzLmNvbS5icqA4BgVgTAEDBKAvBC0wNTA5MTk3NjI1MjczNjA3ODUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDCgGwYFYEwBAwKgEgQQQ1JJU1RJQU5PIEdSSU5HU6AZBgVgTAEDA6AQBA4wMzEwMjQ1MjAwMDE3MqAXBgVgTAEDB6AOBAwwMDAwMDAwMDAwMDAwKQYDVR0lBCIwIAYIKwYBBQUHAwIGCCsGAQUFBwMEBgorBgEEAYI3FAICMA0GCSqGSIb3DQEBCwUAA4ICAQAGEA7G5TP8+aGZHgaShOQF43b8vIkMik4qe3GfYvNeM9+Vtx2Byka8mb0/pptnbpmsH6w7xsC9U31eCY1XXmB2+GhFSSnwweuaDIuDwSx14PDoPadCKU5aKGvMcHr86j08dq4831XjHLCK//mPJLHNcPTVQmVIxUrDpeUruX5+LKP2d0keYdtO5v3S7cqOzJ9ioa0m+zwjU/wCV9KC+EcO2U3CAz7uqjZHwGBpkBzeWW66eNf8PYiGIs/hNI1a62kFn5SDxmmBOYCxsJtrOC3z2nAGW2kN6D4hwM0y9hi2g+Wpb3mbuQS6KvOYqsGI4bUa++PMSSLZChWTuhWPMFEHuEFX1f2K3PYQgliADiE3x02eFr0DzBm+M02xkzGSZee8HsmyhwnGl1lMRgkd5tPU1O0hH93OHjTZh+Kfpzgav0JJ0D5mD0LN2EM3ozy+M+0koo1ECTQGXLyNF9i+7ejhAHrmO+V3753xRgU1GXPCv8WiAoUD+TEles4ZdSwjeA15+tZICtIM5HSguyHMLclPQTeQBhrgFV3bvIC0/HpTyDy/eLaK8P5fzibTaptojZg04RTZsh/ZeKm0qdhJYAk/eq+xixVztgsqj/0OxaZDQfAccXkiSaRmN+h0z0MAHkjgUpQi+2/hhPNgiYjPjv+/IVbBV2pRv/q4uU+/SuRtsQ==1SP_NFE_PL009_V4351808031024520001725500100004742819200074982018-08-07T09:19:31-03:00135180527657478XDmAGrL0Fox6w2ycVL7O8auPEjA=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000474491454651420-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000474491454651420-nfe.xml new file mode 100644 index 00000000..781c4f41 --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000474491454651420-nfe.xml @@ -0,0 +1 @@ +3545465142Bonificação de mercadoria sujeita ao regime de Substituição551474492018-08-08T10:25:10-03:002018-08-08T11:25:10-03:0011354910211011100Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito III3549102Sao Joao da Boa VistaSP138771231058Brasil551912345678803879214167353232886000165REPRESENTACAO COMERCIAL ALIMENTICIOS LTDARua Ema7Jardim Shangri-la3522307ItapetiningaSP182081231058Brasil9ia@ai.com10947897846900945CEREALLE GRANOLA TRADICIONAL 800G1904100017030005910UN2.00005.123160010.257897846900945UN2.00005.123160010.00000310.2518.001.84999510110.250.650.070110.253.000.3110957897846900952GRANOLA BANANA & MEL 800G1904100017030005910UN2.00005.123160010.257897846900952UN2.00005.123160010.00000310.2518.001.84999510110.250.650.070110.253.000.3110977897846900976GRANOLA ZERO 800G1904100017030005910UN2.00005.123160010.257897846900976UN2.00005.123160010.00000310.2518.001.84999510110.250.650.070110.253.000.3111287897846901287GRANOLA MAIS 500G1904100017030005910UN2.00002.26233004.527897846901287UN2.00002.262330010.0000034.5218.000.8199951014.520.650.03014.523.000.1412087897846902086QUINOA FACIL CASTANHA 100G (2X50G)100850905910UN2.00002.97171005.947897846902086UN2.00002.971710010.0000035.9418.001.0799953015.940.650.04015.943.000.181111789784690111912 GRAOS 500G100620205910UN2.00002.61660005.237897846901119UN2.00002.616600010.00020361.112.0318.000.3799953060612107897846902109QUINOA FACIL VEGETAIS 100G (2X50G)100850905910UN2.00002.97171005.947897846902109UN2.00002.971710010.0000035.9418.001.0799953015.940.650.04015.943.000.181138789784690138612 GRAOS SELECAO LOW GLUTEN 500G100620205910UN2.00002.97360005.957897846901386UN2.00002.973600010.00020361.112.3118.000.4299953060612357897846902352GOLDEN MIX 100G210690105910UN2.00000.000.007897846902352UN2.00000.0010.0000030.0018.000.0099951010.000.650.00010.003.000.0012327897846902321HIBISCO COM CANELA E GENGIBRE 100G210690105910UN2.00006.740000013.487897846902321UN2.00006.740000010.00000313.4818.002.43999510113.480.650.090113.483.000.4012317897846902314MATCHA COM CANELA E GENGIBRE 100G210690105910UN2.00006.740000013.487897846902314UN2.00006.740000010.00000313.4818.002.43999510113.480.650.090113.483.000.4012677897846902673COOKIES GRANOLA BANANA E MEL 30G1905902017056025910UN7.00000.67000004.697897846902673UN7.00000.670000010.0000034.6918.000.8499951014.690.650.03014.693.000.1412687897846902680COOKIES GRANOLA BAUNILHA COM GOTAS DE CHOCOLATE 30G1905902017056025910UN7.00000.67000004.697897846902680UN7.00000.670000010.0000034.6918.000.8499951014.690.650.03014.693.000.1412707897846902703COOKIES ZERO CASTANHAS 30G1905310017053005910UN7.00000.75000005.257897846902703UN7.00000.750000010.0000035.2518.000.9499951015.250.650.03015.253.000.1612747897846902741COOKIES ZERO BERRIES 30G1905310017053005910UN7.00000.75000005.257897846902741UN7.00000.750000010.0000035.2518.000.9499951015.250.650.03015.253.000.1612547897846902543HIBISCUS FRUIT 6G ABACAXI COM HORTELA210690105910UN12.00001.180000014.167897846902543UN12.00001.180000010.00000314.1618.002.55999510114.160.650.090114.163.000.42114678978469014618 GRAOS CASTANHAS BRASILEIRAS 250G100620205910UN2.00002.82240005.647897846901461UN2.00002.822400010.00020361.112.1918.000.40999530606114778978469014788 GRAOS FUNGHI SECCHI C/ TOMATE SECO 250G100620205910UN2.00002.82240005.647897846901478UN2.00002.822400010.00020361.112.1918.000.4099953060612567897846902567HIBISCUS FRUIT 6G CRANBERRY210690105910UN12.00001.180000014.167897846902567UN12.00001.180000010.00000314.1618.002.55999510114.160.650.090114.163.000.4211677897846901676MATCHA FRUIT LIMAO 6G (#)0902100017097005910UN12.00001.177050014.127897846901676UN12.00001.177050010.00000314.1218.002.54999510114.120.650.090114.123.000.4211767897846901768MATCHA FRUIT ABACAXI HORTELA 6G (#)0902100017097005910UN12.00001.177050014.127897846901768UN12.00001.177050010.00000314.1218.002.54999510114.120.650.090114.123.000.42159.2728.660.000.000.000.000.000.00173.010.000.000.000.000.000.000.984.510.00173.01056382230000117TRANSP E ENCOMENDAS LTDA089981799688R GEN AUGUSTO, 683, 683, PQ. IND. LAGOINHARibeirao PretoSP210.93010.93099173.01ENDERECO DE ENTREGA:| Rua Ema, 7| Jd Shangrila| Itapetininga -SP| CEP. 18208-123 -mtUbXNIGEhdxdsGQncKQz7/Op40=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1SP_NFE_PL009_V4351808031024520001725500100004744914546514202018-08-08T10:26:58-03:00135180531287041mtUbXNIGEhdxdsGQncKQz7/Op40=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000474501597356342-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000474501597356342-nfe.xml new file mode 100644 index 00000000..aa7fd34f --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000474501597356342-nfe.xml @@ -0,0 +1 @@ +3559735634Bonificacao551474502018-08-08T11:21:27-03:002018-08-09T11:16:57-03:0012354910211211100Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito III3549102Sao Joao da Boa VistaSP138771231058Brasil551912345678803879214167317902818000100COMERCIO DE PRODUTOS ALIMENTICIOS LTDA MERua Tadeu2Bairro Presidente4207007IcaraSC888201231058Brasil9ai1@ai.com10947897846900945GRANOLA TRADICIONAL 800G1904100017030006910UN2.00005.123160010.257897846900945UN2.00005.123160010.00000010.2512.001.23999510110.250.650.070110.253.000.3112.350.0017.0012.0080.000.000.500.1210957897846900952GRANOLA BANANA & MEL 800G1904100017030006910UN2.00005.123160010.257897846900952UN2.00005.123160010.00000010.2512.001.23999510110.250.650.070110.253.000.3112.350.0017.0012.0080.000.000.500.1210977897846900976GRANOLA ZERO 800G1904100017030006910UN2.00005.123160010.257897846900976UN2.00005.123160010.00000010.2512.001.23999510110.250.650.070110.253.000.3112.350.0017.0012.0080.000.000.500.1211287897846901287GRANOLA MAIS 500G1904100017030006910UN2.00002.26233004.527897846901287UN2.00002.262330010.0000004.5212.000.5499951014.520.650.03014.523.000.145.450.0017.0012.0080.000.000.220.0512087897846902086QUINOA FACIL CASTANHA 100G (2X50G)100850906910UN2.00002.97171005.947897846902086UN2.00002.971710010.0000005.9412.000.7199953015.940.650.04015.943.000.187.160.0017.0012.0080.000.000.290.071111789784690111912 GRAOS 500G100620206910UN2.00002.61660005.237897846901119UN2.00002.616600010.0000005.2312.000.639995306066.300.0017.0012.0080.000.000.250.0612107897846902109QUINOA FACIL VEGETAIS 100G (2X50G)100850906910UN2.00002.97171005.947897846902109UN2.00002.971710010.0000005.9412.000.7199953015.940.650.04015.943.000.187.160.0017.0012.0080.000.000.290.071138789784690138612 GRAOS SELECAO LOW GLUTEN 500G100620206910UN2.00002.97360005.957897846901386UN2.00002.973600010.0000005.9512.000.719995306067.170.0017.0012.0080.000.000.290.0712357897846902352GOLDEN MIX 100G210690106910UN2.00001.00000002.007897846902352UN2.00001.000000010.0000002.0012.000.2499951012.000.650.01012.003.000.062.410.0017.0012.0080.000.000.100.0212327897846902321HIBISCO COM CANELA E GENGIBRE 100G210690106910UN2.00006.740000013.487897846902321UN2.00006.740000010.00000013.4812.001.62999510113.480.650.090113.483.000.4016.240.0017.0012.0080.000.000.650.1612317897846902314MATCHA COM CANELA E GENGIBRE 100G210690106910UN2.00006.740000013.487897846902314UN2.00006.740000010.00000013.4812.001.62999510113.480.650.090113.483.000.4016.240.0017.0012.0080.000.000.650.1612677897846902673COOKIES GRANOLA BANANA E MEL 30G1905902017056026910UN7.00000.67000004.697897846902673UN7.00000.670000010.0000004.6912.000.5699951014.690.650.03014.693.000.145.650.0017.0012.0080.000.000.220.0612687897846902680COOKIES GRANOLA BAUNILHA COM GOTAS DE CHOCOLATE 30G1905902017056026910UN7.00000.67000004.697897846902680UN7.00000.670000010.0000004.6912.000.5699951014.690.650.03014.693.000.145.650.0017.0012.0080.000.000.220.0612707897846902703COOKIES ZERO CASTANHAS 30G1905310017053006910UN7.00000.75000005.257897846902703UN7.00000.750000010.0000005.2512.000.6399951015.250.650.03015.253.000.166.330.0017.0012.0080.000.000.260.0612747897846902741COOKIES ZERO BERRIES 30G1905310017053006910UN7.00000.75000005.257897846902741UN7.00000.750000010.0000005.2512.000.6399951015.250.650.03015.253.000.166.330.0017.0012.0080.000.000.260.0612547897846902543HIBISCUS FRUIT 6G ABACAXI COM HORTELA210690106910UN12.00001.180000014.167897846902543UN12.00001.180000010.00000014.1612.001.70999510114.160.650.090114.163.000.4217.060.0017.0012.0080.000.000.680.17114678978469014618 GRAOS CASTANHAS BRASILEIRAS 250G100620206910UN2.00002.82240005.647897846901461UN2.00002.822400010.0000005.6412.000.689995306066.800.0017.0012.0080.000.000.270.07114778978469014788 GRAOS FUNGHI SECCHI C/ TOMATE SECO 250G100620206910UN2.00002.82240005.647897846901478UN2.00002.822400010.0000005.6412.000.689995306066.800.0017.0012.0080.000.000.270.0712567897846902567HIBISCUS FRUIT 6G CRANBERRY210690106910UN12.00001.180000014.167897846902567UN12.00001.180000010.00000014.1612.001.70999510114.160.650.090114.163.000.4217.060.0017.0012.0080.000.000.680.1711677897846901676MATCHA FRUIT LIMAO 6G (#)0902100017097006910UN12.00001.177050014.127897846901676UN12.00001.177050010.00000014.1212.001.69999510114.120.650.090114.123.000.4217.010.0017.0012.0080.000.000.680.1711767897846901768MATCHA FRUIT ABACAXI HORTELA 6G (#)0902100017097006910UN12.00001.177050014.127897846901768UN12.00001.177050010.00000014.1212.001.69999510114.120.650.090114.123.000.4217.010.0017.0012.0080.000.000.680.17175.0120.990.008.462.080.000.000.000.000.00175.010.000.000.000.000.000.000.994.570.00175.01025663791000160TRANSP E ENCOMENDAS LTDA089981799688R GEN AUGUSTO, 683, 683, PQ. IND. LAGOINHARibeirao PretoSP210.93010.93099175.01VALORES TOTAIS DO ICMS INTERESTADUAL: DIFAL UF DESTINO R$ 8,46 + FCP 0,00: DIFAL UF ORIGEM: R$ 2,08| ENDERECO DE ENTREGA:| Rua - Tadeu n - 2| Bairro Presidente | Cidade - Icara/SC| Cep- 88.820.123.csL95WHF/pvlCeG+vror5RS3DVw=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1SP_NFE_PL009_V4351808031024520001725500100004745015973563422018-08-08T11:23:05-03:00135180531548408csL95WHF/pvlCeG+vror5RS3DVw=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000474641681223493-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000474641681223493-nfe.xml new file mode 100644 index 00000000..515a810a --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000474641681223493-nfe.xml @@ -0,0 +1 @@ +3568122349Bonificacao551474642018-08-08T14:30:22-03:002018-08-09T14:24:36-03:0012354910211311100Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito III3549102Sao Joao da Boa VistaSP138771231058Brasil551912345678803879214167348527693000100REPRESENTACOES EIRELIRua Moacyr3Box 33Centro3200300Alfredo ChavesES292401231058Brasil9a@a.com10947897846900945CEREALLE GRANOLA TRADICIONAL 800G1904100017030006910UN2.00005.123160010.257897846900945UN2.00005.123160010.00000010.257.000.72999510110.250.650.070110.253.000.3112.350.0017.007.0080.000.000.980.2510957897846900952GRANOLA BANANA & MEL 800G1904100017030006910UN2.00005.123160010.257897846900952UN2.00005.123160010.00000010.257.000.72999510110.250.650.070110.253.000.3112.350.0017.007.0080.000.000.980.2510977897846900976GRANOLA ZERO 800G1904100017030006910UN2.00005.123160010.257897846900976UN2.00005.123160010.00000010.257.000.72999510110.250.650.070110.253.000.3112.350.0017.007.0080.000.000.980.2511287897846901287GRANOLA MAIS 500G1904100017030006910UN2.00002.26233004.527897846901287UN2.00002.262330010.0000004.527.000.3299951014.520.650.03014.523.000.145.450.0017.007.0080.000.000.440.1112087897846902086QUINOA FACIL CASTANHA 100G (2X50G)100850906910UN2.00002.97171005.947897846902086UN2.00002.971710010.0000005.947.000.4299953015.940.650.04015.943.000.187.160.0017.007.0080.000.000.580.141111789784690111912 GRAOS 500G100620206910UN2.00002.61660005.237897846901119UN2.00002.616600010.0000005.237.000.379995306066.300.0017.007.0080.000.000.500.1312107897846902109QUINOA FACIL VEGETAIS 100G (2X50G)100850906910UN2.00002.97171005.947897846902109UN2.00002.971710010.0000005.947.000.4299953015.940.650.04015.943.000.187.160.0017.007.0080.000.000.580.141138789784690138612 GRAOS SELECAO LOW GLUTEN 500G100620206910UN2.00002.97360005.957897846901386UN2.00002.973600010.0000005.957.000.429995306067.170.0017.007.0080.000.000.580.1412357897846902352GOLDEN MIX 100G210690106910UN2.00001.00000002.007897846902352UN2.00001.000000010.0000002.007.000.1499951012.000.650.01012.003.000.062.410.0017.007.0080.000.000.190.0512327897846902321HIBISCO COM CANELA E GENGIBRE 100G210690106910UN2.00006.740000013.487897846902321UN2.00006.740000010.00000013.487.000.94999510113.480.650.090113.483.000.4016.240.0017.007.0080.000.001.300.3212317897846902314MATCHA COM CANELA E GENGIBRE 100G210690106910UN2.00006.740000013.487897846902314UN2.00006.740000010.00000013.487.000.94999510113.480.650.090113.483.000.4016.240.0017.007.0080.000.001.300.3212677897846902673COOKIES GRANOLA BANANA E MEL 30G1905902017056026910UN7.00000.67000004.697897846902673UN7.00000.670000010.0000004.697.000.3399951014.690.650.03014.693.000.145.650.0017.007.0080.000.000.460.1112687897846902680COOKIES GRANOLA BAUNILHA COM GOTAS DE CHOCOLATE 30G1905902017056026910UN7.00000.67000004.697897846902680UN7.00000.670000010.0000004.697.000.3399951014.690.650.03014.693.000.145.650.0017.007.0080.000.000.460.1112707897846902703COOKIES ZERO CASTANHAS 30G1905310017053006910UN7.00000.75000005.257897846902703UN7.00000.750000010.0000005.257.000.3799951015.250.650.03015.253.000.166.330.0017.007.0080.000.000.500.1312747897846902741COOKIES ZERO BERRIES 30G1905310017053006910UN7.00000.75000005.257897846902741UN7.00000.750000010.0000005.257.000.3799951015.250.650.03015.253.000.166.330.0017.007.0080.000.000.500.1312547897846902543HIBISCUS FRUIT 6G ABACAXI COM HORTELA210690106910UN12.00001.180000014.167897846902543UN12.00001.180000010.00000014.167.000.99999510114.160.650.090114.163.000.4217.060.0017.007.0080.000.001.370.34114678978469014618 GRAOS CASTANHAS BRASILEIRAS 250G100620206910UN2.00002.82240005.647897846901461UN2.00002.822400010.0000005.647.000.399995306066.800.0017.007.0080.000.000.540.14114778978469014788 GRAOS FUNGHI SECCHI C/ TOMATE SECO 250G100620206910UN2.00002.82240005.647897846901478UN2.00002.822400010.0000005.647.000.399995306066.800.0017.007.0080.000.000.540.1412567897846902567HIBISCUS FRUIT 6G CRANBERRY210690106910UN12.00001.180000014.167897846902567UN12.00001.180000010.00000014.167.000.99999510114.160.650.090114.163.000.4217.060.0017.007.0080.000.001.370.3411677897846901676MATCHA FRUIT LIMAO 6G (#)0902100017097006910UN12.00001.177050014.127897846901676UN12.00001.177050010.00000014.127.000.99999510114.120.650.090114.123.000.4217.010.0017.007.0080.000.001.360.3411767897846901768MATCHA FRUIT ABACAXI HORTELA 6G (#)0902100017097006910UN12.00001.177050014.127897846901768UN12.00001.177050010.00000014.127.000.99999510114.120.650.090114.123.000.4217.010.0017.007.0080.000.001.360.34175.0112.270.0016.874.220.000.000.000.000.00175.010.000.000.000.000.000.000.994.570.00175.01025663791000160LOGISTICA ME089981799688PAULINO, 1905, JARDIM ITIMALIASao Joao da Boa VistaSP210.93010.93099175.01Entregar no endereco: | Rua: Rio n 3| Bairro: Helio| Serra - Espirito Santo| Cep: 29.160-541| VALORES TOTAIS DO ICMS INTERESTADUAL: DIFAL UF DESTINO R$ 16,87 + FCP 0,00: DIFAL UF ORIGEM: R$ 4,22| | TRANSPORTADORA :GUARU CARGO - TRANSPORTES LTDA.CNPJ: - IE END: AVENIDA MONTEIRO, 4 - GALPAO01 ASA 7 - CIDADE JARDIM CUMBICA - GUARULHOS - SP - CEP: 07.180-123 FRETE POR CONTA DO EMITENTEcCSb3ou9tF66rnbjFbG+7jpy+IQ=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1SP_NFE_PL009_V4351808031024520001725500100004746416812234932018-08-08T14:31:17-03:00135180532184231cCSb3ou9tF66rnbjFbG+7jpy+IQ=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000476051695511860-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000476051695511860-nfe.xml new file mode 100644 index 00000000..a3c67d9b --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000476051695511860-nfe.xml @@ -0,0 +1 @@ +3569551186Bonificação de mercadoria sujeita ao regime de Substituição551476052018-08-15T16:16:57-03:002018-08-17T16:16:43-03:0011354910211011000Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Eisleben2Distrito III3549102Sao Joao da Boa VistaSP138771231058Brasil551912345678803879214167357647232000153SUPERMERCADOS LTDAR TOMAZ JASSO8SANTA CRUZ3524709JaguariunaSP138201231058Brasil19123456781189454930860nfentrada@b.com.br10957897846900952GRANOLA BANANA & MEL 800G1904100017030005910UN12.000012.8400000154.087897846900952UN12.000012.840000010.00070333.33102.7318.0018.49471.35264.0218.0029.039995101154.080.651.0001154.083.004.6210967897846900969GRANOLA MACA & GERGELIM 800G1904100017030005910UN12.000012.8400000154.087897846900969UN12.000012.840000010.00070333.33102.7318.0018.49471.35264.0218.0029.039995101154.080.651.0001154.083.004.6210977897846900976GRANOLA ZERO 800G1904100017030005910UN12.000012.8400000154.087897846900976UN12.000012.840000010.00070333.33102.7318.0018.49471.35264.0218.0029.039995101154.080.651.0001154.083.004.6211237897846901232GRANOLA BANANA & CACAU 800G1904100017030005910UN4.000012.840000051.367897846901232UN4.000012.840000010.00070333.3334.2418.006.16471.3588.0118.009.68999510151.360.650.330151.363.001.54342.4361.630.000.00880.0796.770.000.00513.600.000.000.000.000.000.003.3315.400.00610.37034128745000152Alimentos Ltda.803879214167Rua Fonseca, 2, DistritoSao Joao da Boa VistaSP32.00032.00099610.37lnaJCoqT9rFTCMDfi24mWYtzKJE=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1SP_NFE_PL009_V4351808031024520001725500100004760516955118602018-08-15T16:17:15-03:00135180550847249lnaJCoqT9rFTCMDfi24mWYtzKJE=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000476121675985748-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000476121675985748-nfe.xml new file mode 100644 index 00000000..26038d59 --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000476121675985748-nfe.xml @@ -0,0 +1 @@ +3567598574Bonificação de mercadoria sujeita ao regime de Substituição551476122018-08-16T11:55:31-03:002018-08-16T11:55:31-03:0012354910211811100Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito III3549102Sao Joao da Boa VistaSP138771231058Brasil5519123456788038792141671015410878032368834846982ROBERTORUA MAJOR1CENTRO3115508CaxambuMG374401231058Brasil35912345678911687897846901683COOKIES GRANOLA CASTANHA 150G (#)1905902017056026910UN6.00001.51000009.067897846901683UN6.00001.510000010.0000009.0612.001.0999951019.060.650.06019.063.000.2711.050.0018.0012.0080.000.000.530.139.061.090.000.530.130.000.000.000.000.009.060.000.000.000.000.000.000.060.270.009.06925663791000160EMP.BRAS.DE CORREIOSBLOCO II 17 ANDAR, 592, VILA LEOPOLDINASao PauloSP0.9000.900999.06SAC | VALORES TOTAIS DO ICMS INTERESTADUAL: DIFAL UF DESTINO R$ 0,53 + FCP R$ 0,00: DIFAL UF ORIGEM: R$ 0,139f4hJBfPb+BkiQks0WI7zrdf6WU=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1SP_NFE_PL009_V4351808031024520001725500100004761216759857482018-08-16T11:55:39-03:001351805531900749f4hJBfPb+BkiQks0WI7zrdf6WU=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000476491552806942-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000476491552806942-nfe.xml new file mode 100644 index 00000000..8cce1a53 --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000476491552806942-nfe.xml @@ -0,0 +1 @@ +3555280694Venda de Mercadoria Sujeita a Substituição Tributária551476492018-08-17T09:06:43-03:002018-08-18T09:06:34-03:0012354910211211000Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito III3549102São João da Boa VistaSP138771231058Brasil5519123456788038792141671015410878032397493746000116DANIELA - MERUA ANTONIO3CENTRO3120508CristinaMG374761231058Brasil3512345678193751378383410947897846900945GRANOLA TRADICIONAL 800G1904100017030006401UN6.000013.039020078.237897846900945UN6.000013.039020010.00010078.2312.009.39450.24117.5318.0011.77999510178.230.650.510178.233.002.3510187897846900181AVEIA EM FLOCOS FINOS 500G (#)110412006101UN12.00004.360000052.327897846900181UN12.00004.360000010.00000052.3212.006.28999510152.320.650.340152.323.001.5710957897846900952GRANOLA BANANA & MEL 800G1904100017030006401UN6.000013.039020078.237897846900952UN6.000013.039020010.00010078.2312.009.39450.24117.5318.0011.77999510178.230.650.510178.233.002.3510217897846900211AVEIA EM FLOCOS 500G (#)110412006101UN12.00004.360000052.327897846900211UN12.00004.360000010.00000052.3212.006.28999510152.320.650.340152.323.001.5711287897846901287MAIS 500G1904100017030006401UN10.00005.999990060.007897846901287UN10.00005.999990010.00010060.0012.007.20450.2490.1418.009.03999510160.000.650.390160.003.001.8011397897846901393ACUCAR DEMERARA DOURADO 500G1701140017101006401UN6.00004.797140028.787897846901393UN6.00004.797140010.00010028.7812.003.45415.0061.1112.8718.000.3199951060610287897846900280PROTEINA DE SOJA GROSSA 200G (#)210610006101UN6.00003.689870022.147897846900280UN6.00003.689870010.00000022.1412.002.66999510122.140.650.140122.143.000.6610987897846900983FARINHA DE LINHACA MARROM 200G (#)120400906101UN6.00004.430000026.587897846900983UN6.00004.430000010.00000026.5812.003.19999530126.580.650.170126.583.000.8010167897846900167PROTEINA DE SOJA MEDIA 400G (#)210610006101UN6.00005.697560034.197897846900167UN6.00005.697560010.00000034.1912.004.10999510134.190.650.220134.193.001.0312217897846902215SAL ROSA DO HIMALAIA 250G250100906101UN12.00004.437000053.247897846902215UN12.00004.437000010.6410.00500042.6012.005.11999530142.600.650.280142.603.001.2810427897846900426FARINHA TRIGO INTEGRAL 500G1101001017044006101UN12.00003.530750042.377897846900426UN12.00003.530750010.00000042.3712.005.0899953060612707897846902703COOKIES ZERO CASTANHAS 30G1905310017053006401UN14.00001.890000026.467897846902703UN14.00001.890000010.00010026.4612.003.18444.8838.3418.003.72999510126.460.650.170126.463.000.7910787897846900785CEREALLE GRANOLA TRADICIONAL 250G1904100017030006401UN6.00005.567130033.407897846900785UN6.00005.567130010.00010033.4012.004.01450.2450.1818.005.02999510133.400.650.220133.403.001.0010307897846900303GERGELIM 200G (#)120740906101UN6.00006.670000040.027897846900303UN6.00006.670000010.00000040.0212.004.80999530140.020.650.260140.023.001.2012187897846902185OLEO DE COCO 200ML1513190017075006101UN14.000015.3340000214.687897846902185UN14.000015.334000030.0610.000000184.6212.0022.1599951060612047897846902048ACUCAR DE COCO 150G1702900017105006401UN3.00009.356200028.077897846902048UN3.00009.356200010.00210028.074.001.12440.4941.4018.006.339995028.075.001.400128.070.650.180128.073.000.84830.3397.390.000.00467.9947.950.000.00871.030.000.0040.700.001.400.003.7317.240.00879.68048840871000140TRANSP E LOG LTDA ERELI9283369346321AVENIDA FRANCISCO, 678, REZENDEVarginhaMG1549.35052.11047649879.680.00879.680012018-09-17879.6815879.68kiyBDSye9wNYinWvW7mz7Kws+Ik=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1SP_NFE_PL009_V4351808031024520001725500100004764915528069422018-08-17T09:07:11-03:00135180555849149kiyBDSye9wNYinWvW7mz7Kws+Ik=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000476711079516696-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000476711079516696-nfe.xml new file mode 100644 index 00000000..1e6b9f2c --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000476711079516696-nfe.xml @@ -0,0 +1 @@ +3507951669Venda551476712018-08-17T12:28:38-03:002018-08-17T12:28:38-03:0011354910211611100Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito III3549102São João da Boa VistaSP138777761058Brasil551912345678803879214167314654462309Fulano SilvaRUA PERES4JARDIM PRIMAVERA3549102São João da Boa VistaSP138761231058Brasil1912345678912357897846902352GOLDEN MIX 100G210690105101UN1.000012.206000012.217897846902352UN1.000012.206000010.00000312.2118.002.20999510112.210.650.080112.213.000.3712187897846902185OLEO DE COCO 200ML1513190017075005101UN1.000012.127800012.137897846902185UN1.000012.127800010.00020361.114.7218.000.8599951060616.933.050.000.000.000.000.000.0024.340.000.000.000.000.000.000.080.370.0024.34034128745000152Alimentos Ltda.803879214167Rua Fonseca, 2, DistritoSão João da Boa VistaSP10.2700.4704767124.340.0024.340012018-09-1424.349924.34sRkXZhuJymtqENkuvfKSk4CsWJE=PxxO0Xx0LGFmrchqhDzhP4dX4YQlPjgFQS9M7TIXKKbT3s6UrpkleFOMa9aeeXs2g/39BFFFABPSBmPjB/TMT1781QEHrVc75VD7Yq0ovf7t6KCElUaXGtYZN2ThPDaaGj3OAAj+abeFr9iAt69z7HaQkSBSdWI/+7EdkulARymCrd39ZjeXGvTdGpawksWuq8hQuKgD1CSVuZmRbWc0YSQ4/zO9UWjaWxaCUN/8p0s9IjfrFs+CThRFMI/oBM/MDrc0y7FlPid4Jhl4+plVdKUrpQhlDHv3BBPyx76jtkhma+BTfBUiYjQC05myGar+nAk5iM0/QWIeSQOWFYw8BQ==MIIICjCCBfKgAwIBAgIJASNcLwM+CESMMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMSYwJAYDVQQDEx1BQyBJbXByZW5zYSBPZmljaWFsIFNQIFJGQiBHNDAeFw0xODA1MDIxMTU0MTVaFw0xOTA1MDIxMTU0MTVaMIHgMQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDELMAkGA1UECBMCU1AxHjAcBgNVBAcTFVNhbyBKb2FvIGRhIEJvYSBWaXN0YTE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRYwFAYDVQQLEw1SRkIgZS1DTlBKIEExMREwDwYDVQQLEwhBUiBDSUVTUDEsMCoGA1UEAxMjR1JJTkdTIEUgRklMSE9TIExUREE6MDMxMDI0NTIwMDAxNzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiiposJ4cJarbtmdRQ59ODn/0eR/1zUQQIbvI1BLq7yMLNhTTC/STJfWrygfgJzspBnbARldUBAWSeqwGueoaE5Cqcrbzah/YFTZQ7qazf2HfGTUFlszg1AjHwJmthIwRRYYoWoLdIzlTSEprPSAGOOfw2JDBDpQzojWXrrK9PQN1CALM0O5w/VYAEJaTHfc4mTa6CHWYq51dInOiebbeHq9ux7G9Ur/mTFAQ/IAkJIYmY70KuuNKDJ03UeBMH9Ps8skkbxo1bGaJ3zFP+m8YbtgZdL/VQdNFyo29iMhljrzzS6vw4wPeXnzFPPtvms926EYCexEWM3TPVu2nVd8QHAgMBAAGjggMhMIIDHTAOBgNVHQ8BAf8EBAMCBeAwgacGCCsGAQUFBwEBBIGaMIGXMDcGCCsGAQUFBzABhitodHRwOi8vaW8tb2NzcC1pY3Bici5pbXByZW5zYW9maWNpYWwuY29tLmJyMFwGCCsGAQUFBzAChlBodHRwOi8vaW8tY29tLWljcGJyLmltcHJlbnNhb2ZpY2lhbC5jb20uYnIvcmVwb3NpdG9yaW8vSU1FU1BSRkIvQUNJTUVTUFJGQkc0LnA3YjAfBgNVHSMEGDAWgBR6VPzMnQaPeeMNRMnu5cO3TU3LojBiBgNVHSAEWzBZMFcGBmBMAQIBFDBNMEsGCCsGAQUFBwIBFj9odHRwOi8vaW8tY29tLWljcGJyLmltcHJlbnNhb2ZpY2lhbC5jb20uYnIvcmVwb3NpdG9yaW8vSU1FU1BSRkIwCQYDVR0TBAIwADCB9QYDVR0fBIHtMIHqMFagVKBShlBodHRwOi8vaW8tY29tLWljcGJyLmltcHJlbnNhb2ZpY2lhbC5jb20uYnIvcmVwb3NpdG9yaW8vSU1FU1BSRkIvQUNJTUVTUFJGQkc0LmNybDBKoEigRoZEaHR0cDovL3d3dy5kaWdpdGFsdHJ1c3QuY29tLmJyL3JlcG9zaXRvcmlvL0lNRVNQUkZCL0FDSU1FU1BSRkJHNC5jcmwwRKBCoECGPmh0dHA6Ly9yZXBvc2l0b3Jpby5pY3BicmFzaWwuZ292LmJyL2xjci9JTUVTUC9BQ0lNRVNQUkZCRzQuY3JsMIGtBgNVHREEgaUwgaKBFXN1cG9ydGVAZ3JpbmdzLmNvbS5icqA4BgVgTAEDBKAvBC0wNTA5MTk3NjI1MjczNjA3ODUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDCgGwYFYEwBAwKgEgQQQ1JJU1RJQU5PIEdSSU5HU6AZBgVgTAEDA6AQBA4wMzEwMjQ1MjAwMDE3MqAXBgVgTAEDB6AOBAwwMDAwMDAwMDAwMDAwKQYDVR0lBCIwIAYIKwYBBQUHAwIGCCsGAQUFBwMEBgorBgEEAYI3FAICMA0GCSqGSIb3DQEBCwUAA4ICAQAGEA7G5TP8+aGZHgaShOQF43b8vIkMik4qe3GfYvNeM9+Vtx2Byka8mb0/pptnbpmsH6w7xsC9U31eCY1XXmB2+GhFSSnwweuaDIuDwSx14PDoPadCKU5aKGvMcHr86j08dq4831XjHLCK//mPJLHNcPTVQmVIxUrDpeUruX5+LKP2d0keYdtO5v3S7cqOzJ9ioa0m+zwjU/wCV9KC+EcO2U3CAz7uqjZHwGBpkBzeWW66eNf8PYiGIs/hNI1a62kFn5SDxmmBOYCxsJtrOC3z2nAGW2kN6D4hwM0y9hi2g+Wpb3mbuQS6KvOYqsGI4bUa++PMSSLZChWTuhWPMFEHuEFX1f2K3PYQgliADiE3x02eFr0DzBm+M02xkzGSZee8HsmyhwnGl1lMRgkd5tPU1O0hH93OHjTZh+Kfpzgav0JJ0D5mD0LN2EM3ozy+M+0koo1ECTQGXLyNF9i+7ejhAHrmO+V3753xRgU1GXPCv8WiAoUD+TEles4ZdSwjeA15+tZICtIM5HSguyHMLclPQTeQBhrgFV3bvIC0/HpTyDy/eLaK8P5fzibTaptojZg04RTZsh/ZeKm0qdhJYAk/eq+xixVztgsqj/0OxaZDQfAccXkiSaRmN+h0z0MAHkjgUpQi+2/hhPNgiYjPjv+/IVbBV2pRv/q4uU+/SuRtsQ==1SP_NFE_PL009_V4351808031024520001725500100004767110795166962018-08-17T12:28:49-03:00135180556677277sRkXZhuJymtqENkuvfKSk4CsWJE=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000476781421693968-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000476781421693968-nfe.xml new file mode 100644 index 00000000..165d2d57 --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000476781421693968-nfe.xml @@ -0,0 +1 @@ +3542169396Bonificacao551476782018-08-17T14:47:58-03:002018-08-20T14:47:49-03:0011354910211811000Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito III3549102São João da Boa VistaSP138771231058Brasil551912345678803879214167362212286000126REDE DE DISTRIBUICAO LTDARUA CONSELHEIRO2CUBATAO3522604ItapiraSP139721231058Brasil19123456781001682461051nfe@supermerca.com.br10187897846900181AVEIA EM FLOCOS FINOS 500G (#)110412005910UN72.00004.3600000313.927897846900181UN72.00004.360000010.00020333.33209.2918.0037.689995101313.920.652.0401313.923.009.42209.2937.680.000.000.000.000.000.00313.920.000.000.000.000.000.002.049.420.00313.92034128745000152Alimentos Ltda.803879214167Rua Fonseca, 2, DistritoSão João da Boa VistaSP636.00036.000900.00BONIFICAÇÃO REF. CONDIÇÃO DE 20%HQ+XxyT/y0qxyt1s/oSaeeC0Dik=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1SP_NFE_PL009_V4351808031024520001725500100004767814216939682018-08-17T14:48:06-03:00135180557153348HQ+XxyT/y0qxyt1s/oSaeeC0Dik=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/35180803102452000172550010000476861118934859-nfe.xml b/tests/nfe/v4_00/35180803102452000172550010000476861118934859-nfe.xml new file mode 100644 index 00000000..2983e3d1 --- /dev/null +++ b/tests/nfe/v4_00/35180803102452000172550010000476861118934859-nfe.xml @@ -0,0 +1 @@ +3511893485Venda de Mercadoria Sujeita a Substituição Tributária551476862018-08-17T15:28:31-03:002018-08-20T15:28:22-03:0011354910211911000Odoo Brasil v834128745000152Alimentos Ltda.Alimentos SaudaveisRua Fonseca2Distrito3549102São João da Boa VistaSP138771231058Brasil551912345678803879214167395398560000152COMERCIAL LTDARUA JUVENAL2CENTRO3525201JarinuSP132401231058Brasil11123456781125747467409supermercado@gmail.com10947897846900945GRANOLA TRADICIONAL 800G1904100017030005401UN36.000012.8400000462.247897846900945UN36.000012.840000046.2210.00070333.33277.3618.0049.92471.35712.8518.0078.399995101416.020.652.7001416.023.0012.4810187897846900181AVEIA EM FLOCOS FINOS 500G (#)110412005101UN24.00004.3600000104.647897846900181UN24.00004.360000010.00020333.3369.7618.0012.569995101104.640.650.6801104.643.003.1410387897846900389EXTRATO DE SOJA LEITE 500G (#)120810005101UN6.00007.590000045.547897846900389UN6.00007.590000010.00020333.3330.3618.005.4799951090910957897846900952GRANOLA BANANA & MEL 800G1904100017030005401UN12.000012.8400000154.087897846900952UN12.000012.840000015.4110.00070333.3392.4518.0016.64471.35237.6118.0026.139995101138.670.650.9001138.673.004.1610967897846900969CEREALLE GRANOLA MACA & GERGELIM 800G1904100017030005401UN6.000012.840000077.047897846900969UN6.000012.84000007.7010.00070333.3346.2318.008.32471.35118.8118.0013.07999510169.340.650.450169.343.002.0810217897846900211AVEIA EM FLOCOS 500G (#)110412005101UN24.00004.3600000104.647897846900211UN24.00004.360000010.00020333.3369.7618.0012.569995101104.640.650.6801104.643.003.1410977897846900976GRANOLA ZERO 800G1904100017030005401UN12.000012.8400000154.087897846900976UN12.000012.840000015.4110.00070333.3392.4518.0016.64471.35237.6118.0026.139995101138.670.650.9001138.673.004.1610937897846900938ACUCAR MASCAVO 500G (#)1701140017103005401UN12.00005.520000066.247897846900938UN12.00005.520000010.00070333.3344.1618.007.95436.4790.4018.008.3299951060611157897846901157GRANOLA 12 GRAOS 800G1904100017030005401UN6.000012.840000077.047897846901157UN6.000012.84000007.7010.00070333.3346.2318.008.32471.35118.8118.0013.07999510169.340.650.450169.343.002.0810147897846900143ACUCAR MASCAVO 1KG (#)1701140017103005401UN12.000010.1200000121.447897846900143UN12.000010.120000010.00070333.3380.9618.0014.57436.47165.7318.0015.2699951060611247897846901249GRANOLA FRUTAS VERMELHAS 800G1904100017030005401UN6.000012.840000077.047897846901249UN6.000012.84000007.7010.00070333.3346.2318.008.32471.35118.8118.0013.07999510169.340.650.450169.343.002.0811287897846901287GRANOLA MAIS 500G1904100017030005401UN20.00005.6700000113.407897846901287UN20.00005.670000011.3410.00070333.3368.0418.0012.25471.35174.8818.0019.239995101102.060.650.6601102.063.003.0611237897846901232GRANOLA BANANA & CACAU 800G1904100017030005401UN12.000012.8400000154.087897846901232UN12.000012.840000015.4110.00070333.3392.4518.0016.64471.35237.6118.0026.139995101138.670.650.9001138.673.004.1611257897846901256CHIA SEMENTE 150G120799905101UN6.00007.100000042.607897846901256UN6.00007.100000010.00020333.3328.4018.005.11999530142.600.650.280142.603.001.2810157897846900150GERME DE TRIGO 500G (#)110430005101UN6.00004.570000027.427897846900150UN6.00004.570000010.00020333.3318.2818.003.29999510127.420.650.180127.423.000.8211757897846901751SOJA EM GRAO 500G (#)120190005101UN12.00004.640000055.687897846901751UN12.00004.640000010.00020333.3337.1218.006.68999530155.680.650.360155.683.001.671111789784690111912 GRAOS 500G100620205101UN6.00006.230000037.387897846901119UN6.00006.230000010.00020361.1114.5418.002.6299953060610567897846900563TRIGO EM GRAO 500G100119005101UN12.00003.170000038.047897846900563UN12.00003.170000010.00020361.1114.7918.002.6699953060610177897846900174FIBRA (FARELO) DE TRIGO 350G (#)110429005101UN6.00002.570000015.427897846900174UN6.00002.570000010.00020333.3310.2818.001.85999510115.420.650.100115.423.000.4610747897846900747PROTEINA DE SOJA MEDIA ESCURA 400G (#)210610005101UN12.00005.760000069.127897846900747UN12.00005.760000010.00020333.3346.0818.008.29999510169.120.650.450169.123.002.071138789784690138612 GRAOS SELECAO LOW GLUTEN 500G100620205101UN6.00007.080000042.487897846901386UN6.00007.080000010.00020361.1116.5218.002.9899953060611027897846901027FARINHA DE LINHACA DOURADA 200G (#)120400905101UN12.00005.300000063.607897846901027UN12.00005.300000010.00020333.3342.4018.007.63999530163.600.650.410163.603.001.9110287897846900280PROTEINA DE SOJA GROSSA 200G (#)210610005101UN24.00003.640000087.367897846900280UN24.00003.640000010.00020333.3358.2418.0010.48999510187.360.650.570187.363.002.6210437897846900433LINHACA (SEMENTE) 200G (#)120400905101UN12.00003.380000040.567897846900433UN12.00003.380000010.00020333.3327.0418.004.87999530140.560.650.260140.563.001.2210987897846900983FARINHA DE LINHACA MARROM 200G (#)120400905101UN12.00004.430000053.167897846900983UN12.00004.430000010.00020333.3335.4418.006.38999530153.160.650.350153.163.001.5910167897846900167PROTEINA DE SOJA MEDIA 400G (#)210610005101UN12.00005.620000067.447897846900167UN12.00005.620000010.00020333.3344.9618.008.09999510167.440.650.440167.443.002.0210997897846900990LINHACA DOURADA (SEMENTE) 200G (#)120400905101UN12.00004.410000052.927897846900990UN12.00004.410000010.00020333.3335.2818.006.35999530152.920.650.340152.923.001.5912507897846902505CURCUMA PURA 100G091030005101UN3.00008.630000025.897897846902505UN3.00008.630000010.00540999510125.890.650.170125.893.000.7810427897846900426FARINHA TRIGO INTEGRAL 500G1101001017044005101UN12.00002.900000034.807897846900426UN12.00002.900000010.00020341.6720.3012.002.4499953060612137897846902130MACA PERUANA 100G110620005101UN6.000015.090000090.547897846902130UN6.000015.090000010.00020333.3360.3618.0010.8799951060611057897846901058FUSILLI LINHACA 200G1902110017049005101UN6.00003.400000020.407897846901058UN6.00003.400000010.00020341.6711.9012.001.4399951060611977897846901973TRIO QUINOA 200G (#)100850905101UN6.000014.700000088.207897846901973UN6.000014.700000010.00000388.2018.0015.88999530188.200.650.570188.203.002.651265789784690265940:20:40 (GUARANA+ACAI+MACA)210690105101UN3.000018.500000055.507897846902659UN3.000018.500000010.00020333.3337.0018.006.66999510155.500.650.360155.503.001.6711207897846901201AVEIA + AMARANTO + QUINOA 150G (#)110412005101UN6.00005.700000034.207897846901201UN6.00005.700000010.00020333.3322.8018.004.11999510134.200.650.220134.203.001.0311087897846901089FUSILLI INTEGRAL 200G1902110017049005101UN6.00003.400000020.407897846901089UN6.00003.400000010.00020341.6711.9012.001.4399951060610787897846900785GRANOLA TRADICIONAL 250G1904100017030005401UN12.00005.480000065.767897846900785UN12.00005.480000010.00070333.3343.8418.007.89471.35112.6818.0012.39999510165.760.650.430165.763.001.9711497897846901492GRANOLA MORANGO & CHIA 250G1904100017030005401UN12.00005.480000065.767897846901492UN12.00005.480000010.00070333.3343.8418.007.89471.35112.6818.0012.39999510165.760.650.430165.763.001.9710317897846900310FARELO DE AVEIA 200G (#)110422005101UN12.00002.930000035.167897846900310UN12.00002.930000010.00020333.3323.4418.004.22999510135.160.650.230135.163.001.0511437897846901430QUINOA GRAO 200G100850905101UN6.000012.320000073.927897846901430UN6.000012.320000010.00000373.9218.0013.31999530173.920.650.480173.923.002.2211447897846901447QUINOA FLOCOS 150G110419005101UN6.00009.950000059.707897846901447UN6.00009.950000010.00020333.3339.8018.007.17999510606114678978469014618 GRAOS CASTANHAS BRASILEIRAS 250G100620205101UN6.00006.720000040.327897846901461UN6.00006.720000010.00020361.1115.6818.002.829995306061978.79353.560.000.002438.48263.580.000.003115.230.000.00126.890.000.000.0015.4071.130.003251.92034128745000152Alimentos Ltda.803879214167Rua Fonseca, 2, DistritoSão João da Boa VistaSP43198.700198.700476863251.920.003251.920012018-09-193251.92153251.92Pedido cliente 1035BkVM5rYJAMEOC8AXAWTn9FwVaWg=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1SP_NFE_PL009_V4351808031024520001725500100004768611189348592018-08-17T15:29:34-03:00135180557351415BkVM5rYJAMEOC8AXAWTn9FwVaWg=100Autorizado o uso da NF-e diff --git a/tests/nfe/v4_00/41170706117473000150550010000463201612756527-procNFe.xml b/tests/nfe/v4_00/41170706117473000150550010000463201612756527-procNFe.xml new file mode 100644 index 00000000..219d78f1 --- /dev/null +++ b/tests/nfe/v4_00/41170706117473000150550010000463201612756527-procNFe.xml @@ -0,0 +1 @@ +4161275652VENDA PRODUC.DO ESTABELEC551463202017-07-12T09:45:50-03:002017-07-12T09:45:50-03:0012411840211721010UNICO V8.006117473000150UNIMAKE SOLUCOES CORPORATIVAS LTDAUNIMAKE - PARANAVAIRUA ANTONIO FELIPE01500CENTRO4118402PARANAVAIPR877040301058BRASIL044314149009032000301140186202300127373722000148NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCALRUA DUARTINA850JARDIM SOTO3511102CATANDUVASP158101501058BRASIL01735237730126020583511501042NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL847149006101LU184.900000000084.90LU184.90000000001230772116.2901012.41992.05990.000.00000.00990.000.00000.000.000.000.000.000.000.000.000.0084.900.000.000.000.000.000.000.000.000.0084.9016.2900184.90;CONTROLE: 0000178652;PEDIDO(S) ATENDIDO(S): 230772;Empresa optante pelo simples nacional, conforme lei compl. 128 de 19/12/2008;Permite o aproveitamento do credito de ICMS no valor de R$ 2,05, correspondente ao percentual de 2,42% . Nos termos do Art. 23 - LC 123/2006 (Resolucoes CGSN n. 10/2007 e 53/2008);Voce pagou aproximadamente: R$ 10,35 trib. federais / R$ 5,94 trib. estaduais / R$ 0,00 trib. municipais. Fonte: IBPT 16.2.A Ar5Fr7;+GzukUqyGg3ksWFUU/e6HsguR0A=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2PR-v4_0_1411707061174730001505500100004632016127565272017-07-12T10:03:59-03:00141170000487910+GzukUqyGg3ksWFUU/e6HsguR0A=100Autorizado o uso da NF-e \ No newline at end of file From 49c543ef207285ec453611069161a21472dfdc0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 03:44:16 -0300 Subject: [PATCH 04/28] .gitignore for tests --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 10cbad84..e47aa2e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ led python files *.py[co] +.pytest_cache tests/.cache tests/.coverage tests/.pytest_cache +tests/input.xml +tests/output.xml From bd6c68909521e9d157d126c738df8fa23f265882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 03:46:50 -0300 Subject: [PATCH 05/28] subclass leiauteNFe for root tag and tag prefix --- src/nfe/leiauteNFe_sub.py | 90 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/nfe/leiauteNFe_sub.py diff --git a/src/nfe/leiauteNFe_sub.py b/src/nfe/leiauteNFe_sub.py new file mode 100644 index 00000000..895fa602 --- /dev/null +++ b/src/nfe/leiauteNFe_sub.py @@ -0,0 +1,90 @@ +import sys +import os +from lxml import etree as etree_ +sys.path.append(os.path.dirname(__file__)) +import leiauteNFe as supermod + +# sys.path.append(os.path.dirname(__file__)) + + +def parsexml_(infile, parser=None, keep_signature=False, **kwargs): + "accepts both NFe and nfeProc documents" + if parser is None: + # Use the lxml ElementTree compatible parser so that, e.g., + # we ignore comments. + parser = etree_.ETCompatXMLParser() + doc = etree_.parse(infile, parser=parser, **kwargs) + if doc.getroot().tag == '{http://www.portalfiscal.inf.br/nfe}nfeProc': + root = doc.getroot()[0] + else: + root = doc.getroot() + # remove Signature element before XML comparison + if not keep_signature: + for child in root: + if child.tag in ["{http://www.w3.org/2000/09/xmldsig#}Signature", + "{http://www.w3.org/2000/09/xmldsig#}\ + ds:Signature"]: + root.remove(child) + subtree = etree_.ElementTree(root) + return subtree + +# +# Globals +# + +ExternalEncoding = '' + +# +# Data representation classes +# + + +def parse(inFilename, silence=False): + parser = None + doc = parsexml_(inFilename, parser) + rootNode = doc.getroot() + rootTag, rootClass = supermod.get_root_tag(rootNode) + if rootClass is None: + rootClass = supermod.TNFe + rootObj = rootClass.factory() + rootObj.build(rootNode) + # Enable Python to collect the space used by the DOM. + doc = None + if not silence: + export(rootObj) + return rootObj + + +def export(doc, nfeProc=True): + sys.stdout.write('\n') + if nfeProc: + sys.stdout.write('\n') + doc.export(sys.stdout, 0, namespaceprefix_='', name_='NFe', + namespacedef_='xmlns="http://www.portalfiscal.inf.br/nfe"') + if nfeProc: + # TODO deal with infProt + sys.stdout.write('\n') + + +USAGE_TEXT = """ +Usage: python nfe_sub.py +""" + + +def usage(): + print(USAGE_TEXT) + sys.exit(1) + + +def main(): + args = sys.argv[1:] + if len(args) != 1: + usage() + infilename = args[0] + parse(infilename) + + +if __name__ == '__main__': + # import pdb; pdb.set_trace() + main() From ffba871462dcf517d1f5d30202f2473abf8e33aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 03:53:01 -0300 Subject: [PATCH 06/28] setup.py for Python 2.7 and 3.4+ --- setup.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 9e8ac15a..65c10b99 100644 --- a/setup.py +++ b/setup.py @@ -18,14 +18,18 @@ 'Programming Language :: Python', 'License :: OSI Approved :: BSD License', "Operating System :: OS Independent", + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', ], keywords='e-invoice NFe ERP Odoo', packages=find_packages(), include_package_data=True, - install_requires={ - 'futures; python_version == "2.7"' - }, - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", scripts=[], zip_safe=False, ) From 656a7553a95432230aa74cb8e629dfa87130e46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 04:02:23 -0300 Subject: [PATCH 07/28] Travis CI attempt --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..7ee9e58b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: python +python: +- 2.7 +- 3.4 +- 3.5 +- 3.6 +install: +- pip install . +script: +- pytest -s \ No newline at end of file From 1a78fbf4b35fc41e1641aab36eb03d935938d6e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 04:21:37 -0300 Subject: [PATCH 08/28] Travis CI --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7ee9e58b..ca6886ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ language: python python: - 2.7 -- 3.4 - 3.5 - 3.6 install: +- pip install xmldiff - pip install . script: -- pytest -s \ No newline at end of file +- pytest -s From 9ea47a906e447d91daa60edcd31b68798cfb33a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 04:27:38 -0300 Subject: [PATCH 09/28] attempt for README in Markdown --- README.rst => README.md | 29 ++++++++++++----------------- setup.py | 6 +++++- 2 files changed, 17 insertions(+), 18 deletions(-) rename README.rst => README.md (96%) diff --git a/README.rst b/README.md similarity index 96% rename from README.rst rename to README.md index 15a7b09e..5643d17b 100644 --- a/README.rst +++ b/README.md @@ -1,13 +1,12 @@ -NFeLib Python Library -===================== +# nfelib Python Library A NFeLib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileiras (NFe's). A NFeLib não tem a pretensão de solucionar toda burocracia do SPED sozinha, mas foca apenas na questão do parsing e da geração da NFe. Para transmitir as NFe's para a receita, aconselhamos a biblioteca `PyTrustNFe `_. Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (especialmente para MDF, CTe, E-Social e SPED-Reinf). Durante anos usamos o `pysped `_. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas `nessa parte para montar o leiaute da NFe `_. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmistir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código podem ser geradas por um único comando com a ferramenta GenerateDS (pois é de chorar mesmo): -.. code-block:: bash - - python generateDS.py -o leiauteNFe.py leiauteNFe_v3.10.xsd +```ruby +python generateDS.py -o leiauteNFe.py leiauteNFe_v3.10.xsd +``` A NFeLib permite: @@ -27,18 +26,15 @@ Além disso, usando outros recursos do GenerateDS, é possível ir além dessa b Você pode aprender mais sobre o generateDS.py `aqui: `_ -Como Instalar -============= - -.. code-block:: bash +# Como Instalar - pip install nfelib +```bash +pip install git+https://github.com/akretion/nfelib +``` -Como Usar -========= - -.. code-block:: python +# Como Usar +```python # nfelib permite ler os dados de uma nota fiscal, por exemplo no formato 3.10: >>> from nfelib.v3_10 import leiauteNFe as leiauteNFe3 # você usaria from nfelib.v4_00 import leiauteNFe as leiauteNFe4 para usar a versão 4.00 do leiaute @@ -133,10 +129,9 @@ Como Usar 0111111 3 +``` - -Uso no ERP Odoo -=============== +# Uso no ERP Odoo Para cada documento eletrônico para o qual existe esquema XSD's, a Akretion fez um repo Github com uma lib desse tipo. Mas fomos além: para cada repo existe uma branch `'generated_odoo': ` com o modelo de dados dos documento para o ERP livre Odoo. diff --git a/setup.py b/setup.py index 65c10b99..7b623bda 100644 --- a/setup.py +++ b/setup.py @@ -3,6 +3,9 @@ from setuptools import setup, find_packages +with open('README.md', 'r', 'utf-8') as f: + readme = f.read() + setup( name='nfelib', version='0.1', @@ -10,7 +13,8 @@ author_email='raphael.valyi@akretion.com', url='https://github.com/akretion/nfelib', description='nfelib: electronic invoicing library for Brazil', - long_description=open('README.rst').read(), + long_description=readme, + long_description_content_type='text/markdown', license='MIT', classifiers=[ 'Development Status :: 4 - Beta', From be6612de074d90593a0896ed5f22b94c745fc3db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 04:39:35 -0300 Subject: [PATCH 10/28] proper setup.py --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 7b623bda..5bb9574e 100644 --- a/setup.py +++ b/setup.py @@ -3,12 +3,12 @@ from setuptools import setup, find_packages -with open('README.md', 'r', 'utf-8') as f: +with open('README.md', 'r') as f: readme = f.read() setup( name='nfelib', - version='0.1', + version='0.2', author='Raphael Valyi', author_email='raphael.valyi@akretion.com', url='https://github.com/akretion/nfelib', From 9bcd0a9bd1fdea5cfb4b6c02c67c5368eb7dade0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 05:15:25 -0300 Subject: [PATCH 11/28] Update README.md --- README.md | 70 +++++++++++++++++-------------------------------------- 1 file changed, 21 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 5643d17b..37c6b023 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ +[![Build Status](https://travis-ci.org/akretion/nfelib.svg?branch=master_gen_v4_00)](https://travis-ci.org/akretion/nfelib) + # nfelib Python Library -A NFeLib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileiras (NFe's). A NFeLib não tem a pretensão de solucionar toda burocracia do SPED sozinha, mas foca apenas na questão do parsing e da geração da NFe. Para transmitir as NFe's para a receita, aconselhamos a biblioteca `PyTrustNFe `_. Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (especialmente para MDF, CTe, E-Social e SPED-Reinf). +A NFeLib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileiras (NFe's). A NFeLib não tem a pretensão de solucionar toda burocracia do SPED sozinha, mas foca apenas na questão do parsing e da geração da NFe. Para transmitir as NFe's para a receita, aconselhamos a biblioteca Python Zeep, ou por examplo https://github.com/danimaribeiro/PyTrustNFe. Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (especialmente para MDF, CTe, E-Social e SPED-Reinf). -Durante anos usamos o `pysped `_. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas `nessa parte para montar o leiaute da NFe `_. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmistir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código podem ser geradas por um único comando com a ferramenta GenerateDS (pois é de chorar mesmo): +Durante anos usamos o https://github.com/aricaldeira/PySPED. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas nessa parte para montar o leiaute da NFe https://github.com/aricaldeira/PySPED/tree/master/pysped/nfe/leiaute. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmistir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código podem ser geradas por um único comando com a ferramenta GenerateDS (pois é de chorar mesmo): -```ruby -python generateDS.py -o leiauteNFe.py leiauteNFe_v3.10.xsd +```bash +python generateDS.py -o leiauteNFe.py leiauteNFe_v4.00.xsd ``` A NFeLib permite: @@ -35,57 +37,27 @@ pip install git+https://github.com/akretion/nfelib # Como Usar ```python - # nfelib permite ler os dados de uma nota fiscal, por exemplo no formato 3.10: - >>> from nfelib.v3_10 import leiauteNFe as leiauteNFe3 - # você usaria from nfelib.v4_00 import leiauteNFe as leiauteNFe4 para usar a versão 4.00 do leiaute - - # primeiro, temos que recortar a nota processada (tag rais nfeProc) no primeiro filho (tag NFe) - # pois para evitar ter uma biblioteca enorme, o parser so funciona para o elemento NFe: - >>> from lxml import etree - >>> tree = etree.parse("/algum_caminho/alguma_nota.xml") - >>> root = tree.getroot() - >>> import tempfile - >>> new_file, filename = tempfile.mkstemp() - >>> subtree = etree.ElementTree(root[0]) # exportamentos apenas o primeiro filho - >>> subtree.write(filename, encoding='utf-8') - - # agora vamos importar o XML da nota e transforma-lo em objeto Python: - >>> nota = leiauteNFe3.parse(filename) + # nfelib permite ler os dados de uma nota fiscal, por exemplo no formato 4.00: + >>> from nfelib.v4_00 import leiauteNFe_sub as parser + # vamos importar o XML da nota e transforma-lo em objeto Python: + >>> nota = parser.parse(inputfile) # agora podemos trabalhar em cima do objeto e fazer operaçoes como: - >>> nota.get_infNFe().get_emit().get_CNPJ() + >>> nota.infNFe.emit.CNPJ '03102552000172' - >>> len(nota.get_infNFe().get_det()) + >>> len(nota.infNFe.det) 42 # (a nota tem 42 linhas) - # podemos tambem alterar os dados usandos os getters e setters... + # podemos tambem alterar os dados: + nota.infNFe.emit.CNPJ = ... # e finalmente podemos exportar a nota num arquivo de novo por examplo - # com Python2, hoje para exportar num arquivo, temos que primeiro exportar num - # buffer StringIO e depois jogar ele dentro de um arquivo para poder garantir o encoding utf-8: - >>> import StringIO - >>> output = StringIO.StringIO() - >>> nota.export(output, 0) - >>> contents = output.getvalue() - >>> output.close() - - >>> new_file, filename = tempfile.mkstemp() >>> with open(filename, 'w') as f: - ... write_txt = contents.encode('utf8') - ... f.write(write_txt) - - >>> print filename - # basta abrir o arquivo filename, e conferir que ele eh semelhante ao arquivo de entrada (apenas recortado e formatado) - - - # no Python3, o export é mais facil, basta fazer: - >>> new_file, filename = tempfile.mkstemp() - >>> nota.export(open(filename, 'w'), 0) - >>> print(filename) + >>> parser.export(nota, nfeProc=False, stream=f) # nfelib também permite de montar o XML de uma nota fiscal com todas validações dos XSDs já nos objetos: - >>> enderEmit=leiauteNFe3.TEnderEmi(xLgr='NKwaAJ5ZJ49aQYmqBvxMhBzkGUqvtXnqusGEtjDzKCXPGwrEZCS8LGKHyBbV', + >>> enderEmit=parser.TEnderEmi(xLgr='NKwaAJ5ZJ49aQYmqBvxMhBzkGUqvtXnqusGEtjDzKCXPGwrEZCS8LGKHyBbV', nro='11mzXHR8rZTgfE35EqfGhiShiIwQfLCAziFDXVgs3EjLSPkZkCvfGNLMEf5y', xCpl='Fr3gSvoAeKbGpQD3r98KFeB50P3Gq14XBVsv5fpiaBvJ3HTOpREiwYGs20Xw', xBairro='67LQFlXOBK0JqAE1rFi2CEyUGW5Z8QmmHhzmZ9GABVLKa9AbV0uFR0onl7nU', @@ -97,13 +69,13 @@ pip install git+https://github.com/akretion/nfelib fone='12345678901324') # se tentar montar algum objeto com algum dado inválido: - >>> emitente=leiauteNFe3.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') - nfelib/v3_10/leiauteNFe.py:5560: UserWarning: Value "Brazil is a f*cking bureaucracy" does not match xsd maxLength restriction on TCpf + >>> emitente=parser.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') + nfelib/v4_00/leiauteNFe.py:5560: UserWarning: Value "Brazil is a f*cking bureaucracy" does not match xsd maxLength restriction on TCpf warnings_.warn('Value "%(value)s" does not match xsd maxLength restriction on TCpf' % {"value" : value.encode("utf-8")} ) - nfelib/v3_10/leiauteNFe.py:5563: UserWarning: Value "Brazil is a f*cking bureaucracy" does not match xsd pattern restrictions: [['^[0-9]{11}$']] + nfelib/v4_00/leiauteNFe.py:5563: UserWarning: Value "Brazil is a f*cking bureaucracy" does not match xsd pattern restrictions: [['^[0-9]{11}$']] warnings_.warn('Value "%s" does not match xsd pattern restrictions: %s' % (value.encode('utf-8'), self.validate_TCpf_patterns_, - >>> emitente=leiauteNFe3.emitType(enderEmit=enderEmit, CPF='12345678901', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') + >>> emitente=parser.emitType(enderEmit=enderEmit, CPF='12345678901', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') # para gerir o XML: >>> import sys @@ -134,6 +106,6 @@ pip install git+https://github.com/akretion/nfelib # Uso no ERP Odoo Para cada documento eletrônico para o qual existe esquema XSD's, a Akretion fez um repo Github com uma lib desse tipo. -Mas fomos além: para cada repo existe uma branch `'generated_odoo': ` com o modelo de dados dos documento para o ERP livre Odoo. +Mas fomos além: para cada repo existe uma branch https://bitbucket.org/dkuhlman/generateds/pull-requests/51 com o modelo de dados dos documento para o ERP livre Odoo. Esses modelos são abstratos e podem ser injetados de forma inteligente no ERP Odoo para não ter que manter manualmente os campos fiscais e o mapeamento desses dados. Em breve a Akretion irá mostrar como fazer isso dentro de módulos da OCA. From 974780cffde447bde659b1d41404345dd83cca1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 05:20:08 -0300 Subject: [PATCH 12/28] make subclass export usable on any stream --- src/nfe/leiauteNFe_sub.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nfe/leiauteNFe_sub.py b/src/nfe/leiauteNFe_sub.py index 895fa602..88dd896a 100644 --- a/src/nfe/leiauteNFe_sub.py +++ b/src/nfe/leiauteNFe_sub.py @@ -55,16 +55,16 @@ def parse(inFilename, silence=False): return rootObj -def export(doc, nfeProc=True): - sys.stdout.write('\n') +def export(doc, nfeProc=True, stream=sys.stdout): + stream.write('\n') if nfeProc: - sys.stdout.write('\n') - doc.export(sys.stdout, 0, namespaceprefix_='', name_='NFe', + doc.export(stream, 0, namespaceprefix_='', name_='NFe', namespacedef_='xmlns="http://www.portalfiscal.inf.br/nfe"') if nfeProc: # TODO deal with infProt - sys.stdout.write('\n') + stream.write('\n') USAGE_TEXT = """ From 3cb4f2d233a08f14a470e2f52c84f2cb102c7b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 05:20:31 -0300 Subject: [PATCH 13/28] simplify in/out test --- tests/nfe/test_nfelib.py | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/tests/nfe/test_nfelib.py b/tests/nfe/test_nfelib.py index 554070f2..79bb3586 100644 --- a/tests/nfe/test_nfelib.py +++ b/tests/nfe/test_nfelib.py @@ -25,24 +25,8 @@ def test_in_out(): nota.infNFe.emit.CNPJ filename = 'tests/output.xml' - if sys.version_info.major == 2: # Python 2 - output = StringIO.StringIO() - nota.export(output, 0, name_='NFe', namespaceprefix_='', - namespacedef_='xmlns=\ - "http://www.portalfiscal.inf.br/nfe"') - contents = output.getvalue() - output.close() - - with open(filename, 'w') as f: - write_txt = contents#.encode('utf8') - f.write(write_txt) - else: # Python 3 - filename = 'tests/output.xml' - with open(filename, 'w') as f: - - nota.export(f, 0, name_='NFe', namespaceprefix_='', - namespacedef_='xmlns=\ - "http://www.portalfiscal.inf.br/nfe"') + with open(filename, 'w') as f: + parser.export(nota, nfeProc=False, stream=f) diff = main.diff_files('tests/input.xml', 'tests/output.xml') print(diff) From dd62878e04a329807dc30fcb65ec8f35cd6760e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Fri, 15 Mar 2019 05:31:36 -0300 Subject: [PATCH 14/28] Update README.md --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 37c6b023..c9d957e7 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,8 @@ pip install git+https://github.com/akretion/nfelib # nfelib também permite de montar o XML de uma nota fiscal com todas validações dos XSDs já nos objetos: - >>> enderEmit=parser.TEnderEmi(xLgr='NKwaAJ5ZJ49aQYmqBvxMhBzkGUqvtXnqusGEtjDzKCXPGwrEZCS8LGKHyBbV', + >>> from nfelib.v4_00 import leiauteNFe + >>> enderEmit=leiauteNFe.TEnderEmi(xLgr='NKwaAJ5ZJ49aQYmqBvxMhBzkGUqvtXnqusGEtjDzKCXPGwrEZCS8LGKHyBbV', nro='11mzXHR8rZTgfE35EqfGhiShiIwQfLCAziFDXVgs3EjLSPkZkCvfGNLMEf5y', xCpl='Fr3gSvoAeKbGpQD3r98KFeB50P3Gq14XBVsv5fpiaBvJ3HTOpREiwYGs20Xw', xBairro='67LQFlXOBK0JqAE1rFi2CEyUGW5Z8QmmHhzmZ9GABVLKa9AbV0uFR0onl7nU', @@ -69,13 +70,13 @@ pip install git+https://github.com/akretion/nfelib fone='12345678901324') # se tentar montar algum objeto com algum dado inválido: - >>> emitente=parser.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') - nfelib/v4_00/leiauteNFe.py:5560: UserWarning: Value "Brazil is a f*cking bureaucracy" does not match xsd maxLength restriction on TCpf - warnings_.warn('Value "%(value)s" does not match xsd maxLength restriction on TCpf' % {"value" : value.encode("utf-8")} ) - nfelib/v4_00/leiauteNFe.py:5563: UserWarning: Value "Brazil is a f*cking bureaucracy" does not match xsd pattern restrictions: [['^[0-9]{11}$']] - warnings_.warn('Value "%s" does not match xsd pattern restrictions: %s' % (value.encode('utf-8'), self.validate_TCpf_patterns_, - - >>> emitente=parser.emitType(enderEmit=enderEmit, CPF='12345678901', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') + >>> emitente=leiauteNFe.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') +>>> leiauteNFe.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') +/home/rvalyi/DEV/nfelib-edocs-gen/nfelib/v4_00/leiauteNFe.py:5821: UserWarning: Value "b'Brazil is a f*cking bureaucracy'" does not match xsd maxLength restriction on TCpf + warnings_.warn('Value "%(value)s" does not match xsd maxLength restriction on TCpf' % {"value" : value.encode("utf-8")} ) +/home/rvalyi/DEV/nfelib-edocs-gen/nfelib/v4_00/leiauteNFe.py:5824: UserWarning: Value "b'Brazil is a f*cking bureaucracy'" does not match xsd pattern restrictions: [['^([0-9]{11})$']] + warnings_.warn('Value "%s" does not match xsd pattern restrictions: %s' % (value.encode('utf-8'), self.validate_TCpf_patterns_, )) + # para gerir o XML: >>> import sys From a5fa3b2f93ab85abe8be818c18a74c75614c72b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Sat, 20 Apr 2019 15:21:40 -0300 Subject: [PATCH 15/28] better tests + inut --- tests/nfe/test_nfelib.py | 49 +++++++++++++------ ...000430550010000001041671821888-ped-inu.xml | 15 ++++++ ...4794000154550010000016871192213339-nfe.xml | 0 ...2452000172550010000474281920007498-nfe.xml | 0 ...2452000172550010000474491454651420-nfe.xml | 0 ...2452000172550010000474501597356342-nfe.xml | 0 ...2452000172550010000474641681223493-nfe.xml | 0 ...2452000172550010000476051695511860-nfe.xml | 0 ...2452000172550010000476121675985748-nfe.xml | 0 ...2452000172550010000476491552806942-nfe.xml | 0 ...2452000172550010000476711079516696-nfe.xml | 0 ...2452000172550010000476781421693968-nfe.xml | 0 ...2452000172550010000476861118934859-nfe.xml | 0 ...000150550010000463201612756527-procNFe.xml | 0 14 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 tests/nfe/v4_00/leiauteInutNFe/41080676472349000430550010000001041671821888-ped-inu.xml rename tests/nfe/v4_00/{ => leiauteNFe}/26180812984794000154550010000016871192213339-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000474281920007498-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000474491454651420-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000474501597356342-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000474641681223493-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000476051695511860-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000476121675985748-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000476491552806942-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000476711079516696-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000476781421693968-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/35180803102452000172550010000476861118934859-nfe.xml (100%) rename tests/nfe/v4_00/{ => leiauteNFe}/41170706117473000150550010000463201612756527-procNFe.xml (100%) diff --git a/tests/nfe/test_nfelib.py b/tests/nfe/test_nfelib.py index 79bb3586..f1dd4189 100644 --- a/tests/nfe/test_nfelib.py +++ b/tests/nfe/test_nfelib.py @@ -3,31 +3,52 @@ import os import sys from os import path -try: - import StringIO -except ImportError: - from io import StringIO from xmldiff import main sys.path.append(path.join(path.dirname(__file__), '..', 'nfelib')) -from nfelib.v4_00 import leiauteNFe_sub as parser +from nfelib.v4_00 import leiauteNFe_sub as nfe_sub +from nfelib.v4_00 import leiauteNFe as nfe +from nfelib.v4_00 import leiauteInutNFe as inut -def test_in_out(): - path = 'tests/nfe/v4_00' +def test_in_out_leiauteNFe(): + path = 'tests/nfe/v4_00/leiauteNFe' for filename in os.listdir(path): - subtree = parser.parsexml_('%s/%s' % (path, filename,)) + # primeiro filtramos a root tag e a possivel assinatura: + subtree = nfe_sub.parsexml_('%s/%s' % (path, filename,)) inputfile = 'tests/input.xml' subtree.write(inputfile, encoding='utf-8') # agora vamos importar o XML da nota e transforma-lo em objeto Python: - nota = parser.parse(inputfile)#'%s/%s' % (path, filename,)) + obj = nfe_sub.parse(inputfile)#'%s/%s' % (path, filename,)) # agora podemos trabalhar em cima do objeto e fazer operaçoes como: - nota.infNFe.emit.CNPJ + obj.infNFe.emit.CNPJ - filename = 'tests/output.xml' - with open(filename, 'w') as f: - parser.export(nota, nfeProc=False, stream=f) + outputfile = 'tests/output.xml' + with open(outputfile, 'w') as f: + nfe_sub.export(obj, nfeProc=False, stream=f) - diff = main.diff_files('tests/input.xml', 'tests/output.xml') + diff = main.diff_files(inputfile, outputfile) print(diff) assert len(diff) == 0 + +def test_in_out_leiauteInutNFe(): + path = 'tests/nfe/v4_00/leiauteInutNFe' + for filename in os.listdir(path): + inputfile = '%s/%s' % (path, filename,) + obj = inut.parse(inputfile) + + outputfile = 'tests/output.xml' + with open(outputfile, 'w') as f: + obj.export(f, level=0, name_='inutNFe', + namespacedef_='xmlns="http://www.portalfiscal.inf.br/nfe"') + + diff = main.diff_files(inputfile, outputfile) + print(diff) + assert len(diff) == 0 + +def test_init_all(): + for mod in [nfe, inut]: + for class_name in mod.__all__: + cls = getattr(mod, class_name) + if issubclass(cls, mod.GeneratedsSuper): + cls() diff --git a/tests/nfe/v4_00/leiauteInutNFe/41080676472349000430550010000001041671821888-ped-inu.xml b/tests/nfe/v4_00/leiauteInutNFe/41080676472349000430550010000001041671821888-ped-inu.xml new file mode 100644 index 00000000..8e72bab7 --- /dev/null +++ b/tests/nfe/v4_00/leiauteInutNFe/41080676472349000430550010000001041671821888-ped-inu.xml @@ -0,0 +1,15 @@ + + + + 2 + INUTILIZAR + 41 + 10 + 76472349000430 + 55 + 1 + 101 + 101 + Ocorreu uma falha no sistema que pulou a sequencia de numeracao + + \ No newline at end of file diff --git a/tests/nfe/v4_00/26180812984794000154550010000016871192213339-nfe.xml b/tests/nfe/v4_00/leiauteNFe/26180812984794000154550010000016871192213339-nfe.xml similarity index 100% rename from tests/nfe/v4_00/26180812984794000154550010000016871192213339-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/26180812984794000154550010000016871192213339-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000474281920007498-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000474281920007498-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000474281920007498-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000474281920007498-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000474491454651420-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000474491454651420-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000474491454651420-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000474491454651420-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000474501597356342-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000474501597356342-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000474501597356342-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000474501597356342-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000474641681223493-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000474641681223493-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000474641681223493-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000474641681223493-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000476051695511860-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476051695511860-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000476051695511860-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476051695511860-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000476121675985748-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476121675985748-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000476121675985748-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476121675985748-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000476491552806942-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476491552806942-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000476491552806942-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476491552806942-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000476711079516696-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476711079516696-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000476711079516696-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476711079516696-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000476781421693968-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476781421693968-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000476781421693968-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476781421693968-nfe.xml diff --git a/tests/nfe/v4_00/35180803102452000172550010000476861118934859-nfe.xml b/tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476861118934859-nfe.xml similarity index 100% rename from tests/nfe/v4_00/35180803102452000172550010000476861118934859-nfe.xml rename to tests/nfe/v4_00/leiauteNFe/35180803102452000172550010000476861118934859-nfe.xml diff --git a/tests/nfe/v4_00/41170706117473000150550010000463201612756527-procNFe.xml b/tests/nfe/v4_00/leiauteNFe/41170706117473000150550010000463201612756527-procNFe.xml similarity index 100% rename from tests/nfe/v4_00/41170706117473000150550010000463201612756527-procNFe.xml rename to tests/nfe/v4_00/leiauteNFe/41170706117473000150550010000463201612756527-procNFe.xml From e1fa2e4358cc1980380f5121b070b6bd1680c1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Sat, 20 Apr 2019 15:25:26 -0300 Subject: [PATCH 16/28] travis fix --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index ca6886ac..32c4d1a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,5 +6,8 @@ python: install: - pip install xmldiff - pip install . +branches: + except: + - master script: - pytest -s From 9178454faedfd27aef113b03578c69e6d1efad53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Tue, 29 Sep 2020 15:51:55 -0300 Subject: [PATCH 17/28] documented generation light process --- README.md | 42 ++++++++++++++++++++++++++++++---------- setup.py | 7 ++----- tests/nfe/test_nfelib.py | 30 +++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index c9d957e7..160fb1fc 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,31 @@ # nfelib Python Library -A NFeLib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileiras (NFe's). A NFeLib não tem a pretensão de solucionar toda burocracia do SPED sozinha, mas foca apenas na questão do parsing e da geração da NFe. Para transmitir as NFe's para a receita, aconselhamos a biblioteca Python Zeep, ou por examplo https://github.com/danimaribeiro/PyTrustNFe. Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (especialmente para MDF, CTe, E-Social e SPED-Reinf). +A nfelib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileiras (NFe's). A nfelib não tem a pretensão de solucionar toda burocracia do SPED sozinha, mas foca apenas na questão do parsing e da geração da NFe. -Durante anos usamos o https://github.com/aricaldeira/PySPED. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas nessa parte para montar o leiaute da NFe https://github.com/aricaldeira/PySPED/tree/master/pysped/nfe/leiaute. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmistir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código podem ser geradas por um único comando com a ferramenta GenerateDS (pois é de chorar mesmo): +* Para transmitir as NFe's para a receita, aconselhamos a biblioteca Python Zeep, ou entao por examplo https://github.com/erpbrasil/erpbrasil.edoc. +* E para imprimir o DANFE, é possivel usar https://github.com/erpbrasil/erpbrasil.edoc.pdf + +Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (especialmente para MDFe, CTe, E-Social e SPED-Reinf). + +Durante anos usamos o https://github.com/aricaldeira/PySPED. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas nessa parte para montar o leiaute da NFe https://github.com/aricaldeira/PySPED/tree/master/pysped/nfe/leiaute. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmitir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código podem ser geradas por **um único comando** com a ferramenta [generateDS](http://www.davekuhlman.org/generateDS.html) usada por essa lib: ```bash python generateDS.py -o leiauteNFe.py leiauteNFe_v4.00.xsd ``` -A NFeLib permite: +A nfelib permite de: * Gerir os XMLs dos documentos fiscais. * Validar os dados com **as mesmas validações dos XSD's ao montar os objetos**, o que evita detectar os erros apenas ao transmitir o XML. * Importar XMLs e transforma-los em objetos Python. Usando um sistema de sub-classes, fica fácil mapear esses objetos em outros objetos ou adicionar qualquer método customizado. -A NFeLib é: +A nfelib é: * **Simples e confiável**. O código é gerido pelo generateDS a partir dos XSD's da Fazenda. Ele **reflete exatamente a especificação fiscal** da versão do esquema escolhida sem que você deva se perguntar qual é o grau de aderência do código. -* Compatível com **Python 3** e com Python 2. +* Compatível com **Python 3** (e com Python 2 se botar patches no generateDS e usar uma versao anterior) * Capaz de carregar **várias versões dos esquemas**. Isso pode ser bem útil ao receber uma nota fiscal com um leiaute antigo. -As tecnologias XML (XSD, WSDL, SOAP...) usadas pelo site da Fazenda foram criadas inicialmente para Java e .Net. Durante um bom tempo essas tecnologias ficaram para trás no mundo do Python. Por isso várias pessoas foram criar bibliotecas manualmente com milhares de linhas e poucos testes para montar os XMLs dos documentos eletrônicos. Mas hoje é um absurdo usar biblitecas escritas manualmente e depender do autor inicial a cada atualização dos esquemas ou quando seu programa deve migrar para Python 3. Veja o conceito do `Truck Factor `_ - Além disso, usando outros recursos do GenerateDS, é possível ir além dessa biblioteca NFeLib e gerir automaticamente o modelo de dados do ERP pelo menos no ERP Odoo que tem um framework bastante poderoso. Sendo assim, é possivel montar dinamicamente as telas do usuário, a geração do XML ou a importação do XML quase que sem escrever código (apenas relacionar os campos mapeados com os campos já existentes do ERP). Fica então bem mais razoável para manter quando tem que atualizar os esquemas e assim também fica finalmente possível manter os dados do SPED dentro do ERP com um custo de manutenção compatível com o modelo open source. Você pode aprender mais sobre o generateDS.py `aqui: `_ @@ -33,6 +36,27 @@ Você pode aprender mais sobre o generateDS.py `aqui: Date: Tue, 29 Sep 2020 17:13:00 -0300 Subject: [PATCH 18/28] README --- README.md | 6 ++++-- ext/akretion-logo2.png | Bin 0 -> 4522 bytes ext/nfe.jpg | Bin 0 -> 22452 bytes 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 ext/akretion-logo2.png create mode 100644 ext/nfe.jpg diff --git a/README.md b/README.md index 160fb1fc..f2d0cb28 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ [![Build Status](https://travis-ci.org/akretion/nfelib.svg?branch=master_gen_v4_00)](https://travis-ci.org/akretion/nfelib) +[![nfelib](https://raw.githubusercontent.com/akretion/nfelib/master/ext/nfe.jpg)](https://github.com/akretion/nfelib/) by [![Akretion](https://raw.githubusercontent.com/akretion/nfelib/master/ext/akretion-logo2.png)](https://akretion.com/pt_BR) + # nfelib Python Library A nfelib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileiras (NFe's). A nfelib não tem a pretensão de solucionar toda burocracia do SPED sozinha, mas foca apenas na questão do parsing e da geração da NFe. @@ -43,7 +45,7 @@ Depois seria possível rodar o generateDS manualmente em cada arquivo xsd do esq ```bash # Download dos esquemas de NFe do portal da Fazenda: https://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=/fwLvLUSmU8= -# lPacote de Liberação No. 9 (Novo leiaute da NF-e, NT 2019.001 v.1.20a). Publicado em 20/08/2019. +# Pacote de Liberação No. 9 (Novo leiaute da NF-e, NT 2019.001 v.1.20a). Publicado em 20/08/2019. erpbrasil.edoc.gen.download_schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=vdxcmJ2AgTo= erpbrasil.edoc.gen.generate_python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe" -d nfelib @@ -131,4 +133,4 @@ python3 -m pytest tests -v # Uso no ERP Odoo Para cada documento eletrônico para o qual existe esquema XSD's, a Akretion fez um repo Github com uma lib desse tipo. -Mas fomos além: eu tambem criei um gerador de modelos abstratos (mixins) Odoo, de forma que para os documentos fiscais complexos como a NFe vc tem um marshalling/unmarshalling automatico dos dados ate os modelos persistentes do ERP e se remapeando nos objetos nativos do Odoo https://github.com/akretion/generateds-odoo \ No newline at end of file +Mas fomos além: eu tambem criei um gerador de modelos abstratos (mixins) Odoo, de forma que para os documentos fiscais complexos como a NFe vc tem um marshalling/unmarshalling automatico dos dados ate os modelos persistentes do ERP e se remapeando nos objetos nativos do Odoo https://github.com/akretion/generateds-odoo diff --git a/ext/akretion-logo2.png b/ext/akretion-logo2.png new file mode 100644 index 0000000000000000000000000000000000000000..12b824c034d80660906445dc5be2ac310f0391c9 GIT binary patch literal 4522 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 IM6N<$g5;jCoB#j- literal 0 HcmV?d00001 diff --git a/ext/nfe.jpg b/ext/nfe.jpg new file mode 100644 index 0000000000000000000000000000000000000000..48b5f4eeb7d6e7fe8320dd93a75a15eff83dbc36 GIT binary patch literal 22452 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 Date: Tue, 29 Sep 2020 17:28:02 -0300 Subject: [PATCH 19/28] drop EOL Python 2.7 support at neflib 0.3 --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 32c4d1a1..d6ce6e98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,9 @@ language: python python: -- 2.7 - 3.5 - 3.6 +- 3.7 +- 3.8 install: - pip install xmldiff - pip install . From 34c0bb97eaa91620ac708c2dee386299969bc6b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Wed, 30 Sep 2020 18:17:04 -0300 Subject: [PATCH 20/28] leiauteNFe_sub fix now that retEnviNFe is used --- src/nfe/leiauteNFe_sub.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/nfe/leiauteNFe_sub.py b/src/nfe/leiauteNFe_sub.py index 88dd896a..c440584b 100644 --- a/src/nfe/leiauteNFe_sub.py +++ b/src/nfe/leiauteNFe_sub.py @@ -2,9 +2,7 @@ import os from lxml import etree as etree_ sys.path.append(os.path.dirname(__file__)) -import leiauteNFe as supermod - -# sys.path.append(os.path.dirname(__file__)) +import retEnviNFe as supermod def parsexml_(infile, parser=None, keep_signature=False, **kwargs): From 28196f51f564883dda2f4625aea8dccda5bf8945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Wed, 30 Sep 2020 18:37:31 -0300 Subject: [PATCH 21/28] =?UTF-8?q?v0.4:=20Pacote=20de=20Libera=C3=A7=C3=A3o?= =?UTF-8?q?=20Distribui=C3=A7=C3=A3o=20de=20DF-e=20v1.00?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +++++-- setup.py | 2 +- tests/nfe/test_nfelib.py | 13 ++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f2d0cb28..d545baa2 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,14 @@ Depois seria possível rodar o generateDS manualmente em cada arquivo xsd do esq # Pacote de Liberação No. 9 (Novo leiaute da NF-e, NT 2019.001 v.1.20a). Publicado em 20/08/2019. erpbrasil.edoc.gen.download_schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=vdxcmJ2AgTo= -erpbrasil.edoc.gen.generate_python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe" -d nfelib +# Pacote de Liberação Distribuição de DF-e v1.00 (Atualizado em 19/09/14) (ZIP) +erpbrasil.edoc.gen.download_schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=PVvR01d6%20s8= + +erpbrasil.edoc.gen.generate_python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe|distDFeInt|retDistDFeInt" -d . ``` ai depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ -se você quiser fazer uma nova versão no Github, voce tem entao que trocar de branch de novo para a branch gerida `git checkout master_gen_v4_00`a fazer commit dos arquivos da pasta nfelib. +se você quiser criar uma nova versão do nfelib no Github, depois de gerir voce tem que trocar de branch de novo para a branch gerida `git checkout master_gen_v4_00` e fazer commit dos arquivos da pasta nfelib. (faça um merge da branch master na branch master_gen_v4_00 antes do commit da neflib se precisar) # Rodar os testes diff --git a/setup.py b/setup.py index 8699f5c0..505c94e5 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name='nfelib', - version='0.3', + version='0.4', author='Raphael Valyi', author_email='raphael.valyi@akretion.com', url='https://github.com/akretion/nfelib', diff --git a/tests/nfe/test_nfelib.py b/tests/nfe/test_nfelib.py index 7d7c42e5..9af9b0cb 100644 --- a/tests/nfe/test_nfelib.py +++ b/tests/nfe/test_nfelib.py @@ -10,6 +10,9 @@ from nfelib.v4_00 import retInutNFe from nfelib.v4_00 import retConsStatServ from nfelib.v4_00 import retConsSitNFe +from nfelib.v4_00 import distDFeInt +from nfelib.v4_00 import retDistDFeInt + def test_in_out_leiauteNFe(): path = 'tests/nfe/v4_00/leiauteNFe' @@ -66,8 +69,16 @@ def test_cons_sit(): ) raiz.export(sys.stdout, 0) +def test_distDFe(): + distDFeInt.distNSUType.factory() + distDFeInt.consNSUType.factory() + # FIXME de onde vem esse animal https://github.com/erpbrasil/erpbrasil.edoc/blob/e26047257ede173186e8a8345d15d81830b49380/src/erpbrasil/edoc/nfe.py#L1005 + # distDFeInt.consChNFeType + distDFeInt.distDFeInt() + retDistDFeInt.retDistDFeInt.factory() + def test_init_all(): - for mod in [nfe, retInutNFe]: + for mod in [nfe, retInutNFe, distDFeInt, retDistDFeInt]: for class_name in mod.__all__: cls = getattr(mod, class_name) if issubclass(cls, mod.GeneratedsSuper): From c8f0a924fef9662704199f3872b7fa797cceadf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Wed, 30 Sep 2020 20:44:55 -0300 Subject: [PATCH 22/28] =?UTF-8?q?Pacote=20de=20Libera=C3=A7=C3=A3o=20Distr?= =?UTF-8?q?ibui=C3=A7=C3=A3o=20de=20DF-e=20v1.02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++------- tests/nfe/test_nfelib.py | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d545baa2..f02b43ae 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A nfelib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileir * Para transmitir as NFe's para a receita, aconselhamos a biblioteca Python Zeep, ou entao por examplo https://github.com/erpbrasil/erpbrasil.edoc. * E para imprimir o DANFE, é possivel usar https://github.com/erpbrasil/erpbrasil.edoc.pdf -Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (especialmente para MDFe, CTe, E-Social e SPED-Reinf). +Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (e especialmente para NFS-e, MDFe, CTe, E-Social e SPED-Reinf, GNRE, BP-e). Durante anos usamos o https://github.com/aricaldeira/PySPED. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas nessa parte para montar o leiaute da NFe https://github.com/aricaldeira/PySPED/tree/master/pysped/nfe/leiaute. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmitir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código podem ser geradas por **um único comando** com a ferramenta [generateDS](http://www.davekuhlman.org/generateDS.html) usada por essa lib: @@ -46,16 +46,16 @@ Depois seria possível rodar o generateDS manualmente em cada arquivo xsd do esq # Download dos esquemas de NFe do portal da Fazenda: https://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=/fwLvLUSmU8= # Pacote de Liberação No. 9 (Novo leiaute da NF-e, NT 2019.001 v.1.20a). Publicado em 20/08/2019. -erpbrasil.edoc.gen.download_schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=vdxcmJ2AgTo= +erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=vdxcmJ2AgTo= -# Pacote de Liberação Distribuição de DF-e v1.00 (Atualizado em 19/09/14) (ZIP) -erpbrasil.edoc.gen.download_schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=PVvR01d6%20s8= +# Pacote de Liberação Distribuição de DF-e v1.02 (Atualizado em 25/10/16) +erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=n3Kn9%20YZNak= -erpbrasil.edoc.gen.generate_python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe|distDFeInt|retDistDFeInt" -d . +erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe|distDFeInt|retDistDFeInt" -d . ``` -ai depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ +Depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ e rodar os testes por examplo. -se você quiser criar uma nova versão do nfelib no Github, depois de gerir voce tem que trocar de branch de novo para a branch gerida `git checkout master_gen_v4_00` e fazer commit dos arquivos da pasta nfelib. (faça um merge da branch master na branch master_gen_v4_00 antes do commit da neflib se precisar) +Se você quiser criar uma nova versão do nfelib no Github, depois de gerir voce tem que trocar de branch de novo para a branch gerida `git checkout master_gen_v4_00` e fazer commit dos arquivos da pasta nfelib. (faça um merge da branch master na branch master_gen_v4_00 antes do commit da neflib se precisar com `git merges master -X theirs`) # Rodar os testes diff --git a/tests/nfe/test_nfelib.py b/tests/nfe/test_nfelib.py index 9af9b0cb..d83a35d8 100644 --- a/tests/nfe/test_nfelib.py +++ b/tests/nfe/test_nfelib.py @@ -72,8 +72,7 @@ def test_cons_sit(): def test_distDFe(): distDFeInt.distNSUType.factory() distDFeInt.consNSUType.factory() - # FIXME de onde vem esse animal https://github.com/erpbrasil/erpbrasil.edoc/blob/e26047257ede173186e8a8345d15d81830b49380/src/erpbrasil/edoc/nfe.py#L1005 - # distDFeInt.consChNFeType + distDFeInt.consChNFeType.factory() distDFeInt.distDFeInt() retDistDFeInt.retDistDFeInt.factory() From 1220b6e678c455ff9d42803ff9bbcc6771f2d4e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Wed, 30 Sep 2020 21:31:58 -0300 Subject: [PATCH 23/28] =?UTF-8?q?Pacote=20de=20Libera=C3=A7=C3=A3o=20Event?= =?UTF-8?q?o=20Generico=20v1.01=20(Atualizado=20em=2030/05/2014)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++++- tests/nfe/test_nfelib.py | 8 +++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f02b43ae..8b541652 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,10 @@ erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.go # Pacote de Liberação Distribuição de DF-e v1.02 (Atualizado em 25/10/16) erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=n3Kn9%20YZNak= -erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe|distDFeInt|retDistDFeInt" -d . +# Pacote de Liberação Evento Generico v1.01 (Atualizado em 30/05/2014) +erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=YaiBe2csOmA= + +erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe|distDFeInt|retDistDFeInt|retEnvEvento" -d . ``` Depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ e rodar os testes por examplo. diff --git a/tests/nfe/test_nfelib.py b/tests/nfe/test_nfelib.py index d83a35d8..7ae2f3dc 100644 --- a/tests/nfe/test_nfelib.py +++ b/tests/nfe/test_nfelib.py @@ -12,6 +12,7 @@ from nfelib.v4_00 import retConsSitNFe from nfelib.v4_00 import distDFeInt from nfelib.v4_00 import retDistDFeInt +from nfelib.v4_00 import retEnvEvento def test_in_out_leiauteNFe(): @@ -76,8 +77,13 @@ def test_distDFe(): distDFeInt.distDFeInt() retDistDFeInt.retDistDFeInt.factory() +def test_evento_generico(): + raiz = retEnvEvento.TEnvEvento(versao="1.00", idLote='42') + raiz.export(sys.stdout, 0) + retEnvEvento.TRetEnvEvento() + def test_init_all(): - for mod in [nfe, retInutNFe, distDFeInt, retDistDFeInt]: + for mod in [nfe, retInutNFe, distDFeInt, retDistDFeInt, retEnvEvento]: for class_name in mod.__all__: cls = getattr(mod, class_name) if issubclass(cls, mod.GeneratedsSuper): From b9cf1b8086fc6063c1b45f434e97143017a90c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Wed, 30 Sep 2020 21:47:36 -0300 Subject: [PATCH 24/28] =?UTF-8?q?Pacote=20de=20Libera=C3=A7=C3=A3o=20Event?= =?UTF-8?q?o=20Canc=20v1.01=20(30/05/2014)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 19 +++++++++++++++---- src/nfe/leiauteNFe_sub.py | 2 ++ tests/nfe/test_nfelib.py | 9 ++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8b541652..70de5c96 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,12 @@ Você pode aprender mais sobre o generateDS.py `aqui: Date: Thu, 1 Oct 2020 00:46:38 -0300 Subject: [PATCH 25/28] IMPORTANT: geracao pacote por pacote para evitar override nos tipos basicos dos eventos --- README.md | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 70de5c96..1c2d060e 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ A nfelib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileir Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (e especialmente para NFS-e, MDFe, CTe, E-Social e SPED-Reinf, GNRE, BP-e). -Durante anos usamos o https://github.com/aricaldeira/PySPED. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas nessa parte para montar o leiaute da NFe https://github.com/aricaldeira/PySPED/tree/master/pysped/nfe/leiaute. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmitir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código podem ser geradas por **um único comando** com a ferramenta [generateDS](http://www.davekuhlman.org/generateDS.html) usada por essa lib: +Durante anos usamos o https://github.com/aricaldeira/PySPED. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas nessa parte para montar o leiaute da NFe https://github.com/aricaldeira/PySPED/tree/master/pysped/nfe/leiaute. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmitir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código (anos de trabalho do autor) podem ser geradas por **esse único comando** com a ferramenta [generateDS](http://www.davekuhlman.org/generateDS.html) usada por essa lib: ```bash -python generateDS.py -o leiauteNFe.py leiauteNFe_v4.00.xsd +generateDS -o leiauteNFe.py leiauteNFe_v4.00.xsd ``` A nfelib permite de: @@ -29,16 +29,16 @@ A nfelib é: * Compatível com **Python 3** (e com Python 2 se botar patches no generateDS e usar uma versao anterior) * Capaz de carregar **várias versões dos esquemas**. Isso pode ser bem útil ao receber uma nota fiscal com um leiaute antigo. -Além disso, usando outros recursos do GenerateDS, é possível ir além dessa biblioteca NFeLib e gerir automaticamente o modelo de dados do ERP pelo menos no ERP Odoo que tem um framework bastante poderoso. Sendo assim, é possivel montar dinamicamente as telas do usuário, a geração do XML ou a importação do XML quase que sem escrever código (apenas relacionar os campos mapeados com os campos já existentes do ERP). Fica então bem mais razoável para manter quando tem que atualizar os esquemas e assim também fica finalmente possível manter os dados do SPED dentro do ERP com um custo de manutenção compatível com o modelo open source. +Além disso, usando outros recursos do GenerateDS, é possível ir além dessa biblioteca nfelib e gerir automaticamente o modelo de dados do ERP pelo menos no ERP Odoo que tem um framework bastante poderoso. Sendo assim, é possivel montar dinamicamente as telas do usuário, a geração do XML ou a importação do XML quase que sem escrever código (apenas relacionar os campos mapeados com os campos já existentes do ERP). Fica então bem mais razoável para manter quando tem que atualizar os esquemas e assim também fica finalmente possível manter os dados do SPED dentro do ERP com um custo de manutenção compatível com o modelo open source. -Você pode aprender mais sobre o generateDS.py `aqui: `_ +Você pode aprender mais sobre o generateDS [aqui](http://www.davekuhlman.org/generateDS.html) # Como Instalar ```bash pip install git+https://github.com/akretion/nfelib ``` -# Gerir a lib novamente +# Gerir a lib novamente / processo de release **Muito importante:** as fonte estao mantido na branch **master**. Entao voce tem que fazer primeiro ``` @@ -51,25 +51,38 @@ Depois seria possível rodar o generateDS manualmente em cada arquivo xsd do esq # Pacote de Liberação No. 9 (Novo leiaute da NF-e, NT 2019.001 v.1.20a). Publicado em 20/08/2019. erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=vdxcmJ2AgTo= +erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe" -d . # Pacote de Liberação Distribuição de DF-e v1.02 (Atualizado em 25/10/16) erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=n3Kn9%20YZNak= +erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "distDFeInt|retDistDFeInt" -d . # Pacote de Liberação Evento Generico v1.01 (Atualizado em 30/05/2014) erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=YaiBe2csOmA= +erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEvento" -d . # Pacote de Liberação Evento Canc v1.01 (30/05/2014) (ZIP) erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=MtjAJ1Rurjc= - -erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe|distDFeInt|retDistDFeInt|retEnvEvento|retEnvEventoCancNFe" -d . +erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEventoCancNFe" -d . ``` -Depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ e rodar os testes por examplo. - -Se você quiser criar uma nova versão do nfelib no Github, depois de gerir voce tem que trocar de branch de novo para a branch gerida - -```git checkout master_gen_v4_00``` +Depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ e rodar os testes por examplo (`python3 -m pytest tests -v`). -e fazer commit dos arquivos da pasta nfelib e dos schemas. (faça um merge da branch master na branch master_gen_v4_00 antes do commit da neflib se precisar com `git merges master -X theirs`) +Se você quiser criar uma nova versão do nfelib no Github, depois de gerir voce tem fazer um commit do README.md com a receita do bolo atualizada (essa parte) e dos testes atualizados. +Depois voce tem que trocar de branch de novo para a branch onde fica o codigo gerido e gerir de novo: +```bash +rm -r nfelib +git checkout master_gen_v4_00 +git merges master -X theirs +# gera de novo com o script acima (erpbrasil-edoc-gen-generate-python...) +# roda os tests para ver se esta tudo OK +python3 -m pytest tests -v +# copia os schemas, por examplo com +rm -r schemas/nfe +cp -r /tmp/generated/schemas/nfe schemas/nfe +git add schemas +git add nfelib +# ai vc pode fazer um commit e um push com as mudanças (e 2 PRs para as branches master e master_gen_v4_00 eventualmente) +``` # Rodar os testes From c91413d561206c0ab5a52ece279667fb5c2ec0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Thu, 1 Oct 2020 01:14:46 -0300 Subject: [PATCH 26/28] =?UTF-8?q?Pacote=20de=20Libera=C3=A7=C3=A3o=20Event?= =?UTF-8?q?o=20CCe=20v1.01=20(30/05/2014)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +++++-- ...2000172550010000476051695511860-01-cce.xml | 1 + tests/nfe/test_nfelib.py | 24 ++++++++++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 tests/cce/v1_00/leiauteCCe/35180803102452000172550010000476051695511860-01-cce.xml diff --git a/README.md b/README.md index 1c2d060e..c4ac7648 100644 --- a/README.md +++ b/README.md @@ -61,9 +61,13 @@ erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "distDFeInt|retDistDFeInt" erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=YaiBe2csOmA= erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEvento" -d . -# Pacote de Liberação Evento Canc v1.01 (30/05/2014) (ZIP) +# Pacote de Liberação Evento Canc v1.01 (30/05/2014) erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=MtjAJ1Rurjc= erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEventoCancNFe" -d . + +# Pacote de Liberação Evento CCe v1.01 (30/05/2014) +erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=P/FXaGiLKo0= +erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvCCe" -d . ``` Depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ e rodar os testes por examplo (`python3 -m pytest tests -v`). @@ -72,7 +76,7 @@ Depois voce tem que trocar de branch de novo para a branch onde fica o codigo ge ```bash rm -r nfelib git checkout master_gen_v4_00 -git merges master -X theirs +git merge master -X theirs # gera de novo com o script acima (erpbrasil-edoc-gen-generate-python...) # roda os tests para ver se esta tudo OK python3 -m pytest tests -v diff --git a/tests/cce/v1_00/leiauteCCe/35180803102452000172550010000476051695511860-01-cce.xml b/tests/cce/v1_00/leiauteCCe/35180803102452000172550010000476051695511860-01-cce.xml new file mode 100644 index 00000000..9ab7ff4d --- /dev/null +++ b/tests/cce/v1_00/leiauteCCe/35180803102452000172550010000476051695511860-01-cce.xml @@ -0,0 +1 @@ +35175335849000115351808031024520001725500100004760516955118602018-08-17T15:17:45-03:0011011011.00Carta de CorreçãoVOLUME: 4 VOLUMESA Carta de Correção é disciplinada pelo § 1º-A do art. 7º do Convênio S/N, de 15 de dezembro de 1970 e pode ser utilizada para regularização de erro ocorrido na emissão de documento fiscal, desde que o erro não esteja relacionado com: I - as variáveis que determinam o valor do imposto tais como: base de cálculo, alíquota, diferença de preço, quantidade, valor da operação ou da prestação; II - a correção de dados cadastrais que implique mudança do remetente ou do destinatário; III - a data de emissão ou de saída. diff --git a/tests/nfe/test_nfelib.py b/tests/nfe/test_nfelib.py index c7442677..f98bad2b 100644 --- a/tests/nfe/test_nfelib.py +++ b/tests/nfe/test_nfelib.py @@ -15,6 +15,7 @@ from nfelib.v4_00 import retDistDFeInt from nfelib.v4_00 import retEnvEvento from nfelib.v4_00 import retEnvEventoCancNFe +from nfelib.v4_00 import retEnvCCe def test_in_out_leiauteNFe(): @@ -89,8 +90,29 @@ def test_evento_cancelamento(): retEnvEventoCancNFe.infEventoType() retEnvEventoCancNFe.detEventoType() +def test_cce(): + retEnvCCe.infEventoType() + retEnvCCe.detEventoType() + +def test_in_out_leiauteCCe(): + path = 'tests/cce/v1_00/leiauteCCe' + for filename in os.listdir(path): + inputfile = '%s/%s' % (path, filename,) + doc = retInutNFe.parsexml_(inputfile, None) + obj = retEnvCCe.TEvento.factory().build(doc.getroot()) + + outputfile = 'tests/output.xml' + with open(outputfile, 'w') as f: + obj.export(f, level=0, name_='evento', + namespacedef_='xmlns="http://www.portalfiscal.inf.br/nfe"') + + diff = main.diff_files(inputfile, outputfile) + print(diff) + assert len(diff) == 0 + def test_init_all(): - for mod in [nfe, retInutNFe, distDFeInt, retDistDFeInt, retEnvEvento, retEnvEventoCancNFe]: + for mod in [nfe, retInutNFe, distDFeInt, retDistDFeInt, retEnvEvento, + retEnvEventoCancNFe, retEnvCCe]: for class_name in mod.__all__: cls = getattr(mod, class_name) if issubclass(cls, mod.GeneratedsSuper): From 539ae981ceefa2a0c5fd80ffce6115d655f487d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Thu, 1 Oct 2020 12:23:49 -0300 Subject: [PATCH 27/28] =?UTF-8?q?Pacote=20de=20Libera=C3=A7=C3=A3o=20Event?= =?UTF-8?q?o=20Manifesta=20Destinat=C3=A1rio=20v1.01=20(30/05/2014)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++++++ setup.py | 2 +- tests/nfe/test_nfelib.py | 10 +++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c4ac7648..196c81ba 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,12 @@ erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEventoCancNFe" -d . # Pacote de Liberação Evento CCe v1.01 (30/05/2014) erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=P/FXaGiLKo0= erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvCCe" -d . + +# Pacote de Liberação Evento Manifesta Destinatário v1.01 (30/05/2014) +erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=y2nVL6/GFlU= +# mude o encoding desse arquivo xsd de iso-8859-1 para utf-8 e amaldiçoe o cara que usou iso-8859-1 +iconv -f iso-8859-1 /tmp/generated/schemas/nfe/v4_00/retEnvConfRecebto_v1.00.xsd -t UTF-8 -o /tmp/generated/schemas/nfe/v4_00/retEnvConfRecebto_v1.00.xsd +erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvConfRecebto" -d . ``` Depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ e rodar os testes por examplo (`python3 -m pytest tests -v`). diff --git a/setup.py b/setup.py index 505c94e5..72c15ed8 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name='nfelib', - version='0.4', + version='0.5', author='Raphael Valyi', author_email='raphael.valyi@akretion.com', url='https://github.com/akretion/nfelib', diff --git a/tests/nfe/test_nfelib.py b/tests/nfe/test_nfelib.py index f98bad2b..e272742b 100644 --- a/tests/nfe/test_nfelib.py +++ b/tests/nfe/test_nfelib.py @@ -16,6 +16,7 @@ from nfelib.v4_00 import retEnvEvento from nfelib.v4_00 import retEnvEventoCancNFe from nfelib.v4_00 import retEnvCCe +from nfelib.v4_00 import retEnvConfRecebto def test_in_out_leiauteNFe(): @@ -110,9 +111,16 @@ def test_in_out_leiauteCCe(): print(diff) assert len(diff) == 0 +def test_mde(): + retEnvConfRecebto.TEvento() + retEnvConfRecebto.infEventoType() + retEnvConfRecebto.detEventoType() + retEnvConfRecebto.tpEventoType('210200') + retEnvConfRecebto.descEventoType('Confirmacao da Operacao') + def test_init_all(): for mod in [nfe, retInutNFe, distDFeInt, retDistDFeInt, retEnvEvento, - retEnvEventoCancNFe, retEnvCCe]: + retEnvEventoCancNFe, retEnvCCe, retEnvConfRecebto]: for class_name in mod.__all__: cls = getattr(mod, class_name) if issubclass(cls, mod.GeneratedsSuper): From 71ca61def88ef8e2b8976899896bb528fe0cf464 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Tue, 10 Nov 2020 23:07:41 -0300 Subject: [PATCH 28/28] [IMP] Library pattern and standards --- .appveyor.yml | 72 +++++++++ .bumpversion.cfg | 20 +++ .coveragerc | 16 ++ .editorconfig | 16 ++ .gitignore | 82 +++++++++- .travis.yml | 64 ++++++-- AUTHORS.rst | 6 + CHANGELOG.rst | 8 + CONTRIBUTING.rst | 90 +++++++++++ MIT-LICENSE => LICENSE | 0 MANIFEST.in | 29 ++++ README.md | 176 -------------------- README.rst | 285 ++++++++++++++++++++++++++++++++ ci/appveyor-with-compiler.cmd | 23 +++ ci/bootstrap.py | 89 ++++++++++ ci/requirements.txt | 4 + ci/templates/.appveyor.yml | 50 ++++++ ci/templates/.travis.yml | 47 ++++++ docs/Makefile | 130 --------------- docs/authors.rst | 1 + docs/changelog.rst | 1 + docs/conf.py | 296 ++++++---------------------------- docs/contributing.rst | 1 + docs/index.rst | 22 +++ docs/index.txt | 25 --- docs/installation.rst | 7 + docs/intro.txt | 41 ----- docs/make.bat | 155 ------------------ docs/module_contents.txt | 9 -- docs/readme.rst | 1 + docs/reference/index.rst | 7 + docs/reference/nfelib.rst | 9 ++ docs/requirements.txt | 2 + docs/sample_code.txt | 10 -- docs/spelling_wordlist.txt | 11 ++ docs/usage.rst | 7 + nfelib/__init__.py | 1 + setup.cfg | 35 ++++ setup.py | 41 +++-- tox.ini | 83 ++++++++++ 40 files changed, 1145 insertions(+), 827 deletions(-) create mode 100644 .appveyor.yml create mode 100644 .bumpversion.cfg create mode 100644 .coveragerc create mode 100644 .editorconfig create mode 100644 AUTHORS.rst create mode 100644 CHANGELOG.rst create mode 100644 CONTRIBUTING.rst rename MIT-LICENSE => LICENSE (100%) create mode 100644 MANIFEST.in delete mode 100644 README.md create mode 100644 README.rst create mode 100644 ci/appveyor-with-compiler.cmd create mode 100755 ci/bootstrap.py create mode 100644 ci/requirements.txt create mode 100644 ci/templates/.appveyor.yml create mode 100644 ci/templates/.travis.yml delete mode 100644 docs/Makefile create mode 100644 docs/authors.rst create mode 100644 docs/changelog.rst create mode 100644 docs/contributing.rst create mode 100644 docs/index.rst delete mode 100644 docs/index.txt create mode 100644 docs/installation.rst delete mode 100644 docs/intro.txt delete mode 100644 docs/make.bat delete mode 100644 docs/module_contents.txt create mode 100644 docs/readme.rst create mode 100644 docs/reference/index.rst create mode 100644 docs/reference/nfelib.rst create mode 100644 docs/requirements.txt delete mode 100644 docs/sample_code.txt create mode 100644 docs/spelling_wordlist.txt create mode 100644 docs/usage.rst create mode 100644 nfelib/__init__.py create mode 100644 setup.cfg create mode 100644 tox.ini diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..0c621fe6 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,72 @@ +version: '{branch}-{build}' +build: off +image: Visual Studio 2019 +branches: + except: + - master + +environment: + matrix: + - TOXENV: check + TOXPYTHON: C:\Python36\python.exe + PYTHON_HOME: C:\Python36 + PYTHON_VERSION: '3.6' + PYTHON_ARCH: '32' + - TOXENV: py36 + TOXPYTHON: C:\Python36\python.exe + PYTHON_HOME: C:\Python36 + PYTHON_VERSION: '3.6' + PYTHON_ARCH: '32' + - TOXENV: py36 + TOXPYTHON: C:\Python36-x64\python.exe + PYTHON_HOME: C:\Python36-x64 + PYTHON_VERSION: '3.6' + PYTHON_ARCH: '64' + - TOXENV: py37 + TOXPYTHON: C:\Python37\python.exe + PYTHON_HOME: C:\Python37 + PYTHON_VERSION: '3.7' + PYTHON_ARCH: '32' + - TOXENV: py37 + TOXPYTHON: C:\Python37-x64\python.exe + PYTHON_HOME: C:\Python37-x64 + PYTHON_VERSION: '3.7' + PYTHON_ARCH: '64' + - TOXENV: py38 + TOXPYTHON: C:\Python38\python.exe + PYTHON_HOME: C:\Python38 + PYTHON_VERSION: '3.8' + PYTHON_ARCH: '32' + - TOXENV: py38 + TOXPYTHON: C:\Python38-x64\python.exe + PYTHON_HOME: C:\Python38-x64 + PYTHON_VERSION: '3.8' + PYTHON_ARCH: '64' + - TOXENV: py39 + TOXPYTHON: C:\Python39\python.exe + PYTHON_HOME: C:\Python39 + PYTHON_VERSION: '3.9' + PYTHON_ARCH: '32' + - TOXENV: py39 + TOXPYTHON: C:\Python39-x64\python.exe + PYTHON_HOME: C:\Python39-x64 + PYTHON_VERSION: '3.9' + PYTHON_ARCH: '64' +init: + - ps: echo $env:TOXENV + - ps: ls C:\Python* +install: + - '%PYTHON_HOME%\python -mpip install --progress-bar=off tox -rci/requirements.txt' + - '%PYTHON_HOME%\Scripts\virtualenv --version' + - '%PYTHON_HOME%\Scripts\easy_install --version' + - '%PYTHON_HOME%\Scripts\pip --version' + - '%PYTHON_HOME%\Scripts\tox --version' +test_script: + - cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd %PYTHON_HOME%\Scripts\tox +on_failure: + - ps: dir "env:" + - ps: get-content .tox\*\log\* + +### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): +# on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 00000000..bb2253db --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,20 @@ +[bumpversion] +current_version = 0.5 +commit = True +tag = True + +[bumpversion:file:setup.py] +search = version='{current_version}' +replace = version='{new_version}' + +[bumpversion:file:README.rst] +search = v{current_version}. +replace = v{new_version}. + +[bumpversion:file:docs/conf.py] +search = version = release = '{current_version}' +replace = version = release = '{new_version}' + +[bumpversion:file:nfelib/__init__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 00000000..a44e9f1c --- /dev/null +++ b/.coveragerc @@ -0,0 +1,16 @@ +[paths] +source = + src + */site-packages + +[run] +branch = true +source = + nfelib + tests +parallel = true + +[report] +show_missing = true +precision = 2 +omit = *migrations* diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..a9c7977a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# see https://editorconfig.org/ +root = true + +[*] +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 +charset = utf-8 + +[*.{bat,cmd,ps1}] +end_of_line = crlf + +[*.{yml,yaml}] +indent_size = 2 diff --git a/.gitignore b/.gitignore index e47aa2e2..83a43fdb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,74 @@ -led python files -*.py[co] -.pytest_cache -tests/.cache -tests/.coverage -tests/.pytest_cache -tests/input.xml -tests/output.xml +*.py[cod] +__pycache__ + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +.eggs +parts +bin +var +sdist +wheelhouse +develop-eggs +.installed.cfg +lib +lib64 +venv*/ +pyvenv*/ +pip-wheel-metadata/ + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +.coverage.* +.pytest_cache/ +nosetests.xml +coverage.xml +htmlcov + +# Translations +*.mo + +# Buildout +.mr.developer.cfg + +# IDE project files +.project +.pydevproject +.idea +.vscode +*.iml +*.komodoproject + +# Complexity +output/*.html +output/*/index.html + +# Sphinx +docs/_build + +.DS_Store +*~ +.*.sw[po] +.build +.ve +.env +.cache +.pytest +.benchmarks +.bootstrap +.appveyor.token +*.bak + +# Mypy Cache +.mypy_cache/ diff --git a/.travis.yml b/.travis.yml index d6ce6e98..542c9ea9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,58 @@ language: python -python: -- 3.5 -- 3.6 -- 3.7 -- 3.8 -install: -- pip install xmldiff -- pip install . +dist: xenial +virt: lxd +cache: false branches: except: - - master + - master + +env: + global: + - LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so + - SEGFAULT_SIGNALS=all + - LANG=en_US.UTF-8 +matrix: + include: + - python: '3.8' + env: + - TOXENV=check + - python: '3.8' + env: + - TOXENV=docs + - env: + - TOXENV=py35,codecov + python: '3.5' + - env: + - TOXENV=py36,codecov + python: '3.6' + - env: + - TOXENV=py37,codecov + python: '3.7' + - env: + - TOXENV=py38,codecov + python: '3.8' + - env: + - TOXENV=py39,codecov + python: '3.9' + - env: + - TOXENV=pypy3,codecov + python: 'pypy3' +before_install: + - python --version + - uname -a + - lsb_release -a || true +install: + - python -mpip install --progress-bar=off tox -rci/requirements.txt + - virtualenv --version + - easy_install --version + - pip --version + - tox --version script: -- pytest -s + - tox -v +after_failure: + - cat .tox/log/* + - cat .tox/*/log/* +notifications: + email: + on_success: never + on_failure: always diff --git a/AUTHORS.rst b/AUTHORS.rst new file mode 100644 index 00000000..39dfc140 --- /dev/null +++ b/AUTHORS.rst @@ -0,0 +1,6 @@ +Authors +======= + +* `Akretion `__: + + * Raphael Valyi diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 00000000..a4a6d7b7 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,8 @@ + +Changelog +========= + +0.1.0 (2020-11-08) +~~~~~~~~~~~~~~~~~~ + +* First release on PyPI. diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 00000000..a9b7627f --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,90 @@ +============ +Contributing +============ + +Contributions are welcome, and they are greatly appreciated! Every +little bit helps, and credit will always be given. + +Bug reports +=========== + +When `reporting a bug `_ please include: + + * Your operating system name and version. + * Any details about your local setup that might be helpful in troubleshooting. + * Detailed steps to reproduce the bug. + +Documentation improvements +========================== + +nfselib.ginfes could always use more documentation, whether as part of the +official nfselib.ginfes docs, in docstrings, or even on the web in blog posts, +articles, and such. + +Feature requests and feedback +============================= + +The best way to send feedback is to file an issue at https://github.com/erpbrasil/nfselib.ginfes/issues. + +If you are proposing a feature: + +* Explain in detail how it would work. +* Keep the scope as narrow as possible, to make it easier to implement. +* Remember that this is a volunteer-driven project, and that code contributions are welcome :) + +Development +=========== + +To set up `nfselib.ginfes` for local development: + +1. Fork `nfselib.ginfes `_ + (look for the "Fork" button). +2. Clone your fork locally:: + + git clone git@github.com:YOURGITHUBNAME/nfselib.ginfes.git + +3. Create a branch for local development:: + + git checkout -b name-of-your-bugfix-or-feature + + Now you can make your changes locally. + +4. When you're done making changes run all the checks and docs builder with `tox `_ one command:: + + tox + +5. Commit your changes and push your branch to GitHub:: + + git add . + git commit -m "Your detailed description of your changes." + git push origin name-of-your-bugfix-or-feature + +6. Submit a pull request through the GitHub website. + +Pull Request Guidelines +----------------------- + +If you need some code review or feedback while you're developing the code just make the pull request. + +For merging, you should: + +1. Include passing tests (run ``tox``) [1]_. +2. Update documentation when there's new API, functionality etc. +3. Add a note to ``CHANGELOG.rst`` about the changes. +4. Add yourself to ``AUTHORS.rst``. + +.. [1] If you don't have all the necessary python versions available locally you can rely on Travis - it will + `run the tests `_ for each change you add in the pull request. + + It will be slower though ... + +Tips +---- + +To run a subset of tests:: + + tox -e envname -- pytest -k test_myfeature + +To run all the test environments in *parallel*:: + + tox -p auto diff --git a/MIT-LICENSE b/LICENSE similarity index 100% rename from MIT-LICENSE rename to LICENSE diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..f2d49704 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,29 @@ +graft docs +graft src +graft ci +graft tests + +include .bumpversion.cfg +include .coveragerc +include .cookiecutterrc +include .editorconfig + +include AUTHORS.rst +include CHANGELOG.rst +include CONTRIBUTING.rst +include LICENSE +include README.rst + +include tox.ini .travis.yml .appveyor.yml .readthedocs.yml + +global-exclude *.py[cod] __pycache__/* *.so *.dylib + +include *.xml +recursive-include nfelib *.py +recursive-include nfelib *.txt +recursive-include schemas *.xsd +recursive-include scripts *.md +recursive-include scripts *.sh +recursive-include ext *.jpg +recursive-include ext *.png +recursive-include schemas *.txt diff --git a/README.md b/README.md deleted file mode 100644 index 196c81ba..00000000 --- a/README.md +++ /dev/null @@ -1,176 +0,0 @@ -[![Build Status](https://travis-ci.org/akretion/nfelib.svg?branch=master_gen_v4_00)](https://travis-ci.org/akretion/nfelib) - -[![nfelib](https://raw.githubusercontent.com/akretion/nfelib/master/ext/nfe.jpg)](https://github.com/akretion/nfelib/) by [![Akretion](https://raw.githubusercontent.com/akretion/nfelib/master/ext/akretion-logo2.png)](https://akretion.com/pt_BR) - -# nfelib Python Library - -A nfelib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileiras (NFe's). A nfelib não tem a pretensão de solucionar toda burocracia do SPED sozinha, mas foca apenas na questão do parsing e da geração da NFe. - -* Para transmitir as NFe's para a receita, aconselhamos a biblioteca Python Zeep, ou entao por examplo https://github.com/erpbrasil/erpbrasil.edoc. -* E para imprimir o DANFE, é possivel usar https://github.com/erpbrasil/erpbrasil.edoc.pdf - -Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (e especialmente para NFS-e, MDFe, CTe, E-Social e SPED-Reinf, GNRE, BP-e). - -Durante anos usamos o https://github.com/aricaldeira/PySPED. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas nessa parte para montar o leiaute da NFe https://github.com/aricaldeira/PySPED/tree/master/pysped/nfe/leiaute. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmitir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código (anos de trabalho do autor) podem ser geradas por **esse único comando** com a ferramenta [generateDS](http://www.davekuhlman.org/generateDS.html) usada por essa lib: - -```bash -generateDS -o leiauteNFe.py leiauteNFe_v4.00.xsd -``` - -A nfelib permite de: - -* Gerir os XMLs dos documentos fiscais. -* Validar os dados com **as mesmas validações dos XSD's ao montar os objetos**, o que evita detectar os erros apenas ao transmitir o XML. -* Importar XMLs e transforma-los em objetos Python. Usando um sistema de sub-classes, fica fácil mapear esses objetos em outros objetos ou adicionar qualquer método customizado. - -A nfelib é: - -* **Simples e confiável**. O código é gerido pelo generateDS a partir dos XSD's da Fazenda. Ele **reflete exatamente a especificação fiscal** da versão do esquema escolhida sem que você deva se perguntar qual é o grau de aderência do código. -* Compatível com **Python 3** (e com Python 2 se botar patches no generateDS e usar uma versao anterior) -* Capaz de carregar **várias versões dos esquemas**. Isso pode ser bem útil ao receber uma nota fiscal com um leiaute antigo. - -Além disso, usando outros recursos do GenerateDS, é possível ir além dessa biblioteca nfelib e gerir automaticamente o modelo de dados do ERP pelo menos no ERP Odoo que tem um framework bastante poderoso. Sendo assim, é possivel montar dinamicamente as telas do usuário, a geração do XML ou a importação do XML quase que sem escrever código (apenas relacionar os campos mapeados com os campos já existentes do ERP). Fica então bem mais razoável para manter quando tem que atualizar os esquemas e assim também fica finalmente possível manter os dados do SPED dentro do ERP com um custo de manutenção compatível com o modelo open source. - -Você pode aprender mais sobre o generateDS [aqui](http://www.davekuhlman.org/generateDS.html) - -# Como Instalar - -```bash -pip install git+https://github.com/akretion/nfelib -``` -# Gerir a lib novamente / processo de release -**Muito importante:** as fonte estao mantido na branch **master**. Entao voce tem que fazer primeiro - -``` -git checkout master -``` - -Depois seria possível rodar o generateDS manualmente em cada arquivo xsd do esquema que interessa. Porem é interessante instalar essa pequena ferramenta https://github.com/akretion/erpbrasil.edoc.gen para automatizar as operações. Depois da lib instalada (ela puxa o pacote GenerateDS), basta fazer: -```bash -# Download dos esquemas de NFe do portal da Fazenda: https://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=/fwLvLUSmU8= - -# Pacote de Liberação No. 9 (Novo leiaute da NF-e, NT 2019.001 v.1.20a). Publicado em 20/08/2019. -erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=vdxcmJ2AgTo= -erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe" -d . - -# Pacote de Liberação Distribuição de DF-e v1.02 (Atualizado em 25/10/16) -erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=n3Kn9%20YZNak= -erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "distDFeInt|retDistDFeInt" -d . - -# Pacote de Liberação Evento Generico v1.01 (Atualizado em 30/05/2014) -erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=YaiBe2csOmA= -erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEvento" -d . - -# Pacote de Liberação Evento Canc v1.01 (30/05/2014) -erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=MtjAJ1Rurjc= -erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEventoCancNFe" -d . - -# Pacote de Liberação Evento CCe v1.01 (30/05/2014) -erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=P/FXaGiLKo0= -erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvCCe" -d . - -# Pacote de Liberação Evento Manifesta Destinatário v1.01 (30/05/2014) -erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=y2nVL6/GFlU= -# mude o encoding desse arquivo xsd de iso-8859-1 para utf-8 e amaldiçoe o cara que usou iso-8859-1 -iconv -f iso-8859-1 /tmp/generated/schemas/nfe/v4_00/retEnvConfRecebto_v1.00.xsd -t UTF-8 -o /tmp/generated/schemas/nfe/v4_00/retEnvConfRecebto_v1.00.xsd -erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvConfRecebto" -d . -``` -Depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ e rodar os testes por examplo (`python3 -m pytest tests -v`). - -Se você quiser criar uma nova versão do nfelib no Github, depois de gerir voce tem fazer um commit do README.md com a receita do bolo atualizada (essa parte) e dos testes atualizados. -Depois voce tem que trocar de branch de novo para a branch onde fica o codigo gerido e gerir de novo: -```bash -rm -r nfelib -git checkout master_gen_v4_00 -git merge master -X theirs -# gera de novo com o script acima (erpbrasil-edoc-gen-generate-python...) -# roda os tests para ver se esta tudo OK -python3 -m pytest tests -v -# copia os schemas, por examplo com -rm -r schemas/nfe -cp -r /tmp/generated/schemas/nfe schemas/nfe -git add schemas -git add nfelib -# ai vc pode fazer um commit e um push com as mudanças (e 2 PRs para as branches master e master_gen_v4_00 eventualmente) -``` - -# Rodar os testes - -```bash -python3 -m pytest tests -v -``` - -# Como Usar - -```python - # nfelib permite ler os dados de uma nota fiscal, por exemplo no formato 4.00: - >>> from nfelib.v4_00 import leiauteNFe_sub as parser - # vamos importar o XML da nota e transforma-lo em objeto Python: - >>> nota = parser.parse(inputfile) - # agora podemos trabalhar em cima do objeto e fazer operaçoes como: - >>> nota.infNFe.emit.CNPJ - '03102552000172' - >>> len(nota.infNFe.det) - 42 - # (a nota tem 42 linhas) - - # podemos tambem alterar os dados: - nota.infNFe.emit.CNPJ = ... - - # e finalmente podemos exportar a nota num arquivo de novo por examplo - >>> with open(filename, 'w') as f: - >>> parser.export(nota, nfeProc=False, stream=f) - - - # nfelib também permite de montar o XML de uma nota fiscal com todas validações dos XSDs já nos objetos: - >>> from nfelib.v4_00 import leiauteNFe - >>> enderEmit=leiauteNFe.TEnderEmi(xLgr='NKwaAJ5ZJ49aQYmqBvxMhBzkGUqvtXnqusGEtjDzKCXPGwrEZCS8LGKHyBbV', - nro='11mzXHR8rZTgfE35EqfGhiShiIwQfLCAziFDXVgs3EjLSPkZkCvfGNLMEf5y', - xCpl='Fr3gSvoAeKbGpQD3r98KFeB50P3Gq14XBVsv5fpiaBvJ3HTOpREiwYGs20Xw', - xBairro='67LQFlXOBK0JqAE1rFi2CEyUGW5Z8QmmHhzmZ9GABVLKa9AbV0uFR0onl7nU', - cMun='9999999', - xMun='s1Cr2hWP6bptQ80A9vWBuTaODR1U82LtKQi1DEm3LsAXu9AbkSeCtfXJVTKG', - UF='RS', - CEP='88095550', - cPais=1058, - fone='12345678901324') - - # se tentar montar algum objeto com algum dado inválido: - >>> emitente=leiauteNFe.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') ->>> leiauteNFe.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') -/home/rvalyi/DEV/nfelib-edocs-gen/nfelib/v4_00/leiauteNFe.py:5821: UserWarning: Value "b'Brazil is a f*cking bureaucracy'" does not match xsd maxLength restriction on TCpf - warnings_.warn('Value "%(value)s" does not match xsd maxLength restriction on TCpf' % {"value" : value.encode("utf-8")} ) -/home/rvalyi/DEV/nfelib-edocs-gen/nfelib/v4_00/leiauteNFe.py:5824: UserWarning: Value "b'Brazil is a f*cking bureaucracy'" does not match xsd pattern restrictions: [['^([0-9]{11})$']] - warnings_.warn('Value "%s" does not match xsd pattern restrictions: %s' % (value.encode('utf-8'), self.validate_TCpf_patterns_, )) - - - # para gerir o XML: - >>> import sys - >>> emitente.export(sys.stdout, 0) - - 12345678901 - Raphael - - NKwaAJ5ZJ49aQYmqBvxMhBzkGUqvtXnqusGEtjDzKCXPGwrEZCS8LGKHyBbV - 11mzXHR8rZTgfE35EqfGhiShiIwQfLCAziFDXVgs3EjLSPkZkCvfGNLMEf5y - Fr3gSvoAeKbGpQD3r98KFeB50P3Gq14XBVsv5fpiaBvJ3HTOpREiwYGs20Xw - 67LQFlXOBK0JqAE1rFi2CEyUGW5Z8QmmHhzmZ9GABVLKa9AbV0uFR0onl7nU - 9999999 - s1Cr2hWP6bptQ80A9vWBuTaODR1U82LtKQi1DEm3LsAXu9AbkSeCtfXJVTKG - RS - 88095550 - 1058 - 12345678901324 - - 12345678901234 - 84 - zjfBnFVG8TBq8iW - 0111111 - 3 - -``` - -# Uso no ERP Odoo - -Para cada documento eletrônico para o qual existe esquema XSD's, a Akretion fez um repo Github com uma lib desse tipo. -Mas fomos além: eu tambem criei um gerador de modelos abstratos (mixins) Odoo, de forma que para os documentos fiscais complexos como a NFe vc tem um marshalling/unmarshalling automatico dos dados ate os modelos persistentes do ERP e se remapeando nos objetos nativos do Odoo https://github.com/akretion/generateds-odoo diff --git a/README.rst b/README.rst new file mode 100644 index 00000000..3c734cae --- /dev/null +++ b/README.rst @@ -0,0 +1,285 @@ +======== +Overview +======== + +.. start-badges + +.. list-table:: + :stub-columns: 1 + + * - tests + - | |travis| |appveyor| |codecov| + | + * - package + - | |version| |wheel| |supported-versions| |supported-implementations| + | |commits-since| + +.. |travis| image:: https://api.travis-ci.org/erpbrasil/nfelib.svg?branch=master_gen + :alt: Travis-CI Build Status + :target: https://travis-ci.org/erpbrasil/nfelib + +.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/erpbrasil/nfelib?branch=master_gen&svg=true + :alt: AppVeyor Build Status + :target: https://ci.appveyor.com/project/mileo/nfselib-ginfes + +.. |codecov| image:: https://codecov.io/gh/erpbrasil/nfelib/branch/master_gen/graphs/badge.svg?branch=master_gen + :alt: Coverage Status + :target: https://codecov.io/github/erpbrasil/nfelib + +.. |version| image:: https://img.shields.io/pypi/v/nfelib.svg + :alt: PyPI Package latest release + :target: https://pypi.org/project/nfelib + +.. |wheel| image:: https://img.shields.io/pypi/wheel/nfelib.svg + :alt: PyPI Wheel + :target: https://pypi.org/project/nfelib + +.. |supported-versions| image:: https://img.shields.io/pypi/pyversions/nfelib.svg + :alt: Supported versions + :target: https://pypi.org/project/nfelib + +.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/nfelib.svg + :alt: Supported implementations + :target: https://pypi.org/project/nfelib + +.. |commits-since| image:: https://img.shields.io/github/commits-since/erpbrasil/nfelib/v0.5.0.svg + :alt: Commits since latest release + :target: https://github.com/erpbrasil/nfelib/compare/v0.5.0...master + +.. end-badges + +Python Library to genereate NF-E +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A nfelib é uma biblioteca para ler e gerir notas fiscais eletrônicas brasileiras (NFe's). A nfelib não tem a pretensão de solucionar toda burocracia do SPED sozinha, mas foca apenas na questão do parsing e da geração da NFe. + +Esta biblioteca faz parte do projeto: https://erpbrasil.github.io/ + +* Para transmitir as NFe's para a receita, aconselhamos a biblioteca Python Zeep, ou entao por examplo https://github.com/erpbrasil/erpbrasil.edoc. +* E para imprimir o DANFE, é possivel usar https://github.com/erpbrasil/erpbrasil.edoc.pdf + +Na Akretion queriamos algo modular, simples de se manter para usar com o ERP Odoo que adaptamos para as necessidades fiscais brasileiras. Também criamos outras bibliotecas semelhantes para os outros documentos eletrônicos do SPED (e especialmente para NFS-e, MDFe, CTe, E-Social e SPED-Reinf, GNRE, BP-e). + +Durante anos usamos o https://github.com/aricaldeira/PySPED. Porém no PySPED, o autor partiu para escrever e manter manualmente **mais de 10 000 de linhas de código**, apenas nessa parte para montar o leiaute da NFe https://github.com/aricaldeira/PySPED/tree/master/pysped/nfe/leiaute. Mas isso ocasiona um custo de manutenção proibitivo a cada atualização dos esquemas sem falar que por se tratar de código manual tem vários erros com as TAGs pouco usadas e na Akretion cansamos de escrever patch na urgência no PySPED a cada vez que um cliente Odoo nosso não consegue transmitir uma NF'e. Na verdade o equivalente dessas 10 000 linhas de código (anos de trabalho do autor) podem ser geradas por **esse único comando** com a ferramenta [generateDS](http://www.davekuhlman.org/generateDS.html) usada por essa lib: + + +.. code-block:: shell + + generateDS -o leiauteNFe.py leiauteNFe_v4.00.xsd + + +A nfelib permite de: + +* Gerir os XMLs dos documentos fiscais. +* Validar os dados com **as mesmas validações dos XSD's ao montar os objetos**, o que evita detectar os erros apenas ao transmitir o XML. +* Importar XMLs e transforma-los em objetos Python. Usando um sistema de sub-classes, fica fácil mapear esses objetos em outros objetos ou adicionar qualquer método customizado. + +A nfelib é: + +* **Simples e confiável**. O código é gerido pelo generateDS a partir dos XSD's da Fazenda. Ele **reflete exatamente a especificação fiscal** da versão do esquema escolhida sem que você deva se perguntar qual é o grau de aderência do código. +* Compatível com **Python 3** (e com Python 2 se botar patches no generateDS e usar uma versao anterior) +* Capaz de carregar **várias versões dos esquemas**. Isso pode ser bem útil ao receber uma nota fiscal com um leiaute antigo. + +Além disso, usando outros recursos do GenerateDS, é possível ir além dessa biblioteca nfelib e gerir automaticamente o modelo de dados do ERP pelo menos no ERP Odoo que tem um framework bastante poderoso. Sendo assim, é possivel montar dinamicamente as telas do usuário, a geração do XML ou a importação do XML quase que sem escrever código (apenas relacionar os campos mapeados com os campos já existentes do ERP). Fica então bem mais razoável para manter quando tem que atualizar os esquemas e assim também fica finalmente possível manter os dados do SPED dentro do ERP com um custo de manutenção compatível com o modelo open source. + +Você pode aprender mais sobre o generateDS `aqui `__ + +# Gerir a lib novamente / processo de release +**Muito importante:** as fonte estao mantido na branch **master**. Entao voce tem que fazer primeiro + + +# Gerir a lib novamente / processo de release +**Muito importante:** as fonte estao mantido na branch **master**. Entao voce tem que fazer primeiro + +>>> git checkout master + +Depois seria possível rodar o generateDS manualmente em cada arquivo xsd do esquema que interessa. Porem é interessante instalar essa pequena ferramenta https://github.com/akretion/erpbrasil.edoc.gen para automatizar as operações. Depois da lib instalada (ela puxa o pacote GenerateDS), basta fazer: + +.. code-block:: shell + + # Download dos esquemas de NFe do portal da Fazenda: https://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=/fwLvLUSmU8= + + # Pacote de Liberação No. 9 (Novo leiaute da NF-e, NT 2019.001 v.1.20a). Publicado em 20/08/2019. + erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=vdxcmJ2AgTo= + erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retConsStatServ|retConsSitNFe|retEnviNFe|retConsReciNFe|retInutNFe" -d . + + # Pacote de Liberação Distribuição de DF-e v1.02 (Atualizado em 25/10/16) + erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=n3Kn9%20YZNak= + erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "distDFeInt|retDistDFeInt" -d . + + # Pacote de Liberação Evento Generico v1.01 (Atualizado em 30/05/2014) + erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=YaiBe2csOmA= + erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEvento" -d . + + # Pacote de Liberação Evento Canc v1.01 (30/05/2014) + erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u http://hom.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=MtjAJ1Rurjc= + erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvEventoCancNFe" -d . + + # Pacote de Liberação Evento CCe v1.01 (30/05/2014) + erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=P/FXaGiLKo0= + erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvCCe" -d . + + # Pacote de Liberação Evento Manifesta Destinatário v1.01 (30/05/2014) + erpbrasil-edoc-gen-download-schema -n nfe -v v4.00 -u https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=y2nVL6/GFlU= + # mude o encoding desse arquivo xsd de iso-8859-1 para utf-8 e amaldiçoe o cara que usou iso-8859-1 + iconv -f iso-8859-1 /tmp/generated/schemas/nfe/v4_00/retEnvConfRecebto_v1.00.xsd -t UTF-8 -o /tmp/generated/schemas/nfe/v4_00/retEnvConfRecebto_v1.00.xsd + erpbrasil-edoc-gen-generate-python -n nfe -v v4.00 -i "retEnvConfRecebto" -d . + + +Depois você pode olhar os arquivos Python geridos na pasta nfelib/v4_00/ e rodar os testes por examplo (`python3 -m pytest tests -v`). + +Se você quiser criar uma nova versão do nfelib no Github, depois de gerir voce tem fazer um commit do README.md com a receita do bolo atualizada (essa parte) e dos testes atualizados. +Depois voce tem que trocar de branch de novo para a branch onde fica o codigo gerido e gerir de novo: + +.. code-block:: shell + + rm -r nfelib + git checkout master_gen_v4_00 + git merge master -X theirs + # gera de novo com o script acima (erpbrasil-edoc-gen-generate-python...) + # roda os tests para ver se esta tudo OK + python3 -m pytest tests -v + # copia os schemas, por examplo com + rm -r schemas/nfe + cp -r /tmp/generated/schemas/nfe schemas/nfe + git add schemas + git add nfelib + # ai vc pode fazer um commit e um push com as mudanças (e 2 PRs para as branches master e master_gen_v4_00 eventualmente) + +# Como Usar + +.. code-block:: shell + + # nfelib permite ler os dados de uma nota fiscal, por exemplo no formato 4.00: + >>> from nfelib.v4_00 import leiauteNFe_sub as parser + # vamos importar o XML da nota e transforma-lo em objeto Python: + >>> nota = parser.parse(inputfile) + # agora podemos trabalhar em cima do objeto e fazer operaçoes como: + >>> nota.infNFe.emit.CNPJ + '03102552000172' + >>> len(nota.infNFe.det) + 42 + # (a nota tem 42 linhas) + + # podemos tambem alterar os dados: + nota.infNFe.emit.CNPJ = ... + + # e finalmente podemos exportar a nota num arquivo de novo por examplo + >>> with open(filename, 'w') as f: + >>> parser.export(nota, nfeProc=False, stream=f) + + + # nfelib também permite de montar o XML de uma nota fiscal com todas validações dos XSDs já nos objetos: + >>> from nfelib.v4_00 import leiauteNFe + >>> enderEmit=leiauteNFe.TEnderEmi(xLgr='NKwaAJ5ZJ49aQYmqBvxMhBzkGUqvtXnqusGEtjDzKCXPGwrEZCS8LGKHyBbV', + nro='11mzXHR8rZTgfE35EqfGhiShiIwQfLCAziFDXVgs3EjLSPkZkCvfGNLMEf5y', + xCpl='Fr3gSvoAeKbGpQD3r98KFeB50P3Gq14XBVsv5fpiaBvJ3HTOpREiwYGs20Xw', + xBairro='67LQFlXOBK0JqAE1rFi2CEyUGW5Z8QmmHhzmZ9GABVLKa9AbV0uFR0onl7nU', + cMun='9999999', + xMun='s1Cr2hWP6bptQ80A9vWBuTaODR1U82LtKQi1DEm3LsAXu9AbkSeCtfXJVTKG', + UF='RS', + CEP='88095550', + cPais=1058, + fone='12345678901324') + + # se tentar montar algum objeto com algum dado inválido: + >>> emitente=leiauteNFe.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') + >>> leiauteNFe.emitType(enderEmit=enderEmit, CPF='Brazil is a f*cking bureaucracy', xNome='Raphael', IE='12345678901234', IEST='84', IM='zjfBnFVG8TBq8iW', CNAE='0111111', CRT='3') + /home/rvalyi/DEV/nfelib-edocs-gen/nfelib/v4_00/leiauteNFe.py:5821: UserWarning: Value "b'Brazil is a f*cking bureaucracy'" does not match xsd maxLength restriction on TCpf + warnings_.warn('Value "%(value)s" does not match xsd maxLength restriction on TCpf' % {"value" : value.encode("utf-8")} ) + /home/rvalyi/DEV/nfelib-edocs-gen/nfelib/v4_00/leiauteNFe.py:5824: UserWarning: Value "b'Brazil is a f*cking bureaucracy'" does not match xsd pattern restrictions: [['^([0-9]{11})$']] + warnings_.warn('Value "%s" does not match xsd pattern restrictions: %s' % (value.encode('utf-8'), self.validate_TCpf_patterns_, )) + + + # para gerir o XML: + >>> import sys + >>> emitente.export(sys.stdout, 0) + + 12345678901 + Raphael + + NKwaAJ5ZJ49aQYmqBvxMhBzkGUqvtXnqusGEtjDzKCXPGwrEZCS8LGKHyBbV + 11mzXHR8rZTgfE35EqfGhiShiIwQfLCAziFDXVgs3EjLSPkZkCvfGNLMEf5y + Fr3gSvoAeKbGpQD3r98KFeB50P3Gq14XBVsv5fpiaBvJ3HTOpREiwYGs20Xw + 67LQFlXOBK0JqAE1rFi2CEyUGW5Z8QmmHhzmZ9GABVLKa9AbV0uFR0onl7nU + 9999999 + s1Cr2hWP6bptQ80A9vWBuTaODR1U82LtKQi1DEm3LsAXu9AbkSeCtfXJVTKG + RS + 88095550 + 1058 + 12345678901324 + + 12345678901234 + 84 + zjfBnFVG8TBq8iW + 0111111 + 3 + + + +Uso no ERP Odoo +~~~~~~~~~~~~~~~ + +Para cada documento eletrônico para o qual existe esquema XSD's, a Akretion fez um repo Github com uma lib desse tipo. +Mas fomos além: eu tambem criei um gerador de modelos abstratos (mixins) Odoo, de forma que para os documentos fiscais complexos como a NFe vc tem um marshalling/unmarshalling automatico dos dados ate os modelos persistentes do ERP e se remapeando nos objetos nativos do Odoo https://github.com/akretion/generateds-odoo + + +Instalação +========== + +:: + + pip install nfelib + +You can also install the in-development version with:: + + pip install https://github.com/erpbrasil/nfelib/archive/master_gen.zip + + +Branchs +======= + +* master - Script de geração e outros arquivos importantes (Customizações, Testes e Readme); +* master_gen - Versão final da bibliotaca para uso; + +Documentação +============ + +https://erpbrasil.github.io/ + +Créditos +======== + +Esta é uma biblioteca criada atravês do esforço de das empresas: + +* Akretion https://akretion.com/pt-BR/ +* KMEE https://www.kmee.com.br + +Licença +~~~~~~~ + +* Free software: MIT license + +Desenvolvimento +=============== + +To run all the tests run:: + + tox + +Note, to combine the coverage data from all the tox environments run: + +.. list-table:: + :widths: 10 90 + :stub-columns: 1 + + - - Windows + - :: + + set PYTEST_ADDOPTS=--cov-append + tox + + - - Other + - :: + + PYTEST_ADDOPTS=--cov-append tox diff --git a/ci/appveyor-with-compiler.cmd b/ci/appveyor-with-compiler.cmd new file mode 100644 index 00000000..289585fc --- /dev/null +++ b/ci/appveyor-with-compiler.cmd @@ -0,0 +1,23 @@ +:: Very simple setup: +:: - if WINDOWS_SDK_VERSION is set then activate the SDK. +:: - disable the WDK if it's around. + +SET COMMAND_TO_RUN=%* +SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows +SET WIN_WDK="c:\Program Files (x86)\Windows Kits\10\Include\wdf" +ECHO SDK: %WINDOWS_SDK_VERSION% ARCH: %PYTHON_ARCH% + +IF EXIST %WIN_WDK% ( + REM See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/ + REN %WIN_WDK% 0wdf +) +IF "%WINDOWS_SDK_VERSION%"=="" GOTO main + +SET DISTUTILS_USE_SDK=1 +SET MSSdk=1 +"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% +CALL "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release + +:main +ECHO Executing: %COMMAND_TO_RUN% +CALL %COMMAND_TO_RUN% || EXIT 1 diff --git a/ci/bootstrap.py b/ci/bootstrap.py new file mode 100755 index 00000000..2eb77232 --- /dev/null +++ b/ci/bootstrap.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals + +import os +import subprocess +import sys +from os.path import abspath +from os.path import dirname +from os.path import exists +from os.path import join + +base_path = dirname(dirname(abspath(__file__))) + + +def check_call(args): + print("+", *args) + subprocess.check_call(args) + + +def exec_in_env(): + env_path = join(base_path, ".tox", "bootstrap") + if sys.platform == "win32": + bin_path = join(env_path, "Scripts") + else: + bin_path = join(env_path, "bin") + if not exists(env_path): + import subprocess + + print("Making bootstrap env in: {0} ...".format(env_path)) + try: + check_call([sys.executable, "-m", "venv", env_path]) + except subprocess.CalledProcessError: + try: + check_call([sys.executable, "-m", "virtualenv", env_path]) + except subprocess.CalledProcessError: + check_call(["virtualenv", env_path]) + print("Installing `jinja2` into bootstrap environment...") + check_call([join(bin_path, "pip"), "install", "jinja2", "tox"]) + python_executable = join(bin_path, "python") + if not os.path.exists(python_executable): + python_executable += '.exe' + + print("Re-executing with: {0}".format(python_executable)) + print("+ exec", python_executable, __file__, "--no-env") + os.execv(python_executable, [python_executable, __file__, "--no-env"]) + + +def main(): + import jinja2 + + print("Project path: {0}".format(base_path)) + + jinja = jinja2.Environment( + loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")), + trim_blocks=True, + lstrip_blocks=True, + keep_trailing_newline=True + ) + + tox_environments = [ + line.strip() + # 'tox' need not be installed globally, but must be importable + # by the Python that is running this script. + # This uses sys.executable the same way that the call in + # cookiecutter-pylibrary/hooks/post_gen_project.py + # invokes this bootstrap.py itself. + for line in subprocess.check_output([sys.executable, '-m', 'tox', '--listenvs'], universal_newlines=True).splitlines() + ] + tox_environments = [line for line in tox_environments if line.startswith('py')] + + for name in os.listdir(join("ci", "templates")): + with open(join(base_path, name), "w") as fh: + fh.write(jinja.get_template(name).render(tox_environments=tox_environments)) + print("Wrote {}".format(name)) + print("DONE.") + + +if __name__ == "__main__": + args = sys.argv[1:] + if args == ["--no-env"]: + main() + elif not args: + exec_in_env() + else: + print("Unexpected arguments {0}".format(args), file=sys.stderr) + sys.exit(1) diff --git a/ci/requirements.txt b/ci/requirements.txt new file mode 100644 index 00000000..d7f5177e --- /dev/null +++ b/ci/requirements.txt @@ -0,0 +1,4 @@ +virtualenv>=16.6.0 +pip>=19.1.1 +setuptools>=18.0.1 +six>=1.14.0 diff --git a/ci/templates/.appveyor.yml b/ci/templates/.appveyor.yml new file mode 100644 index 00000000..0ac6421c --- /dev/null +++ b/ci/templates/.appveyor.yml @@ -0,0 +1,50 @@ +version: '{branch}-{build}' +build: off +image: Visual Studio 2019 +environment: + matrix: + - TOXENV: check + TOXPYTHON: C:\Python36\python.exe + PYTHON_HOME: C:\Python36 + PYTHON_VERSION: '3.6' + PYTHON_ARCH: '32' +{% for env in tox_environments %} +{% if env.startswith(('py2', 'py3')) %} + - TOXENV: {{ env }}{{ "" }} + TOXPYTHON: C:\Python{{ env[2:4] }}\python.exe + PYTHON_HOME: C:\Python{{ env[2:4] }} + PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}' + PYTHON_ARCH: '32' +{% if 'nocov' in env %} + WHEEL_PATH: .tox/dist +{% endif %} + - TOXENV: {{ env }}{{ "" }} + TOXPYTHON: C:\Python{{ env[2:4] }}-x64\python.exe + PYTHON_HOME: C:\Python{{ env[2:4] }}-x64 + PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}' + PYTHON_ARCH: '64' +{% if 'nocov' in env %} + WHEEL_PATH: .tox/dist +{% endif %} +{% if env.startswith('py2') %} + WINDOWS_SDK_VERSION: v7.0 +{% endif %} +{% endif %}{% endfor %} +init: + - ps: echo $env:TOXENV + - ps: ls C:\Python* +install: + - '%PYTHON_HOME%\python -mpip install --progress-bar=off tox -rci/requirements.txt' + - '%PYTHON_HOME%\Scripts\virtualenv --version' + - '%PYTHON_HOME%\Scripts\easy_install --version' + - '%PYTHON_HOME%\Scripts\pip --version' + - '%PYTHON_HOME%\Scripts\tox --version' +test_script: + - cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd %PYTHON_HOME%\Scripts\tox +on_failure: + - ps: dir "env:" + - ps: get-content .tox\*\log\* + +### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): +# on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/ci/templates/.travis.yml b/ci/templates/.travis.yml new file mode 100644 index 00000000..ae1b0ba1 --- /dev/null +++ b/ci/templates/.travis.yml @@ -0,0 +1,47 @@ +language: python +dist: xenial +virt: lxd +cache: false +env: + global: + - LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so + - SEGFAULT_SIGNALS=all + - LANG=en_US.UTF-8 +matrix: + include: + - python: '3.6' + env: + - TOXENV=check + - python: '3.6' + env: + - TOXENV=docs +{%- for env in tox_environments %}{{ '' }} + - env: + - TOXENV={{ env }},codecov +{%- if env.startswith('pypy3') %}{{ '' }} + python: 'pypy3' +{%- elif env.startswith('pypy') %}{{ '' }} + python: 'pypy' +{%- else %}{{ '' }} + python: '{{ '{0[2]}.{0[3]}'.format(env) }}' +{%- endif %}{{ '' }} +{%- endfor %}{{ '' }} +before_install: + - python --version + - uname -a + - lsb_release -a || true +install: + - python -mpip install --progress-bar=off tox -rci/requirements.txt + - virtualenv --version + - easy_install --version + - pip --version + - tox --version +script: + - tox -v +after_failure: + - cat .tox/log/* + - cat .tox/*/log/* +notifications: + email: + on_success: never + on_failure: always diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 0808f30e..00000000 --- a/docs/Makefile +++ /dev/null @@ -1,130 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/{{schema_name}}lib.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/{{schema_name}}lib.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/{{schema_name}}lib" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/{{schema_name}}lib" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/authors.rst b/docs/authors.rst new file mode 100644 index 00000000..e122f914 --- /dev/null +++ b/docs/authors.rst @@ -0,0 +1 @@ +.. include:: ../AUTHORS.rst diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 00000000..565b0521 --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1 @@ +.. include:: ../CHANGELOG.rst diff --git a/docs/conf.py b/docs/conf.py index 0ab007d7..8ff74865 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,253 +1,47 @@ # -*- coding: utf-8 -*- -# -# {{schema_name}}lib documentation build configuration file, created by -# sphinx-quickstart on Mon Jul 19 11:59:11 2010. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.txt' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'{{schema_name}}lib' -copyright = u'2010, Dave Kuhlman' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.0a' -# The full version, including alpha/beta/rc tags. -release = '1.0a' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = '{{schema_name}}libdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', '{{schema_name}}lib.tex', u'{{schema_name}}lib Documentation', - u'Dave Kuhlman', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', '{{schema_name}}lib', u'{{schema_name}}lib Documentation', - [u'Dave Kuhlman'], 1) +from __future__ import unicode_literals + +import os + +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.coverage', + 'sphinx.ext.doctest', + 'sphinx.ext.extlinks', + 'sphinx.ext.ifconfig', + 'sphinx.ext.napoleon', + 'sphinx.ext.todo', + 'sphinx.ext.viewcode', ] - - -# -- Options for Epub output --------------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = u'{{schema_name}}lib' -epub_author = u'Dave Kuhlman' -epub_publisher = u'Dave Kuhlman' -epub_copyright = u'2010, Dave Kuhlman' - -# The language of the text. It defaults to the language option -# or en if the language is not set. -#epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -#epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -#epub_identifier = '' - -# A unique identification for the text. -#epub_uid = '' - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -#epub_pre_files = [] - -# HTML files shat should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -#epub_post_files = [] - -# A list of files that should not be packed into the epub file. -#epub_exclude_files = [] - -# The depth of the table of contents in toc.ncx. -#epub_tocdepth = 3 +source_suffix = '.rst' +master_doc = 'index' +project = 'nfelib' +year = '2019-2020' +author = 'Raphael Valyi' +copyright = '{0}, {1}'.format(year, author) +version = release = '0.1.0' + +pygments_style = 'trac' +templates_path = ['.'] +extlinks = { + 'issue': ('https://github.com/erpbrasil/nfelib/issues/%s', '#'), + 'pr': ('https://github.com/erpbrasil/nfelib/pull/%s', 'PR #'), +} +# on_rtd is whether we are on readthedocs.org +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if not on_rtd: # only set the theme if we're building docs locally + html_theme = 'sphinx_rtd_theme' + +html_use_smartypants = True +html_last_updated_fmt = '%b %d, %Y' +html_split_index = False +html_sidebars = { + '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], +} +html_short_title = '%s-%s' % (project, version) + +napoleon_use_ivar = True +napoleon_use_rtype = False +napoleon_use_param = False diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 00000000..e582053e --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1 @@ +.. include:: ../CONTRIBUTING.rst diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 00000000..40f35b5e --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,22 @@ +======== +Contents +======== + +.. toctree:: + :maxdepth: 2 + + readme + installation + usage + reference/index + contributing + authors + changelog + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/docs/index.txt b/docs/index.txt deleted file mode 100644 index 0074b7d8..00000000 --- a/docs/index.txt +++ /dev/null @@ -1,25 +0,0 @@ -.. {{schema_name}}lib documentation master file, created by - sphinx-quickstart on Mon Jul 19 11:59:11 2010. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to {{schema_name}}lib's documentation! -=========================================================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - intro - module_contents - sample_code - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 00000000..71fa60d7 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,7 @@ +============ +Installation +============ + +At the command line:: + + pip install nfelib diff --git a/docs/intro.txt b/docs/intro.txt deleted file mode 100644 index 739b6ec5..00000000 --- a/docs/intro.txt +++ /dev/null @@ -1,41 +0,0 @@ -Introduction -============== - -{{schema_name}}lib helps to process XML instance documents that obey the -{{schema_name}} XML schema. - -With {{schema_name}}lib ({{schema_name}}lib.py) you can write -Python code to: - -- Parse an XML document that obeys the {{schema_name}} XML schema, - creating instances of the Python classes that represent the types - defined in the {{schema_name}} schema. These Python classes are - defined in {{schema_name}}lib.py. - -- Create instances of classes that represent the types described in - the {{schema_name}} XML schema. - -- Write Python application code that uses the classes that - represent {{schema_name}} types. - -- Export the objects to an XML document. - - -Schemas ---------- - -The {{schema_name}}lib.py module in this package was generated from the -XML schemas in ./schemas. - - -generateDS.py ---------------- - -The {{schema_name}}lib.py module in this package was generated by -generateDS.py. You can learn about generateDS.py here: -http://www.rexx.com/~dkuhlman/generateDS.html - - - - - diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index e1c7a356..00000000 --- a/docs/make.bat +++ /dev/null @@ -1,155 +0,0 @@ -<@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\{{schema_name}}lib.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\{{schema_name}}lib.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/docs/module_contents.txt b/docs/module_contents.txt deleted file mode 100644 index c37f1e0e..00000000 --- a/docs/module_contents.txt +++ /dev/null @@ -1,9 +0,0 @@ -Module contents -================= - -.. automodule:: {{schema_name}}lib - :members: - :undoc-members: - :show-inheritance: - - diff --git a/docs/readme.rst b/docs/readme.rst new file mode 100644 index 00000000..72a33558 --- /dev/null +++ b/docs/readme.rst @@ -0,0 +1 @@ +.. include:: ../README.rst diff --git a/docs/reference/index.rst b/docs/reference/index.rst new file mode 100644 index 00000000..a5f460ea --- /dev/null +++ b/docs/reference/index.rst @@ -0,0 +1,7 @@ +Reference +========= + +.. toctree:: + :glob: + + nfelib* diff --git a/docs/reference/nfelib.rst b/docs/reference/nfelib.rst new file mode 100644 index 00000000..658f9aa2 --- /dev/null +++ b/docs/reference/nfelib.rst @@ -0,0 +1,9 @@ +nfelib +============== + +.. testsetup:: + + from nfelib import * + +.. automodule:: nfelib + :members: diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..37da9aee --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx>=1.3 +sphinx-rtd-theme diff --git a/docs/sample_code.txt b/docs/sample_code.txt deleted file mode 100644 index 80fd2b7b..00000000 --- a/docs/sample_code.txt +++ /dev/null @@ -1,10 +0,0 @@ -Sample Code -============= - -See ./sample_code/README.txt - -.. include:: ../sample_code/README.txt - - - - diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt new file mode 100644 index 00000000..f95eb78d --- /dev/null +++ b/docs/spelling_wordlist.txt @@ -0,0 +1,11 @@ +builtin +builtins +classmethod +staticmethod +classmethods +staticmethods +args +kwargs +callstack +Changelog +Indices diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 00000000..49d1ec95 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,7 @@ +===== +Usage +===== + +To use nfelib in a project:: + + import nfelib diff --git a/nfelib/__init__.py b/nfelib/__init__.py new file mode 100644 index 00000000..5a6f84c5 --- /dev/null +++ b/nfelib/__init__.py @@ -0,0 +1 @@ +__version__ = '0.5' diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..918f7145 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,35 @@ +[bdist_wheel] +universal = 1 + +[flake8] +max-line-length = 140 +exclude = .tox,.eggs,ci/templates,build,dist + +[tool:pytest] +# If a pytest section is found in one of the possible config files +# (pytest.ini, tox.ini or setup.cfg), then pytest will not look for any others, +# so if you add a pytest config section elsewhere, +# you will need to delete this section from setup.cfg. +norecursedirs = + migrations + +python_files = + test_*.py + *_test.py + tests.py +addopts = + -ra + --strict + --doctest-modules + --doctest-glob=\*.rst + --tb=short +testpaths = + tests + +[tool:isort] +force_single_line = True +line_length = 120 +known_first_party = nfelib +default_section = THIRDPARTY +forced_separate = test_nfelib +skip = .tox,.eggs,ci/templates,build,dist diff --git a/setup.py b/setup.py index 72c15ed8..703a6e79 100644 --- a/setup.py +++ b/setup.py @@ -1,21 +1,41 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- +# -*- encoding: utf-8 -*- +from __future__ import absolute_import +from __future__ import print_function -from setuptools import setup, find_packages +import io +import re +from os.path import dirname +from os.path import join + +from setuptools import find_packages +from setuptools import setup + + +def read(*names, **kwargs): + with io.open( + join(dirname(__file__), *names), + encoding=kwargs.get('encoding', 'utf8') + ) as fh: + return fh.read() -with open('README.md', 'r') as f: - readme = f.read() setup( name='nfelib', version='0.5', + license='MIT', + description='nfelib: electronic invoicing library for Brazil', + long_description='%s\n%s\n%s' % ( + re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub('', read('README.rst')), + re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('AUTHORS.rst')), + re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst')) + ), author='Raphael Valyi', author_email='raphael.valyi@akretion.com', - url='https://github.com/akretion/nfelib', - description='nfelib: electronic invoicing library for Brazil', - long_description=readme, - long_description_content_type='text/markdown', - license='MIT', + url='https://github.com/erpbrasil/nfelib', + packages=find_packages(), + include_package_data=True, + zip_safe=False, classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', @@ -28,9 +48,6 @@ 'Programming Language :: Python :: 3.7', ], keywords='e-invoice NFe ERP Odoo', - packages=find_packages(), - include_package_data=True, python_requires=">=3.5", scripts=[], - zip_safe=False, ) diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..fb1b65c7 --- /dev/null +++ b/tox.ini @@ -0,0 +1,83 @@ +[testenv:bootstrap] +deps = + jinja2 + matrix + tox +skip_install = true +commands = + python ci/bootstrap.py --no-env +passenv = + * +; a generative tox configuration, see: https://tox.readthedocs.io/en/latest/config.html#generative-envlist + +[tox] +envlist = + clean, + check, + docs, + {py35,py36,py37,py38,py39,pypy,pypy3}, + report +ignore_basepython_conflict = true + +[testenv] +basepython = + pypy3: {env:TOXPYTHON:pypy3} + py35: {env:TOXPYTHON:python3.5} + py36: {env:TOXPYTHON:python3.6} + py37: {env:TOXPYTHON:python3.7} + py38: {env:TOXPYTHON:python3.8} + py39: {env:TOXPYTHON:python3.9} + {bootstrap,clean,check,report,codecov,docs}: {env:TOXPYTHON:python3} +setenv = + PYTHONPATH={toxinidir}/tests + PYTHONUNBUFFERED=yes +passenv = + * +usedevelop = false +deps = + pytest + pytest-travis-fold + pytest-cov + xmldiff +commands = + {posargs:pytest --cov --cov-report=term-missing -vv tests} + +[testenv:check] +deps = + docutils + check-manifest + readme-renderer + pygments +skip_install = true +commands = + python setup.py check --strict --metadata --restructuredtext + check-manifest {toxinidir} + +[testenv:docs] +usedevelop = true +deps = + -r{toxinidir}/docs/requirements.txt +commands = + sphinx-build {posargs:-E} -b html docs dist/docs + sphinx-build -b linkcheck docs dist/docs + +[testenv:codecov] +deps = + codecov +skip_install = true +commands = + coverage xml --ignore-errors + codecov [] + +[testenv:report] +deps = + coverage +skip_install = true +commands = + coverage report + coverage html + +[testenv:clean] +commands = coverage erase +skip_install = true +deps = coverage