Browse Source

Trabalhando na serializacao da NF para XML

tags/0.1
Marinho Brandão 16 years ago
parent
commit
5a4b6e7360
  1. 9
      pynfe/__init__.py
  2. 32
      pynfe/entidades/notafiscal.py
  3. 23
      pynfe/processamento/serializacao.py
  4. 26
      pynfe/utils/flags.py
  5. 14
      tests/02-modelo-05-notafiscal.txt
  6. 14
      tests/03-processamento-01-serializacao-xml.txt

9
pynfe/__init__.py

@ -1,3 +1,8 @@
__version__ = '0.1'
def get_version():
return '0.1'
__version__ = get_version()
__author__ = 'Marinho Brandao'
__license__ = 'Lesser Gnu Public License'
__license__ = 'GNU Lesser General Public License (LGPL)'
__url__ = 'http://github.com/marinho/PyNFe'

32
pynfe/entidades/notafiscal.py

@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
from base import Entidade
from pynfe import get_version
from pynfe.utils.flags import NF_STATUS, NF_TIPOS_DOCUMENTO, NF_TIPOS_IMPRESSAO_DANFE,\
NF_FORMAS_PAGAMENTO, NF_FORMAS_EMISSAO, NF_FINALIDADES_EMISSAO,\
NF_REFERENCIADA_TIPOS, NF_PRODUTOS_ESPECIFICOS, ICMS_TIPOS_TRIBUTACAO,\
ICMS_ORIGENS, ICMS_MODALIDADES, IPI_TIPOS_TRIBUTACAO, IPI_TIPOS_CALCULO,\
PIS_TIPOS_TRIBUTACAO, PIS_TIPOS_CALCULO, COFINS_TIPOS_TRIBUTACAO,\
COFINS_TIPOS_CALCULO, MODALIDADES_FRETE, ORIGENS_PROCESSO, CODIGO_BRASIL
COFINS_TIPOS_CALCULO, MODALIDADES_FRETE, ORIGENS_PROCESSO, CODIGO_BRASIL,\
NF_PROCESSOS_EMISSAO, CODIGOS_ESTADOS
from pynfe.utils import so_numeros, memoize
from decimal import Decimal
@ -30,14 +34,20 @@ class NotaFiscal(Entidade):
# - Tipo do Documento (obrigatorio - seleciona de lista) - NF_TIPOS_DOCUMENTO
tipo_documento = int()
# - Processo de emissão da NF-e (obrigatorio - seleciona de lista) - NF_PROCESSOS_EMISSAO
processo_emissao = 0
# - Versao do processo de emissão da NF-e
versao_processo_emissao = get_version()
# - Tipo impressao DANFE (obrigatorio - seleciona de lista) - NF_TIPOS_IMPRESSAO_DANFE
tipo_impressao_danfe = str()
tipo_impressao_danfe = int()
# - Data de saida/entrada
data_saida_entrada = None
# - Forma de pagamento (obrigatorio - seleciona de lista) - NF_FORMAS_PAGAMENTO
forma_pagamento = str()
forma_pagamento = int()
# - Forma de emissao (obrigatorio - seleciona de lista) - NF_FORMAS_EMISSAO
forma_emissao = str()
@ -321,6 +331,22 @@ class NotaFiscal(Entidade):
u"""Adiciona uma instancia de Processo Referenciado"""
self.processos_referenciados.append(NotaFiscalProcessoReferenciado(**kwargs))
@property
@memoize
def identificador_unico(self):
# Monta 'Id' da raiz
# Ex.: NFe35080599999090910270550010000000015180051273
return "NFe%(uf)s%(ano)s%(mes)s%(cnpj)s%(mod)s%(serie)s%(nNF)s%(cNF)s%(cDV)s"%{
'uf': CODIGOS_ESTADOS[self.uf],
'ano': self.data_emissao.strftime('%y'),
'mes': self.data_emissao.strftime('%m'),
'cnpj': so_numeros(self.emitente.cnpj),
'mod': self.modelo,
'serie': str(self.serie).zfill(3),
'nNF': str(self.numero_nf).zfill(9),
'cNF': '518005127'.zfill(9), # FIXME
'cDV': '3', # FIXME
}
class NotaFiscalReferenciada(Entidade):
# - Tipo (seleciona de lista) - NF_REFERENCIADA_TIPOS

