From c1ea862475e555a970ec4b6ab43c23620e6f5a3d Mon Sep 17 00:00:00 2001 From: Danimar Ribeiro Date: Fri, 3 Jul 2015 16:03:57 -0300 Subject: [PATCH] =?UTF-8?q?Parte=20de=20c=C3=B3digo=20do=20danfe,=20corre?= =?UTF-8?q?=C3=A7=C3=A3o=20na=20gera=C3=A7=C3=A3o=20do=20xml=20para=20perm?= =?UTF-8?q?itir=20unicode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pytrustnfe/pdf/Danfe.py | 49 +++++++++++++++----- pytrustnfe/test/test_envio_nfe.py | 98 +++++++++++++++++++++++++++++++++++++++ pytrustnfe/xml/DynamicXml.py | 66 +++++++++++++------------- 3 files changed, 171 insertions(+), 42 deletions(-) create mode 100644 pytrustnfe/test/test_envio_nfe.py diff --git a/pytrustnfe/pdf/Danfe.py b/pytrustnfe/pdf/Danfe.py index c31a95d..42bd543 100644 --- a/pytrustnfe/pdf/Danfe.py +++ b/pytrustnfe/pdf/Danfe.py @@ -10,6 +10,8 @@ from reportlab.pdfgen.canvas import Canvas from reportlab.lib.pagesizes import A4 from reportlab.platypus.doctemplate import SimpleDocTemplate from reportlab.lib import colors +from reportlab.platypus.paragraph import Paragraph +from reportlab.lib.styles import ParagraphStyle inch = 28.34 @@ -23,14 +25,7 @@ class Danfe(object): 'ObjetoNFe deve ser do tipo DynamicXml' self.objeto = objetoNFe - def gerar(self): - doc = SimpleDocTemplate( - '/home/danimar/projetos/pdfs/danfe.pdf', - pagesize=A4, leftMargin=0.5 * inch, rightMargin=0.5 * inch, - topMargin=0.5 * inch, bottomMargin=0.5 * inch) - - elementos = [] - + def _header(self): data = [ ['Recebemos de verdesaine industria e comércio os produtos constantes na nota fiscal abaixo ', '', 'NF-e\nNº 000.000.001\nSérie 001'], @@ -41,13 +36,45 @@ class Danfe(object): estilo = [('SPAN', (0, 0), (1, 0)), ('SPAN', (2, 0), (2, 1)), - ('FONTSIZE', (0, 0), (1, 1), 8.0), + ('FONTSIZE', (0, 0), (1, 1), 7.0), ('VALIGN', (0, 0), (1, 1), 'TOP'), ('ALIGN', (2, 0), (2, 1), 'CENTER'), - ('GRID', (0, 0), (3, 1), 1, colors.black)] + ('TOPPADING', (0, 0), (1, 1), 6), + ('GRID', (0, 0), (3, 1), 0.5, colors.black)] colunas = [4 * inch, 12 * inch, 4 * inch] + linhas = [20,30] + table = Table(data, style=estilo, colWidths=colunas, rowHeights=linhas) + return table + + def _field(self, label, value): + estilo = ParagraphStyle('default') + return Paragraph('' + label + '' + '
' + value, estilo) + + def _segundo_cabecalho(self): + data = [ + [self._field('Natureza da operação', 'Venda de produção do estabelecimento'), '', + self._field('Protocolo de autorização de uso', '12345678956665487')], + [self._field('Inscrição estadual', '156466487897'), + self._field('Inscrição estadual substituto tributário', '1456465456'), + self._field('CNPJ', '87.224.633/0001-61'), ] + ] + + estilo = [('SPAN', (0, 0), (1, 0)), + ('FONTSIZE', (0, 0), (1, 1), 7.0), + ('GRID', (0, 0), (2, 1), 0.5, colors.black)] + colunas = [6 * inch, 7 * inch, 7 * inch] table = Table(data, style=estilo, colWidths=colunas) + return table + + def gerar(self): + doc = SimpleDocTemplate( + '/home/danimar/projetos/pdfs/danfe.pdf', + pagesize=A4, leftMargin=0.5 * inch, rightMargin=0.5 * inch, + topMargin=0.5 * inch, bottomMargin=0.5 * inch) - elementos.append(table) + elementos = [] + + elementos.append(self._header()) + elementos.append(self._segundo_cabecalho()) doc.build(elementos) diff --git a/pytrustnfe/test/test_envio_nfe.py b/pytrustnfe/test/test_envio_nfe.py new file mode 100644 index 0000000..acce9fe --- /dev/null +++ b/pytrustnfe/test/test_envio_nfe.py @@ -0,0 +1,98 @@ +# coding=utf-8 + +''' +Created on 01/07/2015 + +@author: danimar +''' +import unittest +from pytrustnfe.xml.DynamicXml import DynamicXml + + +class test_envio(unittest.TestCase): + + def test_envio_nfe(self): + t = DynamicXml('enviNFe') + t(versao="3.10") + t.idLote = "1" + t.indSinc = "1" + t.NFe.infNFe(versao="3.10", Id="NFe123") + t.NFe.infNFe.ide.cUF = '43' + t.NFe.infNFe.ide.cNF = '12345678' + t.NFe.infNFe.ide.natOp = u'Venda de produção' + t.NFe.infNFe.ide.indPag = '1' + t.NFe.infNFe.ide.mod = '55' + t.NFe.infNFe.ide.serie = '49' + t.NFe.infNFe.ide.nNF = '9' + t.NFe.infNFe.ide.dhEmi = '2015-06-30T15:18:05-03:00' + t.NFe.infNFe.ide.dhSaiEnt = '2015-06-30T15:18:05-03:00' + t.NFe.infNFe.ide.tpNF = '1' + t.NFe.infNFe.ide.idDest = '2' + t.NFe.infNFe.ide.cMunFG = '4321667' + t.NFe.infNFe.ide.tpImp = '1' + t.NFe.infNFe.ide.tpEmis = '1' + t.NFe.infNFe.ide.cDV = '3' + t.NFe.infNFe.ide.tpAmb = '2' + t.NFe.infNFe.ide.finNFe = '1' + t.NFe.infNFe.ide.indFinal = '0' + t.NFe.infNFe.ide.indPres = '0' + t.NFe.infNFe.ide.procEmi = '0' + t.NFe.infNFe.ide.verProc = 'Odoo Brasil 8.0' + + # Emitente + t.NFe.infNFe.emit.CNPJ = '02261542000143' + t.NFe.infNFe.emit.xNome = 'Trust-Code' + t.NFe.infNFe.emit.xFant = 'Trust-Code' + t.NFe.infNFe.emit.enderEmit.xLgr = 'Rua severiano rodrigues' + t.NFe.infNFe.emit.enderEmit.nro = '1092' + t.NFe.infNFe.emit.enderEmit.xBairro = 'Santa Rita' + t.NFe.infNFe.emit.enderEmit.cMun = '4321667' + t.NFe.infNFe.emit.enderEmit.xMun = 'Tres Cachoeiras' + t.NFe.infNFe.emit.enderEmit.UF = 'RS' + t.NFe.infNFe.emit.enderEmit.CEP = '95099190' + t.NFe.infNFe.emit.enderEmit.cPais = '1058' + t.NFe.infNFe.emit.enderEmit.xPais = 'Brasil' + t.NFe.infNFe.emit.enderEmit.Fone = '15551238069' + t.NFe.infNFe.emit.IE = '3220014803' + t.NFe.infNFe.emit.CRT = '3' + + # Destinatario + t.NFe.infNFe.dest.CNPJ = '77311846000177' + t.NFe.infNFe.dest.xNome = 'Akretion' + t.NFe.infNFe.dest.enderEmit.xLgr = 'Rua severiano rodrigues' + t.NFe.infNFe.dest.enderEmit.nro = '47' + t.NFe.infNFe.dest.enderEmit.xBairro = 'Santa Rita' + t.NFe.infNFe.dest.enderEmit.cMun = '3304557' + t.NFe.infNFe.dest.enderEmit.xMun = 'Rio de Janeiro' + t.NFe.infNFe.dest.enderEmit.UF = 'RJ' + t.NFe.infNFe.dest.enderEmit.CEP = '20081000' + t.NFe.infNFe.dest.enderEmit.cPais = '1058' + t.NFe.infNFe.dest.enderEmit.xPais = 'Brasil' + t.NFe.infNFe.dest.enderEmit.Fone = '2125162954' + t.NFe.infNFe.dest.indIEDest = '9' + t.NFe.infNFe.dest.email = 'danimar@trustcode.com.br' + + t.NFe.infNFe.det[0](nItem="1") + t.NFe.infNFe.det[0].prod.cProd = 'A6679' + t.NFe.infNFe.det[0].prod.cEAN = '1234567890' + t.NFe.infNFe.det[0].prod.xProd = 'iPod' + t.NFe.infNFe.det[0].prod.NCM = '84716053' + t.NFe.infNFe.det[0].prod.CFOP = '6101' + t.NFe.infNFe.det[0].prod.uCom = 'UN' + t.NFe.infNFe.det[0].prod.qCom = '1.0' + t.NFe.infNFe.det[0].prod.vUnCom = '22.90' + t.NFe.infNFe.det[0].prod.vProd = '22.90' + t.NFe.infNFe.det[0].prod.cEANTrib = '' + t.NFe.infNFe.det[0].prod.uTrib = 'UN' + t.NFe.infNFe.det[0].prod.qTrib = '1.00' + t.NFe.infNFe.det[0].prod.vUnTrib = '22.90' + t.NFe.infNFe.det[0].prod.indTot = '1' + + t.NFe.infNFe.det[0].imposto.ICMS.ICMS00.orig = '0' + t.NFe.infNFe.det[0].imposto.ICMS.ICMS00.CST = '00' + t.NFe.infNFe.det[0].imposto.ICMS.ICMS00.modBC = '0' + t.NFe.infNFe.det[0].imposto.ICMS.ICMS00.vBC = '22.90' + t.NFe.infNFe.det[0].imposto.ICMS.ICMS00.pICMS = '18.00' + t.NFe.infNFe.det[0].imposto.ICMS.ICMS00.vICMS = '4.12' + + print t.render(pretty_print=True) \ No newline at end of file diff --git a/pytrustnfe/xml/DynamicXml.py b/pytrustnfe/xml/DynamicXml.py index b066ead..124c939 100644 --- a/pytrustnfe/xml/DynamicXml.py +++ b/pytrustnfe/xml/DynamicXml.py @@ -1,4 +1,4 @@ -#coding=utf-8 +# coding=utf-8 ''' Created on Jun 17, 2015 @@ -7,41 +7,46 @@ Created on Jun 17, 2015 import xml.etree.ElementTree as ET from lxml.etree import Element, tostring +from __builtin__ import str + + +class DynamicXml(object): -class DynamicXml(object): def __getattr__(self, name): - try: - return object.__getattribute__(self,name) - except: + try: + return object.__getattribute__(self, name) + except: self.__setattr__(name, None) - return object.__getattribute__(self,name) - + return object.__getattribute__(self, name) + def __setattr__(self, obj, val): - if(obj=="value" or obj=="atributos" or obj=="_indice"): - object.__setattr__(self,obj, val) + if(obj == "value" or obj == "atributos" or obj == "_indice"): + object.__setattr__(self, obj, val) else: self._indice = self._indice + 1 - object.__setattr__(self,obj, DynamicXml(val, self._indice)) + object.__setattr__(self, obj, DynamicXml(val, self._indice)) def __init__(self, value, indice=0): - self.value = value - self.atributos={} + self.value = unicode(value, 'utf-8') if isinstance(value, + str) else value + self.atributos = {} self._indice = indice - + def __str__(self): - return str(self.value) - def __call__(self, *args, **kw): - if(len(kw)>0): - self.atributos=kw - if(len(args)>0): - self.value= args[0] + return unicode(self.value) + + def __call__(self, *args, **kw): + if(len(kw) > 0): + self.atributos = kw + if(len(args) > 0): + self.value = args[0] else: return self.value def __getitem__(self, i): if not isinstance(self.value, list): self.value = [] - if(i+1 > len(self.value)): + if(i + 1 > len(self.value)): self.value.append(DynamicXml(None)) return self.value[i] @@ -49,24 +54,23 @@ class DynamicXml(object): root = Element(self.value) self._gerar_xml(root, self) return tostring(root, pretty_print=pretty_print) - + def _gerar_xml(self, xml, objeto): items = sorted( - objeto.__dict__.items(), + objeto.__dict__.items(), key=lambda x: x[1]._indice if isinstance(x[1], DynamicXml) else 0 ) for attr, value in items: - if(attr!="value" and attr!="atributos" and attr!="_indice"): - if isinstance(value(), list): + if(attr != "value" and attr != "atributos" and attr != "_indice"): + if isinstance(value(), list): for item in value(): - sub = ET.SubElement(xml, attr) + sub = ET.SubElement(xml, attr) self._gerar_xml(sub, item) else: - sub = ET.SubElement(xml, attr) - if(str(value)!="None"): - sub.text = str(value) + sub = ET.SubElement(xml, attr) + if(unicode(value) != u"None"): + sub.text = unicode(value) self._gerar_xml(sub, value) - elif(attr=="atributos"): - for atr, val in value.items(): + elif(attr == "atributos"): + for atr, val in value.items(): xml.set(atr.replace("__", ":"), str(val)) -