From 36fd6a4961b5d653f2b47b1ae39c71d9cd9003e0 Mon Sep 17 00:00:00 2001 From: martini97 Date: Fri, 30 Sep 2016 19:21:59 -0300 Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=A3o=20do=20Danfe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pytrustnfe/pdf/__init__.py | 72 ++++------------------- pytrustnfe/pdf/super_table.py | 129 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 60 deletions(-) create mode 100644 pytrustnfe/pdf/super_table.py diff --git a/pytrustnfe/pdf/__init__.py b/pytrustnfe/pdf/__init__.py index e0d454a..d9617df 100644 --- a/pytrustnfe/pdf/__init__.py +++ b/pytrustnfe/pdf/__init__.py @@ -2,13 +2,8 @@ # © 2016 Danimar Ribeiro, Trustcode # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from uuid import uuid4 -from reportlab.platypus.tables import Table -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 +from super_table import PdfTable, PdfCell +from .xml import sanitize_response inch = 28.34 @@ -18,60 +13,17 @@ class Danfe(object): objeto = None def __init__(self, objetoNFe): - self.objeto = objetoNFe + self.objeto = sanitize_response(objetoNFe)[1] + self.NFe = self.objeto.getchildren()[2] + self.infNFe = self.NFe.getchildren()[0] + self.ide = self.infNFe.getchildren()[0] + self.emitente = self.infNFe.getchildren()[1] + self.destinatario = self.infNFe.getchildren()[2] - def _header(self): - data = [[ - 'Recebemos de %s os produtos constantes na nota fiscal abaixo' % '', - '', 'NF-e\nNº %s\nSérie 001' - ], [ - 'Data de recebimento', - 'Identificação e assinatura do recebedor', - '' - ]] + def nfe(self): + danfe = PdfTable(columns=12) + pass - estilo = [('SPAN', (0, 0), (1, 0)), - ('SPAN', (2, 0), (2, 1)), - ('FONTSIZE', (0, 0), (1, 1), 7.0), - ('VALIGN', (0, 0), (1, 1), 'TOP'), - ('ALIGN', (2, 0), (2, 1), 'CENTER'), - ('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( - '/tmp/' + uuid4().hex, - pagesize=A4, leftMargin=0.5 * inch, rightMargin=0.5 * inch, - topMargin=0.5 * inch, bottomMargin=0.5 * inch) - - elementos = [] - - elementos.append(self._header()) - elementos.append(self._segundo_cabecalho()) - - doc.build(elementos) + pass diff --git a/pytrustnfe/pdf/super_table.py b/pytrustnfe/pdf/super_table.py new file mode 100644 index 0000000..6191567 --- /dev/null +++ b/pytrustnfe/pdf/super_table.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# © 2016 Danimar Ribeiro, Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from reportlab.lib import colors +from reportlab.platypus import SimpleDocTemplate, BaseDocTemplate, Table, TableStyle +from reportlab.lib.pagesizes import A4 +# from reportlab.lib.units import mm + +INCH = 28.34 + + +class PdfTable(object): + + def __init__(self, columns=1, width=100): + self.columns = columns + self.width = width + self.cells = [] + self.cell_width = self.width/float(self.columns) + + def add_cell(self, cell): + cell.width = self.cell_width + if cell.value.__class__ == PdfTable: + cell.value.width = cell.width + cell.value.cell_width = cell.width / float(cell.value.columns) + + if cell.colspan > 1: + colspan_tot = sum([x.colspan for x in self.cells]) + colspan_tot += cell.colspan + # if colspan_tot % self.columns != 0: + # raise Exception('Colspan incompatível') + self.cells.append(cell) + + def render(self): + colspan_tot = sum([x.colspan for x in self.cells]) + if colspan_tot % self.columns != 0: + raise Exception('O número de celulas adicionadas é incompleto') + + style = [] + data = [] + linha = [] + colspan_tot = 0 + i = j = 0 + + for cell in self.cells: + colspan_tot += cell.colspan + style += cell.style(j, i) + j += 1 + + if isinstance(cell.value, PdfTable): + linha.append(cell.value.render()) + else: + linha.append(cell.value) + if cell.colspan > 1: + for xi in range(1, cell.colspan): + linha.append('') + style += cell.style(j, i, colspan=False) + j += 1 + + if colspan_tot % self.columns == 0: + data.append(linha) + colspan_tot = 0 + linha = [] + j = 0 + i += 1 + + t = Table(data, colWidths=[self.cell_width for + k in range(self.columns)]) + t.setStyle(TableStyle(style)) + return t + + +class PdfCell(object): + + def __init__(self, value, colspan=1): + self.width = 1 + self.value = value + self.colspan = colspan + self.background_color = colors.white + self.text_color = colors.black + self.font_size = 5 + self.bold = False + self.border_width = 1 + self.border_color = colors.black + + def style(self, i, j, colspan=True): + span = [] + if self.colspan > 1 and colspan: + span = [('SPAN', (i, j), (i+self.colspan-1, j))] + if not self.border_width == 0: + span += [('INNERGRID', (i, j), (i, j), self.border_width, + self.border_color), + ('BOX', (i, j), (i, j), self.border_width, + self.border_color)] + return span + [ + ('BACKGROUND', (i, j), (i, j), self.background_color), + ('TEXTCOLOR', (i, j), (i, j), self.text_color), + ('TOPPADDING', (i, j), (i, j), 3 if + isinstance(self.value, str) else 0), + ('LEFTPADDING', (i, j), (i, j), 5 if + isinstance(self.value, str) else 0), + ('RIGHTPADDING', (i, j), (i, j), 5 if + isinstance(self.value, str) else 0), + ('BOTTOMPADDING', (i, j), (i, j), 3 if + isinstance(self.value, str) else 0), + ('FONTSIZE', (i, j), (i, j), self.font_size), + ] + + +if __name__ == '__main__': + + table = PdfTable(columns=30, width=(20 * INCH)*1.7) + + table2 = PdfTable(columns=12) + + table2.add_cell(PdfCell('RECEBEMOS DE ISOCOMPÓSITOS EIRELI ME OS PRODUTOS \ +E/OU SERVIÇOS CONSTANTES DA NOTA FISCAL ELETRÔNICA INDICADA AO LADO', + colspan=12)) + table2.add_cell(PdfCell('Data de Recebimento', colspan=2)) + table2.add_cell(PdfCell('Assinatura', colspan=10)) + + table.add_cell(PdfCell(table2, colspan=10)) + table.add_cell(PdfCell(table2, colspan=20)) + + table = table.render() + + doc = SimpleDocTemplate("ola.pdf", pagesize=A4, leftMargin=0, + rightMargin=0, topMargin=0, bottomMargin=0) + doc.build([table])