23
pynfe/processamento/serializacao.py

@ -38,6 +38,8 @@ class Serializacao(object):
Nao deve ser instanciada diretamente!"""
_fonte_dados = None
_ambiente = 1
_nome_aplicacao = 'PyNFe'
def __new__(cls, *args, **kwargs):
if cls == Serializacao:
@ -45,8 +47,9 @@ class Serializacao(object):
else:
return super(Serializacao, cls).__new__(cls, *args, **kwargs)
def __init__(self, fonte_dados):
def __init__(self, fonte_dados, homologacao=False):
self._fonte_dados = fonte_dados
self._ambiente = homologacao and 2 or 1
def exportar(self, destino, **kwargs):
"""Gera o(s) arquivo(s) de exportacao a partir da Nofa Fiscal eletronica
@ -190,17 +193,29 @@ class SerializacaoXML(Serializacao):
return ''
def _serializar_notas_fiscal(self, nota_fiscal, tag_raiz='infNFe', retorna_string=True):
raiz = etree.Element(tag_raiz)
raiz = etree.Element(tag_raiz, versao="1.10")
# Dados da Nota Fiscal
ide = etree.SubElement(raiz, 'ide')
etree.SubElement(ide, 'cUF').text = CODIGOS_ESTADOS[nota_fiscal.uf]
etree.SubElement(ide, 'cNF').text = '' # FIXME
etree.SubElement(ide, 'natOp').text = nota_fiscal.natureza_operacao
etree.SubElement(ide, 'indPag').text = str(nota_fiscal.forma_pagamento)
etree.SubElement(ide, 'mod').text = str(nota_fiscal.modelo)
etree.SubElement(ide, 'serie').text = nota_fiscal.serie
etree.SubElement(ide, 'nNF').text = nota_fiscal.numero_nf
etree.SubElement(ide, 'dEmi').text = nota_fiscal.data_emissao.strftime('%Y-%m-%d')
etree.SubElement(ide, 'dSaiEnt').text = nota_fiscal.data_saida_entrada.strftime('%Y-%m-%d')
etree.SubElement(ide, 'tpNF').text = str(nota_fiscal.tipo_documento)
etree.SubElement(ide, 'cMunFG').text = nota_fiscal.municipio
etree.SubElement(ide, 'tpImp').text = str(nota_fiscal.tipo_impressao_danfe)
etree.SubElement(ide, 'tpEmis').text = str(nota_fiscal.forma_emissao)
etree.SubElement(ide, 'cDV').text = '3' # FIXME
etree.SubElement(ide, 'tpAmb').text = str(self._ambiente)
etree.SubElement(ide, 'finNFe').text = str(nota_fiscal.finalidade_emissao)
etree.SubElement(ide, 'procEmi').text = str(nota_fiscal.processo_emissao)
etree.SubElement(ide, 'verProc').text = '%s %s'%(self._nome_aplicacao,
nota_fiscal.versao_processo_emissao)
# Emitente
raiz.append(self._serializar_emitente(nota_fiscal.emitente, retorna_string=False))
@ -208,6 +223,10 @@ class SerializacaoXML(Serializacao):
# Destinatário
raiz.append(self._serializar_cliente(nota_fiscal.cliente, retorna_string=False))
# 'Id' da tag raiz
# Ex.: NFe35080599999090910270550010000000015180051273
raiz.attrib['Id'] = nota_fiscal.identificador_unico
if retorna_string:
return etree.tostring(raiz, pretty_print=True)
else:

26
pynfe/utils/flags.py

