PDF a partir de JSON

This commit is contained in:
Mauricio Baeza 2019-01-14 02:07:42 -06:00
parent 7864e236db
commit cf0c4b8622
4 changed files with 53 additions and 24 deletions

View File

@ -340,6 +340,7 @@ class SendMail(object):
class NumberedCanvas(canvas.Canvas): class NumberedCanvas(canvas.Canvas):
X = 20.59 * cm X = 20.59 * cm
XC = 21.6 * cm / 2 + 1.5 * cm
Y = 1.5 * cm Y = 1.5 * cm
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -363,10 +364,14 @@ class NumberedCanvas(canvas.Canvas):
def draw_page_number(self, page_count): def draw_page_number(self, page_count):
self.setFont('Helvetica', 8) self.setFont('Helvetica', 8)
self.setFillColor(colors.darkred) # ~ self.setFillColor(colors.darkred)
text = 'Página {} de {}'.format(self._pageNumber, page_count) text = f'Página {self._pageNumber} de {page_count}'
self.drawRightString(self.X, self.Y, text) self.drawRightString(self.X, self.Y, text)
text = 'Factura elaborada con software libre: www.empresalibre.net'
text = 'Este documento es una representación impresa de un CFDI'
self.drawCentredString(self.XC, self.Y, text)
text = 'Factura elaborada con software libre'
self.drawString(1.5 * cm, 1.5 * cm, text) self.drawString(1.5 * cm, 1.5 * cm, text)
return return
@ -418,6 +423,8 @@ class TemplateInvoice(BaseDocTemplate):
def _emisor(self, styles, data): def _emisor(self, styles, data):
logo_path = data.pop('logo', '') logo_path = data.pop('logo', '')
logo_style = styles.pop('logo', {}) logo_style = styles.pop('logo', {})
logo_path2 = data.pop('logo2', '')
logo_style2 = styles.pop('logo2', {})
for k, v in styles.items(): for k, v in styles.items():
self._set_text(styles[k], data.get(k, '')) self._set_text(styles[k], data.get(k, ''))
@ -428,6 +435,14 @@ class TemplateInvoice(BaseDocTemplate):
for k in keys: for k in keys:
rect[k] = rect[k] * cm rect[k] = rect[k] * cm
self.canv.drawImage(logo_path, **rect) self.canv.drawImage(logo_path, **rect)
if logo_path2 and logo_style2:
rect = logo_style2['rectangulo']
keys = ('x', 'y', 'width', 'height')
for k in keys:
rect[k] = rect[k] * cm
self.canv.drawImage(logo_path2, **rect)
return return
def _receptor(self, styles, data): def _receptor(self, styles, data):
@ -449,6 +464,7 @@ class TemplateInvoice(BaseDocTemplate):
def _comprobante1(self, styles, data): def _comprobante1(self, styles, data):
title = styles.pop('titulo', {}) title = styles.pop('titulo', {})
self.canv.setTitle(f"Factura {data.get('seriefolio', '')}")
for k, v in styles.items(): for k, v in styles.items():
self._set_text(styles[k], data.get(k, '')) self._set_text(styles[k], data.get(k, ''))
@ -480,6 +496,12 @@ class TemplateInvoice(BaseDocTemplate):
fields = ('valorunitario', 'importe') fields = ('valorunitario', 'importe')
if field in fields: if field in fields:
return self._currency(value) return self._currency(value)
if field == 'descripcion':
html = '<font color="black" size=7>{}</font>'
style_bt = getSampleStyleSheet()['BodyText']
return Paragraph(html.format(value), style_bt)
return value return value
def _conceptos(self, conceptos): def _conceptos(self, conceptos):
@ -515,8 +537,8 @@ class TemplateInvoice(BaseDocTemplate):
('GRID', (0, 0), (-1, -1), 0.05 * cm, colors.white), ('GRID', (0, 0), (-1, -1), 0.05 * cm, colors.white),
('ALIGN', (1, 0), (-1, -1), 'RIGHT'), ('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
('FONTSIZE', (0, 0), (-1, -1), 8), ('FONTSIZE', (0, 0), (-1, -1), 8),
('BACKGROUND', (1, 0), (-1, -1), colors.linen), ('BACKGROUND', (1, 0), (-1, -1), colors.lightgrey),
('TEXTCOLOR', (1, 0), (-1, -1), colors.darkred), ('TEXTCOLOR', (1, 0), (-1, -1), colors.black),
('FACE', (1, 0), (-1, -1), 'Helvetica-Bold'), ('FACE', (1, 0), (-1, -1), 'Helvetica-Bold'),
] ]
table = Table(rows, colWidths=widths, spaceBefore=0.25*cm) table = Table(rows, colWidths=widths, spaceBefore=0.25*cm)
@ -524,7 +546,7 @@ class TemplateInvoice(BaseDocTemplate):
return table return table
def _comprobante2(self, styles, data): def _comprobante2(self, styles, data):
leyenda = styles.pop('leyenda', {}) leyendas = styles.pop('leyendas', {})
ls = [] ls = []
for k, v in styles.items(): for k, v in styles.items():
@ -542,7 +564,7 @@ class TemplateInvoice(BaseDocTemplate):
style_bt = getSampleStyleSheet()['BodyText'] style_bt = getSampleStyleSheet()['BodyText']
style_bt.leading = 8 style_bt.leading = 8
html_t = '<b><font size=6>{}</font></b>' html_t = '<b><font size=6>{}</font></b>'
html = '<font color="darkred" size=5>{}</font>' html = '<font color="black" size=5>{}</font>'
msg = 'Cadena original del complemento de certificación digital del SAT' msg = 'Cadena original del complemento de certificación digital del SAT'
rows = [ rows = [
(cbb, Paragraph(html_t.format('Sello Digital del CFDI'), style_bt)), (cbb, Paragraph(html_t.format('Sello Digital del CFDI'), style_bt)),
@ -558,13 +580,13 @@ class TemplateInvoice(BaseDocTemplate):
('FONTSIZE', (0, 0), (-1, -1), 6), ('FONTSIZE', (0, 0), (-1, -1), 6),
('SPAN', (0, 0), (0, -1)), ('SPAN', (0, 0), (0, -1)),
('FACE', (1, 0), (1, 0), 'Helvetica-Bold'), ('FACE', (1, 0), (1, 0), 'Helvetica-Bold'),
('BACKGROUND', (1, 1), (1, 1), colors.linen), ('BACKGROUND', (1, 1), (1, 1), colors.lightgrey),
('TEXTCOLOR', (1, 1), (1, 1), colors.darkred), ('TEXTCOLOR', (1, 1), (1, 1), colors.darkred),
('FACE', (1, 2), (1, 2), 'Helvetica-Bold'), ('FACE', (1, 2), (1, 2), 'Helvetica-Bold'),
('BACKGROUND', (1, 3), (1, 3), colors.linen), ('BACKGROUND', (1, 3), (1, 3), colors.lightgrey),
('TEXTCOLOR', (1, 3), (1, 3), colors.darkred), ('TEXTCOLOR', (1, 3), (1, 3), colors.darkred),
('FACE', (1, 4), (1, 4), 'Helvetica-Bold'), ('FACE', (1, 4), (1, 4), 'Helvetica-Bold'),
('BACKGROUND', (1, 5), (1, 5), colors.linen), ('BACKGROUND', (1, 5), (1, 5), colors.lightgrey),
('TEXTCOLOR', (1, 5), (1, 5), colors.darkred), ('TEXTCOLOR', (1, 5), (1, 5), colors.darkred),
('ALIGN', (0, 0), (0, 0), 'CENTER'), ('ALIGN', (0, 0), (0, 0), 'CENTER'),
('VALIGN', (0, 0), (0, 0), 'MIDDLE'), ('VALIGN', (0, 0), (0, 0), 'MIDDLE'),
@ -573,14 +595,14 @@ class TemplateInvoice(BaseDocTemplate):
table.setStyle(TableStyle(table_styles)) table.setStyle(TableStyle(table_styles))
ls.append(table) ls.append(table)
if leyenda: if leyendas:
if 'spaceBefore' in leyenda['estilo']: if 'spaceBefore' in leyendas['estilo']:
leyenda['estilo']['spaceBefore'] = \ leyendas['estilo']['spaceBefore'] = \
leyenda['estilo']['spaceBefore'] * cm leyendas['estilo']['spaceBefore'] * cm
msg = 'Este documento es una representación impresa de un CFDI' for t in leyendas['textos']:
ps = ParagraphStyle(**leyenda['estilo']) ps = ParagraphStyle(**leyendas['estilo'])
p = Paragraph(msg, ps) p = Paragraph(t, ps)
ls.append(p) ls.append(p)
return ls return ls
@ -607,13 +629,13 @@ class TemplateInvoice(BaseDocTemplate):
('ALIGN', (0, 0), (-1, 0), 'CENTER'), ('ALIGN', (0, 0), (-1, 0), 'CENTER'),
('TEXTCOLOR', (0, 0), (-1, 0), colors.white), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
('FACE', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FACE', (0, 0), (-1, 0), 'Helvetica-Bold'),
('BACKGROUND', (0, 0), (-1, 0), colors.darkred), ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('FONTSIZE', (0, 1), (-1, -1), 7), ('FONTSIZE', (0, 1), (-1, -1), 7),
('VALIGN', (0, 1), (-1, -1), 'TOP'), ('VALIGN', (0, 1), (-1, -1), 'TOP'),
('ALIGN', (0, 1), (0, -1), 'CENTER'), ('ALIGN', (0, 1), (0, -1), 'CENTER'),
('ALIGN', (2, 1), (2, -1), 'CENTER'), ('ALIGN', (2, 1), (2, -1), 'CENTER'),
('ALIGN', (3, 1), (5, -1), 'RIGHT'), ('ALIGN', (3, 1), (5, -1), 'RIGHT'),
('LINEBELOW', (0, 1), (-1, -1), 0.05 * cm, colors.darkred), ('LINEBELOW', (0, 1), (-1, -1), 0.05 * cm, colors.grey),
('LINEBEFORE', (0, 1), (-1, -1), 0.05 * cm, colors.white), ('LINEBEFORE', (0, 1), (-1, -1), 0.05 * cm, colors.white),
] ]
table_conceptos = Table(rows, colWidths=widths, repeatRows=1) table_conceptos = Table(rows, colWidths=widths, repeatRows=1)

View File

@ -1592,9 +1592,15 @@ def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
def to_pdf_from_json(rfc, version, data): def to_pdf_from_json(rfc, version, data):
rfc = rfc.lower()
name = '{}_{}.json'.format(rfc, version) name = '{}_{}.json'.format(rfc, version)
custom_styles = get_custom_styles(name) custom_styles = get_custom_styles(name)
path_logo = _join(PATHS['IMG'], f"{rfc}.png")
data['emisor']['logo'] = path_logo
path_logo = _join(PATHS['IMG'], f"{rfc}_2.png")
data['emisor']['logo2'] = path_logo
path = get_path_temp() path = get_path_temp()
pdf = TemplateInvoice(path) pdf = TemplateInvoice(path)
pdf.custom_styles = custom_styles pdf.custom_styles = custom_styles

View File

@ -3719,6 +3719,7 @@ class Facturas(BaseModel):
values['receptor'] = {} values['receptor'] = {}
for k, v in receptor.items(): for k, v in receptor.items():
values['receptor'][k] = v values['receptor'][k] = v
return values return values
@classmethod @classmethod

View File

@ -1,4 +1,5 @@
{ {
"colores": {"piepagina": "darkred"},
"encabezado": { "encabezado": {
"emisor": { "emisor": {
"direccion": { "direccion": {
@ -208,10 +209,9 @@
"estilo": {"name": "tipocambio", "fontName": "Helvetica", "estilo": {"name": "tipocambio", "fontName": "Helvetica",
"fontSize": 7, "alignment": 0, "textColor": "black"} "fontSize": 7, "alignment": 0, "textColor": "black"}
}, },
"leyenda": { "notas": {
"estilo": {"name": "leyenda", "fontName": "Helvetica-Bold", "estilo": {"name": "notas", "fontName": "Helvetica",
"fontSize": 6, "alignment": 1, "textColor": "black", "fontSize": 7, "alignment": 0, "textColor": "black"}
"spaceBefore": 0.2}
} }
} }
} }