Browse Source

Continuando trabalho da serializacao para XML

tags/0.1
Marinho Brandão 16 years ago
parent
commit
069c561ec7
  1. 2
      pynfe/entidades/notafiscal.py
  2. 53
      pynfe/processamento/serializacao.py
  3. 36
      pynfe/utils/__init__.py
  4. 30
      pynfe/utils/flags.py
  5. 230
      tests/03-processamento-01-serializacao-xml.txt

2
pynfe/entidades/notafiscal.py

@ -45,7 +45,7 @@ class NotaFiscal(Entidade):
# - Finalidade de emissao (obrigatorio - seleciona de lista) - NF_FINALIDADES_EMISSAO
finalidade_emissao = int()
# - UF
# - UF - converter para codigos em CODIGOS_ESTADOS
uf = str()
# - Municipio de ocorrencia

53
pynfe/processamento/serializacao.py

@ -28,6 +28,7 @@ except ImportError:
from pynfe.entidades import Emitente, Cliente, Produto, Transportadora, NotaFiscal
from pynfe.excecoes import NenhumObjetoEncontrado, MuitosObjetosEncontrados
from pynfe.utils import so_numeros, obter_municipio_por_codigo, obter_pais_por_codigo
from pynfe.utils.flags import CODIGOS_ESTADOS
class Serializacao(object):
"""Classe abstrata responsavel por fornecer as funcionalidades basicas para
@ -103,7 +104,7 @@ class SerializacaoXML(Serializacao):
return lista[0]
def _serializar_emitente(self, emitente, tag_raiz='emit'):
def _serializar_emitente(self, emitente, tag_raiz='emit', retorna_string=True):
raiz = etree.Element(tag_raiz)
# Dados do emitente
@ -128,9 +129,12 @@ class SerializacaoXML(Serializacao):
etree.SubElement(endereco, 'xPais').text = obter_pais_por_codigo(emitente.endereco_pais)
etree.SubElement(endereco, 'fone').text = emitente.endereco_telefone
return etree.tostring(raiz, pretty_print=True)
if retorna_string:
return etree.tostring(raiz, pretty_print=True)
else:
return raiz
def _serializar_cliente(self, cliente, tag_raiz='dest'):
def _serializar_cliente(self, cliente, tag_raiz='dest', retorna_string=True):
raiz = etree.Element(tag_raiz)
# Dados do cliente
@ -154,9 +158,12 @@ class SerializacaoXML(Serializacao):
etree.SubElement(endereco, 'xPais').text = obter_pais_por_codigo(cliente.endereco_pais)
etree.SubElement(endereco, 'fone').text = cliente.endereco_telefone
return etree.tostring(raiz, pretty_print=True)
if retorna_string:
return etree.tostring(raiz, pretty_print=True)
else:
return raiz
def _serializar_transportadora(self, transportadora, tag_raiz='transporta'):
def _serializar_transportadora(self, transportadora, tag_raiz='transporta', retorna_string=True):
raiz = etree.Element(tag_raiz)
# Dados da transportadora
@ -172,13 +179,37 @@ class SerializacaoXML(Serializacao):
)
etree.SubElement(raiz, 'UF').text = transportadora.endereco_uf
return etree.tostring(raiz, pretty_print=True)
if retorna_string:
return etree.tostring(raiz, pretty_print=True)
else:
return raiz
def _serializar_produto(self, produto, tag_raiz='prod'):
# TODO
def _serializar_produto(self, produto, tag_raiz='prod', retorna_string=True):
# Provavelmente nao vai ser feito desta forma, e sim como serializacao do produto
# na NF (NotaFiscalProduto)
return ''
def _serializar_notas_fiscal(self, notas_fiscal, tag_raiz='infNFe'):
# TODO
return ''
def _serializar_notas_fiscal(self, nota_fiscal, tag_raiz='infNFe', retorna_string=True):
raiz = etree.Element(tag_raiz)
# Dados da Nota Fiscal
ide = etree.SubElement(raiz, 'ide')
etree.SubElement(ide, 'cUF').text = CODIGOS_ESTADOS[nota_fiscal.uf]
etree.SubElement(ide, 'natOp').text = nota_fiscal.natureza_operacao
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')
# Emitente
raiz.append(self._serializar_emitente(nota_fiscal.emitente, retorna_string=False))
# Destinatário
raiz.append(self._serializar_cliente(nota_fiscal.cliente, retorna_string=False))
if retorna_string:
return etree.tostring(raiz, pretty_print=True)
else:
return raiz

36
pynfe/utils/__init__.py

@ -15,43 +15,17 @@ def obter_pais_por_codigo(codigo):
if codigo == '1058':
return 'Brasil'
ARQUIVOS_ESTADOS = {
'RO': 'MunIBGE-UF11.txt',
'AC': 'MunIBGE-UF12.txt',
'AM': 'MunIBGE-UF13.txt',
'RR': 'MunIBGE-UF14.txt',
'PA': 'MunIBGE-UF15.txt',
'AP': 'MunIBGE-UF16.txt',
'TO': 'MunIBGE-UF17.txt',
'MA': 'MunIBGE-UF21.txt',
'PI': 'MunIBGE-UF22.txt',
'CE': 'MunIBGE-UF23.txt',
'RN': 'MunIBGE-UF24.txt',
'PB': 'MunIBGE-UF25.txt',
'PE': 'MunIBGE-UF26.txt',
'AL': 'MunIBGE-UF27.txt',
'SE': 'MunIBGE-UF28.txt',
'BA': 'MunIBGE-UF29.txt',
'MG': 'MunIBGE-UF31.txt',
'ES': 'MunIBGE-UF32.txt',
'RJ': 'MunIBGE-UF33.txt',
'SP': 'MunIBGE-UF35.txt',
'PR': 'MunIBGE-UF41.txt',
'SC': 'MunIBGE-UF42.txt',
'RS': 'MunIBGE-UF43.txt',
'MS': 'MunIBGE-UF50.txt',
'MT': 'MunIBGE-UF51.txt',
'GO': 'MunIBGE-UF52.txt',
'DF': 'MunIBGE-UF53.txt',
}
CAMINHO_DATA = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data')
CAMINHO_MUNICIPIOS = os.path.join(CAMINHO_DATA, 'MunIBGE')
@memoize
def carregar_arquivo_municipios(uf):
caminho_arquivo = os.path.join(CAMINHO_MUNICIPIOS, ARQUIVOS_ESTADOS[uf.upper()])
caminho_arquivo = os.path.join(
CAMINHO_MUNICIPIOS,
'MunIBGE-UF%s.txt'%flags.CODIGOS_ESTADOS[uf.upper()],
)
# Carrega o conteudo do arquivo
fp = file(caminho_arquivo)
linhas = list(fp.readlines())
fp.close()

30
pynfe/utils/flags.py

@ -149,4 +149,34 @@ ORIGENS_PROCESSO = (
CODIGO_BRASIL = '1058'
CODIGOS_ESTADOS = {
'RO': '11',
'AC': '12',
'AM': '13',
'RR': '14',
'PA': '15',
'AP': '16',
'TO': '17',
'MA': '21',
'PI': '22',
'CE': '23',
'RN': '24',
'PB': '25',
'PE': '26',
'AL': '27',
'SE': '28',
'BA': '29',
'MG': '31',
'ES': '32',
'RJ': '33',
'SP': '35',
'PR': '41',
'SC': '42',
'RS': '43',
'MS': '50',
'MT': '51',
'GO': '52',
'DF': '53',
}

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

@ -61,11 +61,14 @@ Instancia a NF
>>> nota_fiscal = NotaFiscal(
... emitente=emitente,
... transporte_transportadora=transportadora,
... cliente=cliente,
... uf='GO',
... modelo=55,
... serie='1',
... numero_nf='1',
... data_emissao=datetime.date.today(),
... natureza_operacao='Venda no Varejo',
... data_saida_entrada=datetime.date.today(),
... natureza_operacao='Venda a vista',
... )
>>> _fonte_dados.contar_objetos()
@ -139,6 +142,231 @@ Serializando por partes
<BLANKLINE>
- Gera os arquivos XML a partir dos dados das instancias da NF-e
>>> print serializador._serializar_notas_fiscal(nota_fiscal)
<infNFe Id="NFe35080599999090910270550010000000015180051273" versao="1.10">
<ide>
<cUF>52</cUF>
<cNF>518005127</cNF>
<natOp>Venda a vista</natOp>
<indPag>0</indPag>
<mod>55</mod>
<serie>1</serie>
<nNF>1</nNF>
<dEmi>2010-01-13</dEmi>
<dSaiEnt>2010-01-13</dSaiEnt>
<tpNF>0</tpNF>
<cMunFG>3550308</cMunFG>
<tpImp>1</tpImp>
<tpEmis>1</tpEmis>
<cDV>3</cDV>
<tpAmb>2</tpAmb>
<finNFe>1</finNFe>
<procEmi>0</procEmi>
<verProc>NF-eletronica.com</verProc>
</ide>
<emit>
<CNPJ>12345678000190</CNPJ>
<xNome>Tarsila Calcados Ltda.</xNome>
<xFant>Tarsila Calcados Ltda.</xFant>
<IE>123456789012</IE>
<enderEmit>
<xLgr>Rua 10</xLgr>
<nro>15</nro>
<xCpl>qd 17, lt 10</xCpl>
<xBairro>Setor Oeste</xBairro>
<cMun>5208806</cMun>
<xMun>Goianira</xMun>
<UF>GO</UF>
<CEP>75370000</CEP>
<cPais>1058</cPais>
<xPais>Brasil</xPais>
<fone>6242421212</fone>
</enderEmit>
</emit>
<dest>
<CPF>12345678901</CPF>
<xNome>Jose Felipe da Silva</xNome>
<IE>9876543210</IE>
<enderDest>
<xLgr>AV DAS ROSAS</xLgr>
<nro>1777</nro>
<xCpl>10 ANDAR</xCpl>
<xBairro>PARQUE FONTES</xBairro>
<cMun>3304557</cMun>
<xMun>Rio de Janeiro</xMun>
<UF>RJ</UF>
<CEP>23950000</CEP>
<cPais>1058</cPais>
<xPais>Brasil</xPais>
<fone>2132011234</fone>
</enderDest>
</dest>
<retirada>
<CNPJ>99171171000194</CNPJ>
<xLgr>AV PAULISTA</xLgr>
<nro>12345</nro>
<xCpl>TERREO</xCpl>
<xBairro>CERQUEIRA CESAR</xBairro>
<cMun>3550308</cMun>
<xMun>SAO PAULO</xMun>
<UF>SP</UF>
</retirada>
<entrega>
<CNPJ>99299299000194</CNPJ>
<xLgr>AV FARIA LIMA</xLgr>
<nro>1500</nro>
<xCpl>15 ANDAR</xCpl>
<xBairro>PINHEIROS</xBairro>
<cMun>3550308</cMun>
<xMun>SAO PAULO</xMun>
<UF>SP</UF>
</entrega>
<det nItem="1">
<prod>
<cProd>00001</cProd>
<cEAN />
<xProd>Agua Mineral</xProd>
<CFOP>5101</CFOP>
<uCom>dz</uCom>
<qCom>1000000.0000</qCom>
<vUnCom>1</vUnCom>
<vProd>10000000.00</vProd>
<cEANTrib />
<uTrib>und</uTrib>
<qTrib>12000000.0000</qTrib>
<vUnTrib>1</vUnTrib>
</prod>
<imposto>
<ICMS>
<ICMS00>
<orig>0</orig>
<CST>00</CST>
<modBC>0</modBC>
<vBC>10000000.00</vBC>
<pICMS>18.00</pICMS>
<vICMS>1800000.00</vICMS>
</ICMS00>
</ICMS>
<PIS>
<PISAliq>
<CST>01</CST>
<vBC>10000000.00</vBC>
<pPIS>0.65</pPIS>
<vPIS>65000</vPIS>
</PISAliq>
</PIS>
<COFINS>
<COFINSAliq>
<CST>01</CST>
<vBC>10000000.00</vBC>
<pCOFINS>2.00</pCOFINS>
<vCOFINS>200000.00</vCOFINS>
</COFINSAliq>
</COFINS>
</imposto>
</det>
<det nItem="2">
<prod>
<cProd>00002</cProd>
<cEAN />
<xProd>Agua Mineral</xProd>
<CFOP>5101</CFOP>
<uCom>pack</uCom>
<qCom>5000000.0000</qCom>
<vUnCom>2</vUnCom>
<vProd>10000000.00</vProd>
<cEANTrib />
<uTrib>und</uTrib>
<qTrib>3000000.0000</qTrib>
<vUnTrib>0.3333</vUnTrib>
</prod>
<imposto>
<ICMS>
<ICMS00>
<orig>0</orig>
<CST>00</CST>
<modBC>0</modBC>
<vBC>10000000.00</vBC>
<pICMS>18.00</pICMS>
<vICMS>1800000.00</vICMS>
</ICMS00>
</ICMS>
<PIS>
<PISAliq>
<CST>01</CST>
<vBC>10000000.00</vBC>
<pPIS>0.65</pPIS>
<vPIS>65000</vPIS>
</PISAliq>
</PIS>
<COFINS>
<COFINSAliq>
<CST>01</CST>
<vBC>10000000.00</vBC>
<pCOFINS>2.00</pCOFINS>
<vCOFINS>200000.00</vCOFINS>
</COFINSAliq>
</COFINS>
</imposto>
</det>
<total>
<ICMSTot>
<vBC>20000000.00</vBC>
<vICMS>18.00</vICMS>
<vBCST>0</vBCST>
<vST>0</vST>
<vProd>20000000.00</vProd>
<vFrete>0</vFrete>
<vSeg>0</vSeg>
<vDesc>0</vDesc>
<vII>0</vII>
<vIPI>0</vIPI>
<vPIS>130000.00</vPIS>
<vCOFINS>400000.00</vCOFINS>
<vOutro>0</vOutro>
<vNF>20000000.00</vNF>
</ICMSTot>
</total>
<transp>
<modFrete>0</modFrete>
<transporta>
<CNPJ>123123123000112</CNPJ>
<xNome>WS Cargas S/A</xNome>
<IE>171999999119</IE>
<xEnder>Rua Central 100 - Fundos - Distrito Industrial</xEnder>
<cMun>3304557</cMun>
<xMun>Rio de Janeiro</xMun>
<UF>RJ</UF>
</transporta>
<veicTransp>
<placa>BXI1717</placa>
<UF>SP</UF>
<RNTC>123456789</RNTC>
</veicTransp>
<reboque>
<placa>BXI1818</placa>
<UF>SP</UF>
<RNTC>123456789</RNTC>
</reboque>
<vol>
<qVol>10000</qVol>
<esp>CAIXA</esp>
<marca>LINDOYA</marca>
<nVol>500</nVol>
<pesoL>1000000000.000</pesoL>
<pesoB>1200000000.000</pesoB>
<lacres>
<nLacre>XYZ10231486</nLacre>
</lacres>
</vol>
</transp>
<infAdic>
<infAdFisco>Nota Fiscal de exemplo NF-eletronica.com</infAdFisco>
</infAdic>
</infNFe>
<BLANKLINE>
- Quando gerados me lote, apenas o primeiro arquivo deve ter o cabecalho
padrao do XML 1.0
- <?xml version="1.0" encoding="UTF-8"?>

Loading…
Cancel
Save