@ -47,9 +47,16 @@ NF_TIPOS_DOCUMENTO = (
(1, 'Saida'),
)
NF_PROCESSOS_EMISSAO = (
(0, u'Emissão de NF-e com aplicativo do contribuinte'),
(1, u'Emissão de NF-e avulsa pelo Fisco'),
(2, u'Emissão de NF-e avulsa, pelo contribuinte com seu certificado digital, através do site do Fisco'),
(3, u'Emissão NF-e pelo contribuinte com aplicativo fornecido pelo Fisco'),
)
NF_TIPOS_IMPRESSAO_DANFE = (
'Retrato',
'Paisagem',
(1, 'Retrato'),
(2, 'Paisagem'),
)
NF_FORMAS_PAGAMENTO = (
@ -59,11 +66,11 @@ NF_FORMAS_PAGAMENTO = (
)
NF_FORMAS_EMISSAO = (
'Normal',
'Contingencia',
'Contingencia com SCAN',
'Contingencia via DPEC',
'Contingencia FS-DA',
(1, 'Normal'),
(2, 'Contingencia'),
(3, 'Contingencia com SCAN'),
(4, 'Contingencia via DPEC'),
(5, 'Contingencia FS-DA'),
)
NF_FINALIDADES_EMISSAO = (
@ -84,6 +91,11 @@ NF_PRODUTOS_ESPECIFICOS = (
'Combustivel',
)
NF_AMBIENTES = (
(1, 'Producao'),
(2, 'Homologacao'),
)
IPI_TIPOS_TRIBUTACAO = (
('00', 'IPI 00 - Entrada com recuperacao de credito'),
('01', 'IPI 01 - Entrada tributada com aliquota zero'),

14
tests/02-modelo-05-notafiscal.txt

@ -58,6 +58,20 @@ Nenhum dos campos deve permitir acentos e/ou cedilhas.
>>> hasattr(NotaFiscal, 'tipo_documento')
True
- Processo de emissão da NF-e
- 0 - emissão de NF-e com aplicativo do contribuinte;
- 1 - emissão de NF-e avulsa pelo Fisco;
- 2 - emissão de NF-e avulsa, pelo contribuinte com seu certificado digital, através do site do Fisco;
- 3 - emissão NF-e pelo contribuinte com aplicativo fornecido pelo Fisco.
>>> hasattr(NotaFiscal, 'processo_emissao')
True
- Versao do Processo de emissao da NF-e
>>> hasattr(NotaFiscal, 'versao_processo_emissao')
True
- Tipo impressao DANFE (obrigatorio - seleciona de lista)
- Retrato
- Paisagem

14
tests/03-processamento-01-serializacao-xml.txt

@ -69,6 +69,11 @@ Instancia a NF
... data_emissao=datetime.date.today(),
... data_saida_entrada=datetime.date.today(),
... natureza_operacao='Venda a vista',
... forma_pagamento=0,
... tipo_impressao_danfe=1, # Retrato
... forma_emissao=1, # Normal
... finalidade_emissao=1,
... municipio='3550308',
... )
>>> _fonte_dados.contar_objetos()
@ -82,7 +87,7 @@ Gerar arquivos XML
>>> CAMINHO_SAIDA = os.path.join(CUR_DIR, 'tests', 'saida')
>>> from pynfe.processamento.serializacao import SerializacaoXML
>>> serializador = SerializacaoXML(_fonte_dados)
>>> serializador = SerializacaoXML(_fonte_dados, homologacao=True)
Serializando por partes
@ -143,8 +148,11 @@ Serializando por partes
- Gera os arquivos XML a partir dos dados das instancias da NF-e
>>> print nota_fiscal.identificador_unico
NFe52100112345678000190550010000000015180051273
>>> print serializador._serializar_notas_fiscal(nota_fiscal)
<infNFe Id="NFe35080599999090910270550010000000015180051273" versao="1.10">
<infNFe versao="1.10" Id="NFe52100112345678000190550010000000015180051273">
<ide>
<cUF>52</cUF>
<cNF>518005127</cNF>
@ -163,7 +171,7 @@ Serializando por partes
<tpAmb>2</tpAmb>
<finNFe>1</finNFe>
<procEmi>0</procEmi>
<verProc>NF-eletronica.com</verProc>
<verProc>PyNFe 0.1</verProc>
</ide>
<emit>
<CNPJ>12345678000190</CNPJ>

Loading…
Cancel
Save