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))
-