From 88c1dc538380ac88c479db4e9902253bdcf3482a Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Sun, 17 Jan 2010 21:59:53 -0300 Subject: [PATCH 01/17] correcao da identacao --- pynfe/processamento/assinatura.py | 76 +++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/pynfe/processamento/assinatura.py b/pynfe/processamento/assinatura.py index 74fc3b6..44b81a9 100644 --- a/pynfe/processamento/assinatura.py +++ b/pynfe/processamento/assinatura.py @@ -6,25 +6,25 @@ except ImportError: from StringIO import StringIO try: - from lxml import etree + from lxml import etree except ImportError: - try: - # Python 2.5 - cElementTree - import xml.etree.cElementTree as etree - except ImportError: try: - # Python 2.5 - ElementTree - import xml.etree.ElementTree as etree + # Python 2.5 - cElementTree + import xml.etree.cElementTree as etree except ImportError: - try: - # Instalacao normal do cElementTree - import cElementTree as etree - except ImportError: try: - # Instalacao normal do ElementTree - import elementtree.ElementTree as etree + # Python 2.5 - ElementTree + import xml.etree.ElementTree as etree except ImportError: - raise Exception('Falhou ao importar lxml/ElementTree') + try: + # Instalacao normal do cElementTree + import cElementTree as etree + except ImportError: + try: + # Instalacao normal do ElementTree + import elementtree.ElementTree as etree + except ImportError: + raise Exception('Falhou ao importar lxml/ElementTree') import xmlsec, libxml2 # FIXME: verificar ambiguidade de dependencias: lxml e libxml2 @@ -54,11 +54,11 @@ class Assinatura(object): def assinar_etree(self, raiz): u"""Efetua a assinatura numa instancia da biblioteca lxml.etree. - + Este metodo de assinatura será utilizado internamente pelos demais, sendo que eles convertem para uma instancia lxml.etree para somente depois efetivar a assinatura. - + TODO: Verificar o funcionamento da PyXMLSec antes de efetivar isso.""" pass @@ -86,7 +86,7 @@ def extrair_tag(root): class AssinaturaA1(Assinatura): """Classe abstrata responsavel por efetuar a assinatura do certificado digital no XML informado.""" - + def assinar_arquivo(self, caminho_arquivo): # Carrega o XML do arquivo raiz = etree.parse(caminho_arquivo) @@ -113,10 +113,10 @@ class AssinaturaA1(Assinatura): # Tag de assinatura if raiz.getroot().find('Signature') is None: signature = etree.Element( - 'Signature', - URI=raiz.getroot().getchildren()[0].attrib['Id'], - xmlns=NAMESPACE_SIG, - ) + 'Signature', + URI=raiz.getroot().getchildren()[0].attrib['Id'], + xmlns=NAMESPACE_SIG, + ) signature.text = '' raiz.getroot().insert(0, signature) @@ -132,26 +132,26 @@ class AssinaturaA1(Assinatura): # Colocamos o texto no avaliador XML #doc_xml = libxml2.parseMemory(xml, len(xml)) - + # Cria o contexto para manipulação do XML via sintaxe XPATH #ctxt = doc_xml.xpathNewContext() #ctxt.xpathRegisterNs(u'sig', NAMESPACE_SIG) - + # Separa o nó da assinatura #noh_assinatura = ctxt.xpathEval(u'//*/sig:Signature')[0] - + # Buscamos a chave no arquivo do certificado chave = xmlsec.cryptoAppKeyLoad( - filename=str(self.certificado.caminho_arquivo), - format=xmlsec.KeyDataFormatPkcs12, - pwd=str(self.senha), - pwdCallback=None, - pwdCallbackCtx=None, - ) - + filename=str(self.certificado.caminho_arquivo), + format=xmlsec.KeyDataFormatPkcs12, + pwd=str(self.senha), + pwdCallback=None, + pwdCallbackCtx=None, + ) + # Cria a variável de chamada (callable) da função de assinatura assinador = xmlsec.DSigCtx() - + # Atribui a chave ao assinador assinador.signKey = chave @@ -164,26 +164,26 @@ class AssinaturaA1(Assinatura): # Ativa as funções de análise de arquivos XML FIXME libxml2.initParser() libxml2.substituteEntitiesDefault(1) - + # Ativa as funções da API de criptografia xmlsec.init() xmlsec.cryptoAppInit(None) xmlsec.cryptoInit() - + def _desativa_funcoes_criptograficas(self): ''' Desativa as funções criptográficas e de análise XML As funções devem ser chamadas aproximadamente na ordem inversa da ativação ''' - + # Shutdown xmlsec-crypto library xmlsec.cryptoShutdown() - + # Shutdown crypto library xmlsec.cryptoAppShutdown() - + # Shutdown xmlsec library xmlsec.shutdown() - + # Shutdown LibXML2 FIXME libxml2.cleanupParser() From 5fce583aa52359e458a81829032dd99187c73984 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Sun, 17 Jan 2010 22:07:55 -0300 Subject: [PATCH 02/17] so testando. Adicionei um import --- pynfe/processamento/validacao.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pynfe/processamento/validacao.py b/pynfe/processamento/validacao.py index e9a85c1..405288a 100644 --- a/pynfe/processamento/validacao.py +++ b/pynfe/processamento/validacao.py @@ -1,3 +1,26 @@ +#-*- coding:utf-8 -*- + +try: + from lxml import etree +except ImportError: + try: + # Python 2.5 - cElementTree + import xml.etree.cElementTree as etree + except ImportError: + try: + # Python 2.5 - ElementTree + import xml.etree.ElementTree as etree + except ImportError: + try: + # Instalacao normal do cElementTree + import cElementTree as etree + except ImportError: + try: + # Instalacao normal do ElementTree + import elementtree.ElementTree as etree + except ImportError: + raise Exception('Falhou ao importar lxml/ElementTree') + class Validacao(object): pass From e42a67637211084ef1b1f176951a29fd16c3f562 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Mon, 18 Jan 2010 01:02:38 -0300 Subject: [PATCH 03/17] mudei a identacao para a ide aqui parar de xiar e atualizei validacao.py --- pynfe/data/XSDs/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pynfe/data/XSDs/README b/pynfe/data/XSDs/README index e5c82ce..0ed3562 100644 --- a/pynfe/data/XSDs/README +++ b/pynfe/data/XSDs/README @@ -58,10 +58,10 @@ Descrição unitária de cada schema - Pedido de Cancelamento de NF-e processado - inclui: leiauteCancNFe_v1.07 -- procInutNFe_v1.07: +- procInutNFe_v1.07 - Pedido de inutilzação de númeração de NF-e processado - inclui: leiauteInutNFe_v1.07 - procNFe_v1.10 - NF-e processada - - incluid: leiauteNFe_v1.10 \ No newline at end of file + - incluid: leiauteNFe_v1.10 From e9635d4c468fb26d509c0d6d50c6f87966fcad36 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Tue, 19 Jan 2010 16:39:31 -0300 Subject: [PATCH 04/17] adicionados testes para validacao --- tests/02-modelo-07-validacao.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/02-modelo-07-validacao.txt diff --git a/tests/02-modelo-07-validacao.txt b/tests/02-modelo-07-validacao.txt new file mode 100644 index 0000000..d3a58c8 --- /dev/null +++ b/tests/02-modelo-07-validacao.txt @@ -0,0 +1,31 @@ +Validação +--------- +A validação dos arquivos de nota fiscal são controladas pelo módulo validacao. + + >>> from processamento import validacao + +A classe Validacao é utilizada para validar os tanto arquivos xml quanto documentos +etree. Não há problemas em utilizar list-comprehension com a mesma pois ela implementa +um cache simples. + + >>> val = validacao.Validacao() + >>> nfe_caminho = 'tests/xml/NFe.xml' + >>> nfe_assin_caminho = 'tests/xml/NFe_assinada.xml' + >>> nfe_inval_caminho = 'tests/xml/NFe_falhaSchema.xml' + >>> val.validar_xml(nfe_caminho, validacao.XSD_NFE) + True + >>> import lxml as etree + >>> val.validar_etree(etree.parse(nfe_caminho), validacao.XSD_NFE) + True + >>> val.validar_xml(nfe_assin_caminho, XSD_NFE_PROCESSADA) + True + >>> val.validar_xml(nfe_inval_caminho, XSD_NFE) + False + +Note que o schema utilizado para validação contra o xml é definido por variáveis +globais presentes no módulo. São elas: + +- XSD_NFE : valida nfe's não certificadas +- XSD_NFE_PROCESSADA : valida nfe's certificadas +- XSD_PD_CANCELAR_NFE : valida um pedido de cancelamento de nfe +- XSD_PD_INUTILIZAR_NFE : valida um pedido de inutilização de nfe \ No newline at end of file From 9f2fbbabf867e87b6565ccccc2b028b62d22c265 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Tue, 19 Jan 2010 16:40:22 -0300 Subject: [PATCH 05/17] adicionados arquivos exemplo de nfe para testes --- tests/xml/NFe.xml | 223 ++++++++++++++++++++++++++++++++++++++++++ tests/xml/NFe_assinada.xml | 1 + tests/xml/NFe_falhaSchema.xml | 223 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 447 insertions(+) create mode 100644 tests/xml/NFe.xml create mode 100644 tests/xml/NFe_assinada.xml create mode 100644 tests/xml/NFe_falhaSchema.xml diff --git a/tests/xml/NFe.xml b/tests/xml/NFe.xml new file mode 100644 index 0000000..189d825 --- /dev/null +++ b/tests/xml/NFe.xml @@ -0,0 +1,223 @@ + + + + + 35 + 518005127 + Venda a vista + 0 + 55 + 1 + 1 + 2008-05-06 + 2008-05-06 + 0 + 3550308 + 1 + 1 + 3 + 2 + 1 + 0 + NF-eletronica.com + + + 99999090910270 + NF-e Associacao NF-e + NF-e + + Rua Central + 100 + Fundos + Distrito Industrial + 3502200 + Angatuba + SP + 17100171 + 1058 + Brasil + 1733021717 + + 123456789012 + + + 00000000000191 + DISTRIBUIDORA DE AGUAS MINERAIS + + AV DAS FONTES + 1777 + 10 ANDAR + PARQUE FONTES + 5030801 + Sao Paulo + SP + 13950000 + 1058 + BRASIL + 1932011234 + + + + + 99171171000194 + AV PAULISTA + 12345 + TERREO + CERQUEIRA CESAR + 3550308 + SAO PAULO + SP + + + 99299299000194 + AV FARIA LIMA + 1500 + 15 ANDAR + PINHEIROS + 3550308 + SAO PAULO + SP + + + + 00001 + + Agua Mineral + 5101 + dz + 1000000.0000 + 1 + 10000000.00 + + und + 12000000.0000 + 1 + + + + + 0 + 00 + 0 + 10000000.00 + 18.00 + 1800000.00 + + + + + 01 + 10000000.00 + 0.65 + 65000 + + + + + 01 + 10000000.00 + 2.00 + 200000.00 + + + + + + + 00002 + + Agua Mineral + 5101 + pack + 5000000.0000 + 2 + 10000000.00 + + und + 3000000.0000 + 0.3333 + + + + + 0 + 00 + 0 + 10000000.00 + 18.00 + 1800000.00 + + + + + 01 + 10000000.00 + 0.65 + 65000 + + + + + 01 + 10000000.00 + 2.00 + 200000.00 + + + + + + + 20000000.00 + 18.00 + 0 + 0 + 20000000.00 + 0 + 0 + 0 + 0 + 0 + 130000.00 + 400000.00 + 0 + 20000000.00 + + + + 0 + + 99171171000191 + Distribuidora de Bebidas Fazenda de SP Ltda. + 171999999119 + Rua Central 100 - Fundos - Distrito Industrial + SAO PAULO + SP + + + BXI1717 + SP + 123456789 + + + BXI1818 + SP + 123456789 + + + 10000 + CAIXA + LINDOYA + 500 + 1000000000.000 + 1200000000.000 + + XYZ10231486 + + + + + Nota Fiscal de exemplo NF-eletronica.com + + + \ No newline at end of file diff --git a/tests/xml/NFe_assinada.xml b/tests/xml/NFe_assinada.xml new file mode 100644 index 0000000..e3dc170 --- /dev/null +++ b/tests/xml/NFe_assinada.xml @@ -0,0 +1 @@ +35518005127Venda a vista055112008-05-062008-05-0603550308113210NF-eletronica.com99999090910270NF-e Associacao NF-eNF-eRua Central100FundosDistrito Industrial3502200AngatubaSP171001711058Brasil173302171712345678901200000000000191DISTRIBUIDORA DE AGUAS MINERAISAV DAS FONTES177710 ANDARPARQUE FONTES5030801Sao PauloSP139500001058BRASIL193201123499171171000194AV PAULISTA12345TERREOCERQUEIRA CESAR3550308SAO PAULOSP99299299000194AV FARIA LIMA150015 ANDARPINHEIROS3550308SAO PAULOSP00001Agua Mineral5101dz1000000.0000110000000.00und12000000.00001000010000000.0018.001800000.000110000000.000.65650000110000000.002.00200000.0000002Agua Mineral5101pack5000000.0000210000000.00und3000000.00000.3333000010000000.0018.001800000.000110000000.000.65650000110000000.002.00200000.0020000000.0018.000020000000.0000000130000.00400000.00020000000.00099171171000191Distribuidora de Bebidas Fazenda de SP Ltda.171999999119Rua Central 100 - Fundos - Distrito IndustrialSAO PAULOSPBXI1717SP123456789BXI1818SP12345678910000CAIXALINDOYA5001000000000.0001200000000.000XYZ10231486Nota Fiscal de exemplo NF-eletronica.comxhTSDMH61e9uqe04lnoHT4ZzLSY=Iz5Z3PLQbzZt9jnBtr6xsmHZMOu/3plXG9xxfFjRCQYGnD1rjlhzBGrqt026Ca2VHHM/bHNepi6FuFkAi595GScKVuHREUotzifE2OIjgavvTOrMwbXG7+0LYgkwPFiPCao2S33UpZe7MneaxcmKQGKQZw1fP8fsWmaQ4cczZT8=MIIEuzCCA6OgAwIBAgIDMTMxMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYDVQQGEwJCUjELMAkGA1UECBMCUlMxFTATBgNVBAcTDFBvcnRvIEFsZWdyZTEdMBsGA1UEChMUVGVzdGUgUHJvamV0byBORmUgUlMxHTAbBgNVBAsTFFRlc3RlIFByb2pldG8gTkZlIFJTMSEwHwYDVQQDExhORmUgLSBBQyBJbnRlcm1lZGlhcmlhIDEwHhcNMDgwNDI4MDkwMTAyWhcNMDkwNDMwMjM1OTU5WjCBnjELMAkGA1UECBMCUlMxHTAbBgNVBAsTFFRlc3RlIFByb2pldG8gTkZlIFJTMR0wGwYDVQQKExRUZXN0ZSBQcm9qZXRvIE5GZSBSUzEVMBMGA1UEBxMMUE9SVE8gQUxFR1JFMQswCQYDVQQGEwJCUjEtMCsGA1UEAxMkTkZlIC0gQXNzb2NpYWNhbyBORi1lOjk5OTk5MDkwOTEwMjcwMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDh6RRv0bj4RYX+tDQrZRb5opa77LBVVs+6LphIfSF3TSWPfnKh0+xLlBFdmnB5YGgbbW9Uon6pZQTfaC8jZhRhI5eFRRofY/Ugoeo0NGt6PcIQNZQd6lLQ/ASd1qWwjqJoEa7udriKjy3h351Mf1bng1VxS1urqC3Dn39ZWIEwQIDAQABo4IBjjCCAYowIgYDVR0jAQEABBgwFoAUPT5TqhNWAm+ZpcVsvB7malDBjEQwDwYDVR0TAQH/BAUwAwEBADAPBgNVHQ8BAf8EBQMDAOAAMAwGA1UdIAEBAAQCMAAwgbwGA1UdEQEBAASBsTCBrqA4BgVgTAEDBKAvBC0wNzA4MTk1MTE1MTk0NTMxMDg3MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDCgHQYFYEwBAwKgFAQSRmVybmFuZG8gQ2FudG8gQWx0oBkGBWBMAQMDoBAEDjk5OTk5MDkwOTEwMjcwoBcGBWBMAQMHoA4EDDAwMDAwMDAwMDAwMIEfZmVybmFuZG8tYWx0QHByb2NlcmdzLnJzLmdvdi5icjAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwUwYDVR0fAQEABEkwRzBFoEOgQYY/aHR0cDovL25mZWNlcnRpZmljYWRvLnNlZmF6LnJzLmdvdi5ici9MQ1IvQUNJbnRlcm1lZGlhcmlhMzguY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCNPpaZ3Byu3/70nObXE8NiM53j1ddIFXsb+v2ghCVd4ffExv3hYc+/a3lfgV8H/WfQsdSCTzS2cHrd4Aasr/eXfclVDmf2hcWz+R7iysOHuT6B6r+DvV3JcMdJJCDdynR5REa+zViMnVZo1G3KuceQ7/y5X3WFNVq4kwHvonJ9oExsWyw8rTwUK5bsjz0A2yEwXkmkJIngnF41sP31+9jCImiqkXcmsesFhxzX7iurAQAQCZOm7iwMWxQKcAjXCZrgSZWRQy6mU224sX3HTArHahmLJ9Iw+WYAua5qBJsiN6PC7v5tfhrEQFpcG39yMnOecxvkkPolDUyBa7d7xwgm \ No newline at end of file diff --git a/tests/xml/NFe_falhaSchema.xml b/tests/xml/NFe_falhaSchema.xml new file mode 100644 index 0000000..cc8b1ac --- /dev/null +++ b/tests/xml/NFe_falhaSchema.xml @@ -0,0 +1,223 @@ + + + + + 35 + 518005127 + Venda a vista + 0 + 55 + 1 + 1 + 2008-05-06 + 2008-05-06 + 0 + 3550308 + 1 + 1 + 3 + 2 + 1 + 0 + NF-eletronica.com 123456 + + + 99999090910270 + NF-e Associacao NF-e + NF-e + + Rua Central + 100 + Fundos + Distrito Industrial + 3502200 + Angatuba + SP + 17100171 + 1058 + Brasil + 1733021717 + + 123456789012 + + + 00000000000191 + DISTRIBUIDORA DE AGUAS MINERAIS + + AV DAS FONTES + 1777 + 10 ANDAR + PARQUE FONTES + 5030801 + Sao Paulo + SP + 13950000 + 1058 + BRASIL + 1932011234 + + + + + 99171171000194 + AV PAULISTA + 12345 + TERREO + CERQUEIRA CESAR + 3550308 + SAO PAULO + SP + + + 99299299000194 + AV FARIA LIMA + 1500 + 15 ANDAR + PINHEIROS + 3550308 + SAO PAULO + SP + + + + 00001 + + Agua Mineral + 5101 + dz + 1000000.00 + 1 + 10000000.00 + + und + 12000000.00 + 1 + + + + + 0 + 00 + 0 + 10000000.00 + 18.00 + 1800000.00 + + + + + 01 + 10000000.00 + 0.65 + 65000 + + + + + 01 + 10000000.00 + 2.00 + 200000.00 + + + + + + + 00002 + + Agua Mineral + 5101 + pack + 5000000.0000 + 2 + 10000000.00 + + und + 3000000.0000 + 0.3333 + + + + + 0 + 00 + 0 + 10000000.00 + 18.00 + 1800000.00 + + + + + 01 + 10000000.00 + 0.65 + 65000 + + + + + 01 + 10000000.00 + 2.00 + 200000.00 + + + + + + + 20000000.00 + 18.00 + 0 + 0 + 20000000.00 + 0 + 0 + 0 + 0 + 0 + 130000.00 + 400000.00 + 0 + 20000000.00 + + + + 0 + + 99171171000191 + Distribuidora de Bebidas Fazenda de SP Ltda. + 171999999119 + Rua Central 100 - Fundos - Distrito Industrial + SAO PAULO + SP + + + BXI1717 + SP + 123456789 + + + BXI1818 + SP + 123456789 + + + 10000 + CAIXA + LINDOYA + 500 + 1000000000.000 + 1200000000.000 + + XYZ10231486 + + + + + Nota Fiscal de exemplo NF-eletronica.com + + + \ No newline at end of file From 767b4d524d6ac3a0ec8dac8e3c084720931b865b Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Tue, 19 Jan 2010 17:29:27 -0300 Subject: [PATCH 06/17] =?UTF-8?q?adicionada=20op=C3=A7=C3=A3o=20de=20run?= =?UTF-8?q?=5Flevel.=20Permite=20escolher=20qual=20n=C3=ADvel=20de=20teste?= =?UTF-8?q?s=20ser=C3=A1=20executado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- run_tests.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/run_tests.py b/run_tests.py index cfa92bb..8dcf69e 100644 --- a/run_tests.py +++ b/run_tests.py @@ -1,11 +1,24 @@ import sys, doctest, os, glob +from getopt import gnu_getopt as getopt CUR_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, CUR_DIR) if __name__ == '__main__': + run_level = None + optlist, args = getopt(sys.argv[1:], "l:", ['--level=']) + + for opt, arg in optlist: + if opt in ("-l", "--list"): + run_level = arg.zfill(2) + # Test each package - test_files = glob.glob('%s/*.txt' % os.path.join(CUR_DIR, 'tests')) + if run_level is None: + test_files = glob.glob('%s/*.txt' % os.path.join(CUR_DIR, 'tests')) + else: + test_files = glob.glob('%s/%s-*.txt' % \ + (os.path.join(CUR_DIR, 'tests'), run_level)) + test_files = map(lambda i: i[len(CUR_DIR)+1:], test_files) # Run the tests From 58006e0390ab0490ea8b363db97bb7f12cad29df Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Wed, 20 Jan 2010 11:24:07 -0300 Subject: [PATCH 07/17] corrigi a identacao. Alguns testes estavam falhando aqui por conta disto --- tests/01-basico.txt | 196 ++++++++++++++++++++++++++-------------------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/tests/01-basico.txt b/tests/01-basico.txt index c751688..994eddb 100644 --- a/tests/01-basico.txt +++ b/tests/01-basico.txt @@ -1,145 +1,145 @@ TESTES BASICOS ============== - + >>> try: - ... set + ... set ... except: - ... from sets import Set as set + ... from sets import Set as set - + A biblioteca deve fornecer uma colecao de utilitarios para consumir o webservice da NF-e. - + Componentes ----------- - + A separacao entre os componentes da biblioteca deve seguir o seguinte modelo: - + --------------------------------------------------------------------- - | MODELO DE ENTIDADES | + | MODELO DE ENTIDADES | --------------------------------------------------------------------- - | | - | ------------ -------------- | - | | Entidade |-------<>| FonteDados | | - | ------------ -------------- | - | A | - | | | - | ----especializacao-------------------------- | - | | | | | | - | ------------ ----------- ----------- ------------------ | - | | Emitente | | Produto | | Cliente | | Transportadora | | - | ------------ ----------- ----------- ------------------ | - | *| *| *| *| | - | ------------------------------associacao---- | - | | | - | V* | - | --------------- ---------------- | - | | Nota Fiscal |------<>| Lote de NF-e | | - | --------------- 1 * ---------------- | - | | + | | + | ------------ -------------- | + | | Entidade |-------<>| FonteDados | | + | ------------ -------------- | + | A | + | | | + | ----especializacao-------------------------- | + | | | | | | + | ------------ ----------- ----------- ------------------ | + | | Emitente | | Produto | | Cliente | | Transportadora | | + | ------------ ----------- ----------- ------------------ | + | *| *| *| *| | + | ------------------------------associacao---- | + | | | + | V* | + | --------------- ---------------- | + | | Nota Fiscal |------<>| Lote de NF-e | | + | --------------- 1 * ---------------- | + | | --------------------------------------------------------------------- - - + + ---------------------------------------------------------------------------- - | PROCESSAMENTO | + | PROCESSAMENTO | ---------------------------------------------------------------------------- - | | - | ------------------ -------------- -------------------------------- | - | | Serializacao | | DANFE | | Comunicacao | | - | ------------------ -------------- -------------------------------- | - | | exportar() | | imprimir() | | transmitir() | | - | | importar() | -------------- | cancelar() | | - | ------------------ | situacao_nfe() | | - | | status_servico() | | - | ---------------------- | consultar_cadastro() | | - | | Validacao | | inutilizar_faixa_numeracao() | | - | ---------------------- -------------------------------- | - | | validar_arquivo() | | - | | validar_xml() | | - | | validar_etree() | ---------------------- | - | | validar_objetos() | | Assinatura | | - | ---------------------- ---------------------- | - | | assinar_arquivo() | | - | | assinar_xml() | | - | | assinar_etree() | | - | | assinar_objetos() | | - | ---------------------- | + | | + | ------------------ -------------- -------------------------------- | + | | Serializacao | | DANFE | | Comunicacao | | + | ------------------ -------------- -------------------------------- | + | | exportar() | | imprimir() | | transmitir() | | + | | importar() | -------------- | cancelar() | | + | ------------------ | situacao_nfe() | | + | | status_servico() | | + | ---------------------- | consultar_cadastro() | | + | | Validacao | | inutilizar_faixa_numeracao() | | + | ---------------------- -------------------------------- | + | | validar_arquivo() | | + | | validar_xml() | | + | | validar_etree() | ---------------------- | + | | validar_objetos() | | Assinatura | | + | ---------------------- ---------------------- | + | | assinar_arquivo() | | + | | assinar_xml() | | + | | assinar_etree() | | + | | assinar_objetos() | | + | ---------------------- | ---------------------------------------------------------------------------- - + Os pacotes da biblioteca sao: - -- utils (contem todas as funcionalidades utilitarias dentro da + +- utils (contem todas as funcionalidades utilitarias dentro da biblioteca, incluindo flags e funcoes genericas) - + >>> from pynfe import utils >>> set([attr for attr in dir(utils) if not attr.startswith('__')]) >= set(['flags']) True - + - entidades (contem todas as entidades da biblioteca) - + >>> from pynfe import entidades >>> set([attr for attr in dir(entidades) if not attr.startswith('__')]) == set([ - ... 'Cliente', 'Emitente', 'LoteNotaFiscal', 'NotaFiscal', 'Produto', - ... 'Transportadora', 'base', 'cliente', 'emitente', 'lotes', 'notafiscal', - ... 'produto', 'transportadora', 'fonte_dados', '_fonte_dados','certificado', - ... 'CertificadoA1']) + ... 'Cliente', 'Emitente', 'LoteNotaFiscal', 'NotaFiscal', 'Produto', + ... 'Transportadora', 'base', 'cliente', 'emitente', 'lotes', 'notafiscal', + ... 'produto', 'transportadora', 'fonte_dados', '_fonte_dados','certificado', + ... 'CertificadoA1']) True - + - processamento (contem todas as funcionalidades de processamento da biblioteca - + >>> from pynfe import processamento >>> set([attr for attr in dir(processamento) if not attr.startswith('__')]) == set([ - ... 'AssinaturaA1', 'ComunicacaoSefaz', 'DANFE', 'SerializacaoXML', 'Validacao', - ... 'assinatura', 'comunicacao', 'danfe', 'serializacao', 'validacao']) + ... 'AssinaturaA1', 'ComunicacaoSefaz', 'DANFE', 'SerializacaoXML', 'Validacao', + ... 'assinatura', 'comunicacao', 'danfe', 'serializacao', 'validacao']) True - + Ha ainda uma pasta dentro da pasta 'pynfe', chamada 'data', que deve armazenar listas longas de municipios, CNAEs, situacoes tributarias, XSD's, etc. - + >>> import os >>> DATA = os.path.join(os.curdir, 'pynfe', 'data') >>> DATA './pynfe/data' - + >>> os.path.isdir(DATA) True - + Geracao e importacao de XML --------------------------- - + As objetos Python devem ser traduzidos para arquivos XML e o caminho inverso, de introspecao, tambem deve ser feito, atraves de uma fabrica. - + >>> from pynfe.processamento.serializacao import Serializacao - + >>> bool(Serializacao.exportar) True - + >>> bool(Serializacao.importar) True - + A classe basica de Serializacao eh abstrata, ou seja, nao pode ser instanciada diretamente. - + >>> lista_de_nfs = [] - + >>> try: - ... Serializacao(lista_de_nfs) + ... Serializacao(lista_de_nfs) ... except Exception, e: - ... print e.message + ... print e.message Esta classe nao pode ser instanciada diretamente! - + Classe de serializacao especifica para XML, usando lxml - + >>> from pynfe.processamento.serializacao import SerializacaoXML - + Esse procedimento sera feito por padrao atraves da lxml, devido ao seu desempenho, mas pode ser extendido para outros formatos, dependendo do objetivo pretendido. - + >>> try: ... from lxml import etree ... except ImportError: @@ -148,7 +148,7 @@ objetivo pretendido. ... import xml.etree.cElementTree as etree ... except ImportError: ... try: - ... # Python 2.5 + ... # Python 2.5 ... import xml.etree.ElementTree as etree ... except ImportError: ... try: @@ -160,45 +160,45 @@ objetivo pretendido. ... import elementtree.ElementTree as etree ... except ImportError: ... print("A importacao do lxml falhou") - + Consumacao de WebService ------------------------ - + O webservice a ser consumido esta no padrao SOAP, que no Python sera interpretado pela biblioteca SUDS. - + >>> import suds - + Para executar estes testes é preciso instalar a soaplib, para servir WSDL via SOAP, num servidor falso (mock). - + >>> import soaplib - + Certificados Digitais --------------------- - + A biblioteca deve suportar certificados digitais X.509 v.3 do tipo A1. O tipo A3 é certificado por hardware e provavelmente bem mais complexo de colocar em prática. - + eCNPJ A1 - + A3 depende de configurar seu numero de serie. No Windows usa-se a DLL CAPICOM. Ao que tudo indica, o OpenSSL nao suporta esse tipo. - + A transmissao utiliza SSL3. - + No Windows o arquivo é usado como .pfx (pkcs12) - + No Linux o arquivo deve ser convertido para .pem - + Impressao do DANFE ------------------ - + Alem disso, deve gerar PDFs da DANFE, utilizando a engine Geraldo Reports. - + >>> import geraldo >>> import PIL >>> from pynfe.utils import bar_code_128 From 70045164324f78e47f8510a21a4d3adf72b9d8e3 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Wed, 20 Jan 2010 11:26:02 -0300 Subject: [PATCH 08/17] embelezando o codigo um pouco --- run_tests.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/run_tests.py b/run_tests.py index 8dcf69e..072fe01 100644 --- a/run_tests.py +++ b/run_tests.py @@ -14,11 +14,11 @@ if __name__ == '__main__': # Test each package if run_level is None: - test_files = glob.glob('%s/*.txt' % os.path.join(CUR_DIR, 'tests')) - else: - test_files = glob.glob('%s/%s-*.txt' % \ - (os.path.join(CUR_DIR, 'tests'), run_level)) + search_path = '%s/*.txt' % os.path.join(CUR_DIR, 'tests') + else: search_path = '%s/%s-*.txt' % \ + (os.path.join(CUR_DIR, 'tests'), run_level) + test_files = glob.glob(search_path) test_files = map(lambda i: i[len(CUR_DIR)+1:], test_files) # Run the tests From a9d028ab863481f1f7b6bd4520edb23be2816fb7 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Wed, 20 Jan 2010 23:18:04 -0300 Subject: [PATCH 09/17] corrigido import incorreto do teste --- tests/02-modelo-07-validacao.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/02-modelo-07-validacao.txt b/tests/02-modelo-07-validacao.txt index d3a58c8..3229d18 100644 --- a/tests/02-modelo-07-validacao.txt +++ b/tests/02-modelo-07-validacao.txt @@ -2,24 +2,24 @@ Validação --------- A validação dos arquivos de nota fiscal são controladas pelo módulo validacao. - >>> from processamento import validacao + >>> from pynfe.processamento import validacao A classe Validacao é utilizada para validar os tanto arquivos xml quanto documentos etree. Não há problemas em utilizar list-comprehension com a mesma pois ela implementa um cache simples. - >>> val = validacao.Validacao() + >>> validador = validacao.Validacao() >>> nfe_caminho = 'tests/xml/NFe.xml' >>> nfe_assin_caminho = 'tests/xml/NFe_assinada.xml' >>> nfe_inval_caminho = 'tests/xml/NFe_falhaSchema.xml' - >>> val.validar_xml(nfe_caminho, validacao.XSD_NFE) + >>> validador.validar_xml(nfe_caminho, validacao.XSD_NFE) True - >>> import lxml as etree - >>> val.validar_etree(etree.parse(nfe_caminho), validacao.XSD_NFE) + >>> from lxml import etree + >>> validador.validar_etree(etree.parse(nfe_caminho), validacao.XSD_NFE) True - >>> val.validar_xml(nfe_assin_caminho, XSD_NFE_PROCESSADA) + >>> validador.validar_xml(nfe_assin_caminho, validacao.XSD_NFE_PROCESSADA) True - >>> val.validar_xml(nfe_inval_caminho, XSD_NFE) + >>> validador.validar_xml(nfe_inval_caminho, validacao.XSD_NFE) False Note que o schema utilizado para validação contra o xml é definido por variáveis @@ -28,4 +28,4 @@ globais presentes no módulo. São elas: - XSD_NFE : valida nfe's não certificadas - XSD_NFE_PROCESSADA : valida nfe's certificadas - XSD_PD_CANCELAR_NFE : valida um pedido de cancelamento de nfe -- XSD_PD_INUTILIZAR_NFE : valida um pedido de inutilização de nfe \ No newline at end of file +- XSD_PD_INUTILIZAR_NFE : valida um pedido de inutilização de nfe From cf96e68530dcaf418f423a8389fc64f8f8052c30 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Wed, 20 Jan 2010 23:20:45 -0300 Subject: [PATCH 10/17] retirado glob e corrigido uso do etree. Cache agora funciona. --- pynfe/processamento/validacao.py | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/pynfe/processamento/validacao.py b/pynfe/processamento/validacao.py index 3b9a38d..639a4df 100644 --- a/pynfe/processamento/validacao.py +++ b/pynfe/processamento/validacao.py @@ -1,7 +1,6 @@ #-*- coding:utf-8 -*- from os import path -from glob import glob try: from lxml import etree @@ -24,13 +23,20 @@ except ImportError: except ImportError: raise Exception('Falhou ao importar lxml/ElementTree') -XSD_FOLDER = "data/XSDs/" +XSD_FOLDER = "pynfe/data/XSDs/" XSD_NFE="nfe_v1.10.xsd" XSD_NFE_PROCESSADA="procNFe_v1.10.xsd" XSD_PD_CANCELAR_NFE="procCancNFe_v1.07.xsd" XSD_PD_INUTILIZAR_NFE="procInutNFe_v1.07.xsd" +def get_xsd(xsd_file): + """Retorna o caminho absoluto para um arquivo xsd + Argumentos: + xsd_file - nome do arquivo xsd (utilizar nomes definidos em validacao.py) + """ + return path.abspath(path.join(XSD_FOLDER, xsd_file)) + class Validacao(object): '''Valida documentos xml a partir do xsd informado''' def __init__(self): @@ -45,18 +51,24 @@ class Validacao(object): xml_filepath - caminho para arquivo xml xsd_file - caminho para o arquivo xsd ''' - return self._validar(etree.parse(xml_path), xsd_file) + + with open(xml_path) as file: + xml_doc = etree.parse(file) + return self.validar_etree(xml_doc, xsd_file) - def _validar(self, xml_doc, xsd_file): - xsd_filepath = path.join(XSD_FOLDER, xsd_file) + def validar_etree(self, xml_doc, xsd_file): + '''Valida um documento lxml diretamente + Argumentos: + xml_doc - documento etree + xsd_file - caminho para o arquivo xsd''' + xsd_filepath = get_xsd(xsd_file) try: - xsd_schema = self.MEM_CACHE[xsd_file] + # checa se o schema ja existe no cache + xsd_schema = self.MEM_CACHE[xsd_filepath] except: - xsd_doc = etree.parse(xsd_file) - xsd_schema = etree.XMLSchema(xsd_doc) - return xsd_schema.validate(xml_doc) - - # alias - validar_etree = _validar - \ No newline at end of file + with open(xsd_filepath) as file: # lê xsd e atualiza cache + xsd_doc = etree.parse(file) + xsd_schema = etree.XMLSchema(xsd_doc) + self.MEM_CACHE[xsd_file] = xsd_schema + return xsd_schema.validate(xml_doc) From 59873d50fd53b6805febaf53f1bafc05dc72ac64 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Wed, 20 Jan 2010 23:22:09 -0300 Subject: [PATCH 11/17] atualizacao cosmetica. --- pynfe/processamento/validacao.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pynfe/processamento/validacao.py b/pynfe/processamento/validacao.py index 639a4df..9ef3ff1 100644 --- a/pynfe/processamento/validacao.py +++ b/pynfe/processamento/validacao.py @@ -31,14 +31,15 @@ XSD_PD_CANCELAR_NFE="procCancNFe_v1.07.xsd" XSD_PD_INUTILIZAR_NFE="procInutNFe_v1.07.xsd" def get_xsd(xsd_file): - """Retorna o caminho absoluto para um arquivo xsd + """Retorna o caminho absoluto para um arquivo xsd. Argumentos: xsd_file - nome do arquivo xsd (utilizar nomes definidos em validacao.py) """ return path.abspath(path.join(XSD_FOLDER, xsd_file)) class Validacao(object): - '''Valida documentos xml a partir do xsd informado''' + '''Valida documentos xml a partir do xsd informado.''' + def __init__(self): self.clear_cache() @@ -46,7 +47,7 @@ class Validacao(object): self.MEM_CACHE = {} def validar_xml(self, xml_path, xsd_file): - '''Valida um arquivo xml + '''Valida um arquivo xml. Argumentos: xml_filepath - caminho para arquivo xml xsd_file - caminho para o arquivo xsd @@ -57,10 +58,11 @@ class Validacao(object): return self.validar_etree(xml_doc, xsd_file) def validar_etree(self, xml_doc, xsd_file): - '''Valida um documento lxml diretamente + '''Valida um documento lxml diretamente. Argumentos: xml_doc - documento etree - xsd_file - caminho para o arquivo xsd''' + xsd_file - caminho para o arquivo xsd + ''' xsd_filepath = get_xsd(xsd_file) try: From f8bcf6a9d251131bb51d4ccd515678a9d8ad0f92 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Wed, 20 Jan 2010 23:26:45 -0300 Subject: [PATCH 12/17] correcao no uso do parse --- pynfe/processamento/validacao.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pynfe/processamento/validacao.py b/pynfe/processamento/validacao.py index 9ef3ff1..eedb992 100644 --- a/pynfe/processamento/validacao.py +++ b/pynfe/processamento/validacao.py @@ -52,10 +52,7 @@ class Validacao(object): xml_filepath - caminho para arquivo xml xsd_file - caminho para o arquivo xsd ''' - - with open(xml_path) as file: - xml_doc = etree.parse(file) - return self.validar_etree(xml_doc, xsd_file) + return self.validar_etree(etree.parse(xml_path), xsd_file) def validar_etree(self, xml_doc, xsd_file): '''Valida um documento lxml diretamente. @@ -69,8 +66,8 @@ class Validacao(object): # checa se o schema ja existe no cache xsd_schema = self.MEM_CACHE[xsd_filepath] except: - with open(xsd_filepath) as file: # lê xsd e atualiza cache - xsd_doc = etree.parse(file) - xsd_schema = etree.XMLSchema(xsd_doc) + # lê xsd e atualiza cache + xsd_doc = etree.parse(xsd_filepath) + xsd_schema = etree.XMLSchema(xsd_doc) self.MEM_CACHE[xsd_file] = xsd_schema return xsd_schema.validate(xml_doc) From e981ce299f402106942aca768d2b2315f886a3d4 Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Thu, 21 Jan 2010 00:29:41 -0300 Subject: [PATCH 13/17] cosmetico --- tests/02-modelo-07-validacao.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/02-modelo-07-validacao.txt b/tests/02-modelo-07-validacao.txt index 3229d18..9383782 100644 --- a/tests/02-modelo-07-validacao.txt +++ b/tests/02-modelo-07-validacao.txt @@ -8,13 +8,13 @@ A classe Validacao é utilizada para validar os tanto arquivos xml quanto docume etree. Não há problemas em utilizar list-comprehension com a mesma pois ela implementa um cache simples. + >>> from lxml import etree >>> validador = validacao.Validacao() - >>> nfe_caminho = 'tests/xml/NFe.xml' + >>> nfe_caminho = 'tests/saida/nfe-1.xml' >>> nfe_assin_caminho = 'tests/xml/NFe_assinada.xml' >>> nfe_inval_caminho = 'tests/xml/NFe_falhaSchema.xml' >>> validador.validar_xml(nfe_caminho, validacao.XSD_NFE) - True - >>> from lxml import etree + True >>> validador.validar_etree(etree.parse(nfe_caminho), validacao.XSD_NFE) True >>> validador.validar_xml(nfe_assin_caminho, validacao.XSD_NFE_PROCESSADA) From 36620ffe52799e0fb71aa001b59b28052fbb6eac Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Thu, 21 Jan 2010 01:08:10 -0300 Subject: [PATCH 14/17] =?UTF-8?q?alterada=20assinatura=20para=20permitir?= =?UTF-8?q?=20descobrir=20o=20motivo=20da=20falha=20na=20valida=C3=A7?= =?UTF-8?q?=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pynfe/processamento/validacao.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/pynfe/processamento/validacao.py b/pynfe/processamento/validacao.py index eedb992..0520761 100644 --- a/pynfe/processamento/validacao.py +++ b/pynfe/processamento/validacao.py @@ -46,19 +46,22 @@ class Validacao(object): def clear_cache(self): self.MEM_CACHE = {} - def validar_xml(self, xml_path, xsd_file): + def validar_xml(self, xml_path, xsd_file, guess_error=False): '''Valida um arquivo xml. Argumentos: xml_filepath - caminho para arquivo xml xsd_file - caminho para o arquivo xsd + guess_error - levantar exceção caso documento não valide? ''' - return self.validar_etree(etree.parse(xml_path), xsd_file) + return self.validar_etree(etree.parse(xml_path), xsd_file, + guess_error=guess_error) - def validar_etree(self, xml_doc, xsd_file): + def validar_etree(self, xml_doc, xsd_file, guess_error=False): '''Valida um documento lxml diretamente. Argumentos: xml_doc - documento etree xsd_file - caminho para o arquivo xsd + guess_error - levantar exceção caso documento não valide? ''' xsd_filepath = get_xsd(xsd_file) @@ -70,4 +73,14 @@ class Validacao(object): xsd_doc = etree.parse(xsd_filepath) xsd_schema = etree.XMLSchema(xsd_doc) self.MEM_CACHE[xsd_file] = xsd_schema - return xsd_schema.validate(xml_doc) + return self._validar(xsd_schema, xml_doc, guess_error) + + def _validar(self, xsd_schema, xml_doc, use_assert=False): + """Checa se um documento eh valido, podendo jogar exceção caso não seja. + Argumentos + xsd_schema - documento schema usado na validacao + xml_doc - documento xml a ser validado + use_assert - gerar exceção com o erro caso o documento seja inválido? + """ + return use_assert and xsd_schema.assertValid(xml_doc) \ + or xsd_schema.validate(xml_doc) From 6cc83e560eeb99e18c8b49ae3e53736faa4e3eff Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Thu, 21 Jan 2010 01:33:12 -0300 Subject: [PATCH 15/17] corrigidas assinaturas e docs --- pynfe/processamento/validacao.py | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/pynfe/processamento/validacao.py b/pynfe/processamento/validacao.py index 0520761..e1caef3 100644 --- a/pynfe/processamento/validacao.py +++ b/pynfe/processamento/validacao.py @@ -46,22 +46,21 @@ class Validacao(object): def clear_cache(self): self.MEM_CACHE = {} - def validar_xml(self, xml_path, xsd_file, guess_error=False): + def validar_xml(self, xml_path, xsd_file, use_assert=False): '''Valida um arquivo xml. Argumentos: - xml_filepath - caminho para arquivo xml + xml_path - caminho para arquivo xml xsd_file - caminho para o arquivo xsd - guess_error - levantar exceção caso documento não valide? + use_assert - levantar exceção caso documento não valide? ''' - return self.validar_etree(etree.parse(xml_path), xsd_file, - guess_error=guess_error) + return self.validar_etree(etree.parse(xml_path), xsd_file, use_assert) - def validar_etree(self, xml_doc, xsd_file, guess_error=False): + def validar_etree(self, xml_doc, xsd_file, use_assert=False): '''Valida um documento lxml diretamente. Argumentos: xml_doc - documento etree xsd_file - caminho para o arquivo xsd - guess_error - levantar exceção caso documento não valide? + use_assert - levantar exceção caso documento não valide? ''' xsd_filepath = get_xsd(xsd_file) @@ -73,14 +72,5 @@ class Validacao(object): xsd_doc = etree.parse(xsd_filepath) xsd_schema = etree.XMLSchema(xsd_doc) self.MEM_CACHE[xsd_file] = xsd_schema - return self._validar(xsd_schema, xml_doc, guess_error) - - def _validar(self, xsd_schema, xml_doc, use_assert=False): - """Checa se um documento eh valido, podendo jogar exceção caso não seja. - Argumentos - xsd_schema - documento schema usado na validacao - xml_doc - documento xml a ser validado - use_assert - gerar exceção com o erro caso o documento seja inválido? - """ return use_assert and xsd_schema.assertValid(xml_doc) \ - or xsd_schema.validate(xml_doc) + or xsd_schema.validate(xml_doc) \ No newline at end of file From ceabbbc7d4d0943d67be4b3fd8a38cbd4552e6be Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Thu, 21 Jan 2010 01:42:41 -0300 Subject: [PATCH 16/17] testes agora informa o erro da validacao, caso exista --- tests/02-modelo-07-validacao.txt | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/02-modelo-07-validacao.txt b/tests/02-modelo-07-validacao.txt index 9383782..77e6c6b 100644 --- a/tests/02-modelo-07-validacao.txt +++ b/tests/02-modelo-07-validacao.txt @@ -2,25 +2,28 @@ Validação --------- A validação dos arquivos de nota fiscal são controladas pelo módulo validacao. - >>> from pynfe.processamento import validacao + >>> from pynfe.processamento.validacao import * A classe Validacao é utilizada para validar os tanto arquivos xml quanto documentos etree. Não há problemas em utilizar list-comprehension com a mesma pois ela implementa um cache simples. >>> from lxml import etree - >>> validador = validacao.Validacao() - >>> nfe_caminho = 'tests/saida/nfe-1.xml' - >>> nfe_assin_caminho = 'tests/xml/NFe_assinada.xml' - >>> nfe_inval_caminho = 'tests/xml/NFe_falhaSchema.xml' - >>> validador.validar_xml(nfe_caminho, validacao.XSD_NFE) - True - >>> validador.validar_etree(etree.parse(nfe_caminho), validacao.XSD_NFE) - True - >>> validador.validar_xml(nfe_assin_caminho, validacao.XSD_NFE_PROCESSADA) + >>> validador = Validacao() + >>> + >>> nfe = 'tests/xml/NFe.xml' + >>> nfe_assin = 'tests/xml/NFe_assinada.xml' + >>> nfe_inval = 'tests/xml/NFe_falhaSchema.xml' + >>> + >>> try: validador.validar_xml(nfe, XSD_NFE, True) + ... except Exception, e: print unicode(repr(e)) True - >>> validador.validar_xml(nfe_inval_caminho, validacao.XSD_NFE) + >>> try: validador.validar_xml(nfe_inval, XSD_NFE, False) + ... except Exception, e: print unicode(repr(e)) False + >>> try: validador.validar_xml(nfe_assin, XSD_NFE_PROCESSADA, True) + ... except Exception, e: print unicode(repr(e)) + True Note que o schema utilizado para validação contra o xml é definido por variáveis globais presentes no módulo. São elas: From a8d9678c0936496b6c3db10289e26efa1b411aec Mon Sep 17 00:00:00 2001 From: Italo Maia Date: Tue, 26 Jan 2010 10:53:08 -0300 Subject: [PATCH 17/17] adicionando pasta com xmls de teste --- tests/xml/NFe.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xml/NFe.xml b/tests/xml/NFe.xml index 189d825..c0e2037 100644 --- a/tests/xml/NFe.xml +++ b/tests/xml/NFe.xml @@ -220,4 +220,4 @@ Nota Fiscal de exemplo NF-eletronica.com - \ No newline at end of file +