try:
set
except:
from sets import Set as setA biblioteca deve fornecer uma colecao de utilitarios para consumir o webservice da NF-e.
A separacao entre os componentes da biblioteca deve seguir o seguinte modelo:
MODELO DE ENTIDADES
| ------------ -------------- |
| | Entidade |-------<>| FonteDados | |
| ------------ -------------- |
| A |
| | |
| ----especializacao-------------------------- |
| | | | | |
| ------------ ----------- ----------- ------------------ |
| | Emitente | | Produto | | Cliente | | Transportadora | |
| ------------ ----------- ----------- ------------------ |
| *| *| *| *| |
| ------------------------------associacao---- |
| | |
| V* |
| --------------- ---------------- |
| | Nota Fiscal |------<>| Lote de NF-e | |
| --------------- 1 * ---------------- |
| |
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() | |
| ---------------------- |
Os pacotes da biblioteca sao:
-
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'])
-
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'])
-
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']) 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
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)
... except Exception, e:
... 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:
... try:
... # Python 2.5
... import xml.etree.cElementTree as etree
... except ImportError:
... try:
... # Python 2.5
... import xml.etree.ElementTree as etree
... except ImportError:
... try:
... # normal cElementTree install
... import cElementTree as etree
... except ImportError:
... try:
... # normal ElementTree install
... import elementtree.ElementTree as etree
... except ImportError:
... print("A importacao do lxml falhou")
Para executar estes testes é preciso instalar a soaplib, para servir WSDL via SOAP, num servidor falso (mock).
>>> import soaplib
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
Alem disso, deve gerar PDFs da DANFE, utilizando a engine Geraldo Reports.
>>> import geraldo
>>> import PIL
Temos um codigo para geracao de codigo de barras Code128...
>>> from pynfe.utils import bar_code_128
Mas essa geracao podera ser feita diretamente pelo Geraldo, usando uma biblioteca do ReportLab que existe para isso
>>> from reportlab.graphics.barcode import code128