736 lines
23 KiB
Python
736 lines
23 KiB
Python
# coding: utf-8
|
|
import os
|
|
import math
|
|
from PIL import Image
|
|
from fpdf import FPDF
|
|
from flask import current_app
|
|
from flask_login import current_user
|
|
from tempfile import NamedTemporaryFile
|
|
from functools import cache
|
|
from webinterface.models.documentos import Documento
|
|
from datetime import datetime, timedelta, date
|
|
from PyPDF2 import PdfFileReader, PdfFileMerger
|
|
from webinterface.models.gestion import Objetivo, Accion, Evidencia, Comision
|
|
|
|
@cache
|
|
def logoyencabezado(Nodo):
|
|
uuid_nill = "00000000000000000000000000000000"
|
|
responsable = Nodo.responsable
|
|
|
|
while responsable.creado > 1:
|
|
responsable = responsable.supervisor
|
|
|
|
titulo = None
|
|
logo = None
|
|
docLogo = Documento.query.filter(Documento.hash==responsable.logo).one_or_none()
|
|
if docLogo is not None:
|
|
logoFile = docLogo.get_file()
|
|
if logoFile is not None:
|
|
logo = os.path.abspath(logoFile)
|
|
|
|
docTitulo = Documento.query.filter(Documento.hash==responsable.titulo).one_or_none()
|
|
if docTitulo is not None:
|
|
tituloFile = docTitulo.get_file()
|
|
if tituloFile is not None:
|
|
titulo = os.path.abspath(tituloFile)
|
|
|
|
return (logo, titulo)
|
|
|
|
|
|
def ReportePDF(Archivo, Nodo, Fini=None, Ffin=None):
|
|
logo, titulo = logoyencabezado(Nodo)
|
|
|
|
maindoc = plantillaReporte(Titulo=Nodo.nombre, Logo=logo, Encabezado=titulo)
|
|
|
|
maindoc.set_title(u"Reporte de Gestión: {}".format(Nodo.nombre))
|
|
maindoc.set_subject(Nodo.nombre)
|
|
maindoc.set_author("iLab Gestion: {}".format(maindoc.serial))
|
|
maindoc.set_creator(current_user.ascii_nombrecompleto)
|
|
|
|
Horachilena=datetime.today() - timedelta(hours=4)
|
|
Horachilenastr = Horachilena.strftime('Generado el %d/%m/%Y a las %H horas')
|
|
|
|
if isinstance(Fini,date) and isinstance(Ffin, date) and Fini < Ffin:
|
|
maindoc.Tapa('Reporte de Gestión desde {:%d/%m/%Y} hasta {:%d/%m/%Y}.'.format(Fini, Ffin), Linea2=Nodo.nombre, Linea3=Horachilenastr, Logo=True)
|
|
else:
|
|
maindoc.Tapa('Reporte de Gestión', Linea2=Nodo.nombre, Linea3=Horachilenastr, Logo=True)
|
|
|
|
maindoc, _, _ = ReporteNodo(maindoc, Nodo, True, Fini, Ffin)
|
|
|
|
paginas_en_blanco = maindoc.paginas_en_blanco
|
|
anexos_pdf = maindoc.anexospdf
|
|
paginas_reporte = maindoc.page_no()
|
|
|
|
current_app.logger.debug(u'PDF original tiene {} páginas'.format(paginas_reporte))
|
|
|
|
with NamedTemporaryFile() as tmp:
|
|
maindoc.output(name=tmp.name, dest='F')
|
|
|
|
merger = PdfFileMerger(strict=False)
|
|
pagina = 0
|
|
while pagina < paginas_reporte:
|
|
|
|
if pagina not in paginas_en_blanco:
|
|
merger.append(tmp.name, pages=(pagina, pagina+1))
|
|
pagina = pagina + 1
|
|
else:
|
|
archivo_pdf, largo = anexos_pdf.pop(0)
|
|
merger.append(archivo_pdf)
|
|
pagina = pagina + largo
|
|
|
|
merger.write(Archivo)
|
|
merger.close()
|
|
|
|
return "reporte_gestion-{}-{}.pdf".format(Nodo.id, maindoc.serial)
|
|
|
|
def ListaActaPDF(Archivo, Acta):
|
|
logo, titulo = logoyencabezado(Acta.objetivo)
|
|
|
|
maindoc = plantillaReporte(Titulo='Acta {}: {}'.format(Acta.secuencia, Acta.objetivo.nombre), Logo=logo, Encabezado=titulo)
|
|
maindoc.add_page()
|
|
maindoc.PutLogoCenter()
|
|
maindoc.Titulo1(u'{} - Acta {}'.format(Acta.objetivo.nombre, Acta.secuencia), align='C', newpage=False)
|
|
maindoc.Titulo2(u"Listado de Asistentes", align='C', Tight=True)
|
|
maindoc.Titulo2(u"Fecha: {}".format(Acta.horaini.strftime('%d/%m/%Y')), align='C', Tight=True)
|
|
|
|
count = 0
|
|
w = maindoc.AnchoFirma(Acta.asistentes)
|
|
|
|
for asistente in Acta.asistentes:
|
|
if count>0 and count % 11 == 0:
|
|
maindoc.add_page()
|
|
maindoc.ln(25)
|
|
count = count + 1
|
|
# maindoc.ln(5)
|
|
maindoc.Firma("{}) {}".format(count, asistente),Ancho=w)
|
|
|
|
|
|
maindoc.output(name=Archivo, dest='F')
|
|
|
|
return "Lista acta {}-{} {}.pdf".format(Acta.secuencia, Acta.objetivo.nombre, maindoc.serial)
|
|
|
|
def ActaPDF(Archivo, Acta):
|
|
logo, titulo = logoyencabezado(Acta.objetivo)
|
|
maindoc = plantillaReporte(Titulo='Acta {}: {}'.format(Acta.secuencia, Acta.objetivo.nombre), Logo=logo, Encabezado=titulo)
|
|
maindoc = ReporteActa(maindoc, Acta)
|
|
|
|
paginas_en_blanco = maindoc.paginas_en_blanco
|
|
anexos_pdf = maindoc.anexospdf
|
|
paginas_reporte = maindoc.page_no()
|
|
|
|
current_app.logger.debug(u'PDF original tiene {} páginas'.format(paginas_reporte))
|
|
|
|
with NamedTemporaryFile() as tmp:
|
|
maindoc.output(name=tmp.name, dest='F')
|
|
|
|
merger = PdfFileMerger(strict=False)
|
|
pagina = 0
|
|
while pagina < paginas_reporte:
|
|
|
|
if pagina not in paginas_en_blanco:
|
|
merger.append(tmp.name, pages=(pagina, pagina+1))
|
|
pagina = pagina + 1
|
|
else:
|
|
archivo_pdf, largo = anexos_pdf.pop(0)
|
|
merger.append(archivo_pdf)
|
|
pagina = pagina + largo
|
|
|
|
merger.write(Archivo)
|
|
merger.close()
|
|
|
|
return "acta {}-{} {}.pdf".format(Acta.secuencia, Acta.objetivo.nombre, maindoc.serial)
|
|
|
|
def ReporteActa(documento, Acta):
|
|
|
|
documento.add_page()
|
|
documento.PutLogoCenter()
|
|
documento.Titulo1(u'Acta {}'.format(Acta.secuencia), align='C', newpage=False)
|
|
documento.Titulo1(Acta.objetivo.nombre, align='C', newpage=False)
|
|
|
|
documento.LugaryFecha(Acta.lugar, Acta.horaini, Acta.horafin)
|
|
documento.Asistentes(Acta.asistentes)
|
|
documento.TituloParrafo(u'Temas', Acta.temas)
|
|
if len(Acta.desarrollo):
|
|
documento.TituloParrafo(u'Desarrollo', Acta.desarrollo)
|
|
if len(Acta.acuerdos):
|
|
documento.TituloParrafo(u'Acuerdos', Acta.acuerdos)
|
|
|
|
links = []
|
|
fotos = []
|
|
pdfs = []
|
|
evidencias = 0
|
|
for evidencia in Acta.anexos:
|
|
|
|
if evidencia.documento.nombre[:7] == 'http://' or evidencia.documento.nombre[:8] == 'https://':
|
|
# current_app.logger.debug(u'Link detectado: {}'.format(evidencia.documento.nombre))
|
|
links.append((evidencia.documento.nombre, evidencia.documento.descripcion))
|
|
evidencias = evidencias + 1
|
|
|
|
elif evidencia.documento.tamano > 0:
|
|
nombre, extension = os.path.splitext(evidencia.documento.nombre.lower())
|
|
|
|
if extension in ['.jpg', '.jpeg', '.png']:
|
|
evidencias = evidencias + 1
|
|
fotos.append(evidencia)
|
|
|
|
if extension in ['.pdf']:
|
|
evidencias = evidencias + 1
|
|
pdfs.append(evidencia)
|
|
|
|
if evidencias > 0:
|
|
if len(links) > 0:
|
|
documento.Titulo2('Anexos')
|
|
for link in links:
|
|
documento.Link(link)
|
|
|
|
if len(fotos) > 0:
|
|
documento.FotoEvidencia(fotos)
|
|
|
|
if len(pdfs) > 0:
|
|
largo = 0
|
|
for evidencia in pdfs:
|
|
archivo = PdfFileReader(open(evidencia.documento.get_file(), "rb"))
|
|
largo = largo + archivo.getNumPages()
|
|
documento.anexospdf = (evidencia.documento.get_file(), archivo.getNumPages())
|
|
documento.pagina_en_blanco(largo)
|
|
return documento
|
|
|
|
def ReporteNodo(documento, Nodo, Recursive=True, Fini=None, Ffin=None, anexoi=0, anexos={}):
|
|
documento.Titulo1(Nodo.nombre)
|
|
|
|
if isinstance(Fini,date) and isinstance(Ffin, date) and Fini < Ffin:
|
|
rango = True
|
|
DTini = datetime(Fini.year, Fini.month, Fini.day, 0, 0, 0)
|
|
DTfin = datetime(Ffin.year, Ffin.month, Ffin.day, 23, 59, 59)
|
|
else:
|
|
rango = False
|
|
|
|
if Nodo.sub_HDS < 1:
|
|
documento.Item(Sujeto='Dedicación al objetivo:',Predicado= u'{} Horas cronológicas'.format(round(Nodo.sub_horas,1)), Ancho=55)
|
|
else:
|
|
documento.Item(Sujeto='Dedicación al objetivo:',Predicado= u'{} Horas cronológicas ({} Horas de dedicación semanal)'.format(round(Nodo.sub_horas,1), Nodo.sub_HDS), Ancho=55)
|
|
|
|
if len(Nodo.descripcion)>0:
|
|
documento.Titulo3("Descripción del Objetivo")
|
|
documento.Parrafo(Nodo.descripcion)
|
|
|
|
# indicadores
|
|
eactas = 0
|
|
|
|
for Acta in Nodo.actasr:
|
|
if rango and (Acta.horaini < DTini or Acta.horaini > DTfin):
|
|
continue
|
|
|
|
if eactas == 0:
|
|
documento.Titulo2("Actas")
|
|
documento.Indicador(Glosa="Acta/Lugar", vIni="Fecha", vAct="Hora", vFin="Fin", Titulo=True, ancho=25)
|
|
|
|
eactas = eactas + 1
|
|
documento.Indicador(Glosa="Acta {}: {}".format(Acta.secuencia, Acta.lugar), vIni=Acta.horaini.strftime('%d/%m/%Y'), vAct=Acta.horaini.strftime('%H:%M'), vFin=Acta.horafin.strftime('%H:%M'), ancho=25)
|
|
|
|
# indicadores
|
|
eind = 0
|
|
for Indicador in Nodo.indicadores:
|
|
if eind == 0:
|
|
documento.Titulo2("Indicadores")
|
|
documento.Indicador(Glosa="Indicador", vIni="Inicial", vAct="Actual", vFin="Meta", Titulo=True)
|
|
|
|
eind = eind + 1
|
|
documento.Indicador(Glosa=Indicador.nombre, vIni=Indicador.inicial, vAct=Indicador.valor, vFin=Indicador.meta)
|
|
|
|
# Actividades
|
|
if Recursive is True:
|
|
anexos = {}
|
|
eact = 0
|
|
for Accion in Nodo.iactividades:
|
|
if rango and (Accion.fecha < Fini or Accion.fecha > Ffin):
|
|
continue
|
|
|
|
if eact == 0:
|
|
documento.Titulo2("Actividades Realizadas", border='b', Tight=False)
|
|
|
|
eact = eact + 1
|
|
documento.Titulo2(u"Actividad {}: {}".format(eact, Accion.nombre))
|
|
documento.Item(Sujeto='Fecha:',Predicado= u'{}'.format(Accion.fecha.strftime('%d/%m/%Y')), Ancho=20)
|
|
if Accion.dedicacion < 26:
|
|
documento.Item(Sujeto='Dedicación:',Predicado= u'{} Horas cronológicas'.format(Accion.dedicacion), Ancho=30)
|
|
else:
|
|
documento.Item(Sujeto='Dedicación:',Predicado= u'{} Horas cronológicas ({} Horas de dedicación semanal)'.format(Accion.dedicacion, round(Accion.dedicacion/26,2)), Ancho=30)
|
|
if len(Accion.descripcion)>0:
|
|
documento.Titulo3(u"Descripción de la Actividad")
|
|
documento.Parrafo(Accion.descripcion)
|
|
|
|
evidencias = 0
|
|
links = []
|
|
|
|
for evidencia in Accion.evidencias:
|
|
if evidencia.documento.nombre[:7] == 'http://' or evidencia.documento.nombre[:8] == 'https://':
|
|
links.append((evidencia.documento.nombre, evidencia.documento.descripcion))
|
|
elif evidencia.documento.tamano > 0:
|
|
nombre, extension = os.path.splitext(evidencia.documento.nombre.lower())
|
|
if extension in ['.jpg', '.jpeg', '.png', '.pdf']:
|
|
evidencias = evidencias + 1
|
|
|
|
if evidencias > 0 or len(links) > 0:
|
|
documento.Titulo3('Evidencias')
|
|
|
|
if len(links)>0:
|
|
for link in links:
|
|
documento.Link(link)
|
|
|
|
if evidencias > 0:
|
|
if anexoi > 25:
|
|
v1 = chr(ord('A') + int(anexoi/26) - 1)
|
|
v2 = chr(ord('A') + anexoi%26)
|
|
|
|
v = '{}{}'.format(v1,v2)
|
|
else:
|
|
v = chr(ord('A') + anexoi)
|
|
anexoi = anexoi + 1
|
|
anexos[v] = Accion
|
|
documento.Parrafo(u'Ver Anexo {}.'.format(v))
|
|
|
|
if Recursive is True:
|
|
for hijo in Nodo.hijos:
|
|
documento, anexoi, anexos = ReporteNodo(documento, hijo, Recursive=False, Fini=Fini, Ffin=Ffin, anexoi=anexoi, anexos=anexos)
|
|
else:
|
|
return (documento, anexoi, anexos)
|
|
|
|
eacta = 0
|
|
|
|
for Acta in Nodo.actasr:
|
|
if rango and (Acta.horaini < DTini or Acta.horaini > DTfin):
|
|
continue
|
|
if eacta == 0:
|
|
eacta = 1
|
|
documento.Tapa('Anexo Actas')
|
|
|
|
documento = ReporteActa(documento, Acta)
|
|
|
|
if Recursive is True:
|
|
for hijo in Nodo.hijos:
|
|
for Acta in hijo.actas:
|
|
if rango and (Acta.horaini < DTini or Acta.horaini > DTfin):
|
|
continue
|
|
if eacta == 0:
|
|
eacta = 1
|
|
documento.Tapa('Anexo Actas')
|
|
|
|
documento = ReporteActa(documento, Acta)
|
|
|
|
|
|
for letra, anexo in anexos.items():
|
|
documento.Tapa('Anexo {}'.format(letra))
|
|
|
|
fotos = []
|
|
pdfs = []
|
|
|
|
for evidencia in anexo.evidencias:
|
|
nombre, extension = os.path.splitext(evidencia.documento.nombre.lower())
|
|
|
|
if extension in ['.jpg', '.jpeg', '.png']:
|
|
fotos.append(evidencia)
|
|
|
|
if extension in ['.pdf']:
|
|
pdfs.append(evidencia)
|
|
|
|
if len(fotos) > 0:
|
|
documento.FotoEvidencia(fotos)
|
|
|
|
if len(pdfs) > 0:
|
|
|
|
largo = 0
|
|
for evidencia in pdfs:
|
|
archivo = PdfFileReader(open(evidencia.documento.get_file(), "rb"))
|
|
largo = largo + archivo.getNumPages()
|
|
documento.anexospdf = (evidencia.documento.get_file(), archivo.getNumPages())
|
|
documento.pagina_en_blanco(largo)
|
|
|
|
|
|
return (documento, anexoi, anexos)
|
|
|
|
|
|
class plantillaReporte(FPDF):
|
|
|
|
def __init__(self, Titulo = None, Logo = None, Encabezado = None):
|
|
super(plantillaReporte, self).__init__('P', 'mm', 'Letter')
|
|
self.set_compression(True)
|
|
self.add_font('dejavu', '', fname='/srv/font/DejaVuSerif.ttf', uni=True)
|
|
self.add_font('dejavu', 'B', fname='/srv/font/DejaVuSerif-Bold.ttf', uni=True)
|
|
self.add_font('dejavu', 'I', fname='/srv/font/DejaVuSerif-Italic.ttf', uni=True)
|
|
self.add_font('dejavu', 'BI', fname='/srv/font/DejaVuSerif-BoldItalic.ttf', uni=True)
|
|
self.__titulo = Titulo
|
|
self.__ancho = 215.9 # 190 / 185
|
|
self.__alto = 279.4 # 125 / 120
|
|
self.__columna = 90
|
|
self.__limiteT2 = 0.8 * self.__alto
|
|
self.__limiteT3 = 0.85 * self.__alto
|
|
self.__codigo = datetime.today().strftime('%Y%m%d%H.%M%S')
|
|
self.__blanks = []
|
|
self.__pdf = []
|
|
self.__subtitulo = None
|
|
self.__h1 = 14
|
|
self.__h2 = 12
|
|
self.__h3 = 10
|
|
self.__logo = Logo
|
|
self.__encabezado = Encabezado
|
|
|
|
# self.__fecha = datetime.today().strftime('%d/%m/%Y a las %H horas')
|
|
# self.__titulos = []
|
|
# self.__ptitulos = []
|
|
|
|
# Encabezado
|
|
def header(self):
|
|
if self.__titulo is not None and self.page_no() > 1:
|
|
self.set_y(1)
|
|
self.cell(0, 5+self.__h1, u'', border='B', ln=1, align='C')
|
|
if self.__encabezado is not None:
|
|
imLogo = Image.open(os.path.abspath(self.__encabezado))
|
|
w, h = imLogo.size
|
|
|
|
ancho = self.__h2 * w / h
|
|
|
|
_, extension = os.path.splitext(self.__logo)
|
|
|
|
self.image(self.__encabezado, x=10, y=6, w=ancho, type=extension[1:])
|
|
else:
|
|
self.set_font('dejavu', 'B', self.__h2)
|
|
self.set_y(5)
|
|
self.cell(110, self.__h1, self.__titulo, border=0, ln=0, align='L')
|
|
# if self.__subtitulo is not None:
|
|
# self.cell(0, 10, self.__subtitulo, border=0, ln=0, align='R')
|
|
self.ln(self.__h2)
|
|
|
|
# Pie de Página
|
|
def footer(self):
|
|
# Position at 1.5 cm from bottom
|
|
if self.page_no() > 1:
|
|
self.set_y(-15)
|
|
self.cell(0, 8, u'', border='T', ln=1, align='C')
|
|
self.set_y(-15)
|
|
self.set_font('dejavu', '', 3)
|
|
self.cell(60, self.__h3, u'Versión: {}'.format(self.__codigo), border=0, ln=0, align='L')
|
|
self.set_font('dejavu', 'I', self.__h3)
|
|
self.cell(0, self.__h3, u'Página {}'.format(self.page_no()), border=0, ln=0, align='R')
|
|
|
|
def pagina_en_blanco(self, Num = 1):
|
|
for i in range(Num):
|
|
self.Tapa(u"Esta página fue dejada intencionalmente en blanco")
|
|
self.__blanks.append(self.page_no()-1)
|
|
|
|
@property
|
|
def anexospdf(self):
|
|
return self.__pdf
|
|
|
|
@anexospdf.setter
|
|
def anexospdf(self, valor):
|
|
self.__pdf.append(valor)
|
|
|
|
@property
|
|
def paginas_en_blanco(self):
|
|
return self.__blanks
|
|
|
|
@property
|
|
def serial(self):
|
|
return self.__codigo
|
|
|
|
def Tapa(self, Titulo, Linea2=None, Linea3=None, Logo=False):
|
|
if self.page_no() > 1:
|
|
self.__subtitulo = Titulo
|
|
|
|
self.add_page()
|
|
|
|
if self.__logo is not None and Logo is True:
|
|
self.ln(self.__h1)
|
|
self.ln(self.__h2)
|
|
self.PutLogoCenter()
|
|
|
|
|
|
if Linea2 or Linea3:
|
|
self.set_y((self.__alto-40)/2)
|
|
else:
|
|
self.set_y((self.__alto-20)/2)
|
|
|
|
|
|
self.set_font('dejavu', 'B', self.__h1+2)
|
|
self.multi_cell(0, self.__h1, Titulo, border=0, align='C')
|
|
if Linea2 is not None:
|
|
self.set_font('dejavu', 'B', self.__h1)
|
|
self.multi_cell(0, self.__h2, Linea2, border=0, align='C')
|
|
if Linea3 is not None:
|
|
self.set_font('dejavu', '', self.__h2)
|
|
self.multi_cell(0, self.__h3, Linea3, border=0, align='C')
|
|
|
|
def PutLogoCenter(self):
|
|
if self.__logo is not None:
|
|
yini = self.get_y()
|
|
|
|
imLogo = Image.open(os.path.abspath(self.__logo))
|
|
w, h = imLogo.size
|
|
|
|
y = self.__columna * h / w
|
|
xLogo = (self.__ancho - self.__columna) / 2
|
|
|
|
_, extension = os.path.splitext(self.__logo)
|
|
# current_app.logger.debug(u'Logo {} {} {} {} {}'.format(xLogo,w,h,y,extension))
|
|
self.image(self.__logo, x=xLogo, y=yini, w=self.__columna, type=extension[1:])
|
|
|
|
yfin = yini + y
|
|
|
|
self.set_y(yfin)
|
|
|
|
def Titulo1(self, Titulo, align='L', newpage=True):
|
|
if newpage:
|
|
self.add_page()
|
|
# self.__titulos.append(Titulo)
|
|
# self.__ptitulos.append(self.page_no())
|
|
self.set_font('dejavu', 'B', self.__h1)
|
|
self.multi_cell(0, self.__h1, Titulo, border=0, align=align)
|
|
# self.cell(0, self.__h1, Titulo, border=0, ln=0, align=align)
|
|
# self.ln(self.__h1)
|
|
|
|
def Titulo2(self, Titulo, border=0, align='L', Tight=True):
|
|
if not Tight:
|
|
self.ln(self.__h3)
|
|
|
|
if self.get_y() > self.__limiteT2:
|
|
self.add_page()
|
|
self.set_font('dejavu', 'B', self.__h2)
|
|
self.multi_cell(0, self.__h2, Titulo, border=0, align=align)
|
|
# self.cell(0, self.__h2, Titulo, border=border, ln=0, align=align)
|
|
# self.ln(self.__h2)
|
|
|
|
def Titulo3(self, Titulo):
|
|
if self.get_y() > self.__limiteT3:
|
|
self.add_page()
|
|
self.set_font('dejavu', 'B', self.__h3)
|
|
self.multi_cell(0, self.__h3, Titulo, border=0, align='L')
|
|
|
|
# self.cell(0, self.__h3, Titulo, border=0, ln=0, align='L')
|
|
# self.ln(self.__h3)
|
|
|
|
def Parrafo(self, Texto):
|
|
self.Normal()
|
|
self.multi_cell(0, self.__h3, Texto, align='J')
|
|
# self.ln(self.__h3)
|
|
|
|
def Normal(self):
|
|
self.set_font('dejavu', '', self.__h3)
|
|
|
|
def LimpiaColordeFondo(self):
|
|
self.set_fill_color(1, 1, 1)
|
|
def ColordeFondo(self):
|
|
self.set_fill_color(230, 230, 230)
|
|
|
|
def TituloParrafo(self, Titulo, Parrafo):
|
|
self.set_font('dejavu', 'B', self.__h2)
|
|
self.cell(0, self.__h2, Titulo, border=0, ln=1, align='L')
|
|
|
|
self.ColordeFondo()
|
|
self.Normal()
|
|
self.multi_cell(0, self.__h3, Parrafo, align='J', fill=True)
|
|
self.ln(self.__h3)
|
|
|
|
def LugaryFecha(self, lugar, horaini, horafin):
|
|
self.ColordeFondo()
|
|
|
|
self.set_font('dejavu', 'B', self.__h2)
|
|
self.cell(0, self.__h2, "Lugar", border=0, ln=1, align='L')
|
|
|
|
self.set_font('dejavu', '', self.__h2)
|
|
self.cell(0, self.__h2, lugar, border=0, ln=1, align='L', fill = True)
|
|
|
|
self.set_font('dejavu', 'B', self.__h2)
|
|
self.cell(67, self.__h2, 'Fecha', border=0, ln=0, align='L')
|
|
self.cell(67, self.__h2, 'Inicio', border=0, ln=0, align='L')
|
|
self.cell(61, self.__h2, u'Término', border=0, ln=1, align='L')
|
|
|
|
self.set_font('dejavu', '', self.__h2)
|
|
self.cell(61, self.__h2, horaini.strftime('%d/%m/%Y'), border=0, ln=0, align='C', fill = True)
|
|
self.cell(6, self.__h2, '', border=0, ln=0, align='L')
|
|
self.cell(61, self.__h2, horaini.strftime('%H:%M'), border=0, ln=0, align='C', fill = True)
|
|
self.cell(6, self.__h2, '', border=0, ln=0, align='L')
|
|
self.cell(61, self.__h2, horafin.strftime('%H:%M'), border=0, ln=1, align='C', fill = True)
|
|
|
|
def Asistentes(self, asistentes):
|
|
self.ColordeFondo()
|
|
|
|
self.set_font('dejavu', 'B', self.__h2)
|
|
self.cell(0, self.__h2, "Convocados", border=0, ln=1, align='L')
|
|
|
|
count = 0
|
|
for asistente in asistentes:
|
|
self.set_font('dejavu', '', self.__h3)
|
|
rcells = math.ceil(self.get_string_width(asistente)/61)
|
|
|
|
if rcells == 1:
|
|
w = 61
|
|
elif rcells == 2:
|
|
w = 128
|
|
else:
|
|
w = 195
|
|
|
|
if ((count + rcells) % 3 <= count % 3):
|
|
self.set_font('dejavu', '', self.__h3)
|
|
self.cell(w, self.__h3, asistente, border=0, ln=1, align='C', fill = True)
|
|
else:
|
|
self.set_font('dejavu', '', self.__h3)
|
|
self.cell(w, self.__h3, asistente, border=0, ln=0, align='C', fill = True)
|
|
self.cell(6, self.__h3, '', border=0, ln=0, align='L')
|
|
|
|
count = count + rcells
|
|
|
|
if count == 0:
|
|
self.set_font('dejavu', '', self.__h3)
|
|
self.cell(0, self.__h3, 'No existen convocados', border=0, ln=1, align='L')
|
|
elif count % 3 != 0:
|
|
self.ln(self.__h2)
|
|
|
|
def Indicador(self, Glosa, vIni, vAct, vFin, Titulo = False, ancho=16):
|
|
if Titulo:
|
|
self.set_font('dejavu', 'B', self.__h3)
|
|
else:
|
|
self.set_font('dejavu', '', self.__h3)
|
|
|
|
top = self.get_y()
|
|
anchoglosa = 195 - 3*ancho
|
|
self.multi_cell(anchoglosa, self.__h3, str(Glosa), border=1, align='J')
|
|
bottom = self.get_y()
|
|
|
|
if bottom < top: # si el final está en la siguiente página, partimos la celda desde arriba.
|
|
top = 20
|
|
|
|
altura = bottom - top # 125-45 = 80 | 125-36 = 89
|
|
|
|
|
|
|
|
self.set_y(top)
|
|
self.set_x(anchoglosa+10)
|
|
|
|
# current_app.logger.debug(u'Indicador: top:{} bottom:{} altura:{} anchoglosa:{}'.format(top,bottom,altura,anchoglosa))
|
|
|
|
self.cell(ancho, altura, str(vIni), border=1, ln=0, align='C')
|
|
self.cell(ancho, altura, str(vAct), border=1, ln=0, align='C')
|
|
self.cell(ancho, altura, str(vFin), border=1, ln=1, align='C')
|
|
self.set_y(bottom)
|
|
|
|
def AnchoFirma(self, asistentes):
|
|
w = 0
|
|
self.set_font('dejavu', '', self.__h1)
|
|
for asistente in asistentes:
|
|
w = max(w, self.get_string_width(asistente))
|
|
return w+10
|
|
|
|
def Firma(self, Sujeto, Ancho=80, Titulo=False):
|
|
if Titulo:
|
|
self.set_font('dejavu', 'B', self.__h1)
|
|
else:
|
|
self.set_font('dejavu', '', self.__h1)
|
|
|
|
self.cell(Ancho, self.__h1, Sujeto , ln=0, align='L')
|
|
self.cell(0 , self.__h1, '' , border='B', ln=1)
|
|
|
|
def Item(self, Sujeto, Predicado, Ancho=80, borde=0, ln=0, alineacion='L'):
|
|
self.set_font('dejavu', 'I', self.__h2)
|
|
self.cell(Ancho, self.__h3, Sujeto, border=borde, ln=0, align=alineacion)
|
|
self.set_font('dejavu', '', self.__h2)
|
|
self.cell(0, self.__h3, Predicado, border=borde, ln=1, align=alineacion)
|
|
|
|
def Link(self, linktupla):
|
|
link, descripcion = linktupla
|
|
|
|
self.set_font('dejavu', '', self.__h2)
|
|
self.cell(35, self.__h3, u'Link Externo:', border=0, ln=0, align='L')
|
|
self.set_text_color(r=0, g=0, b=255)
|
|
if len(descripcion) > 60:
|
|
self.cell(0, self.__h3, u"{}...".format(descripcion[:60]), border=0, ln=1, align='L', link=link)
|
|
elif len(descripcion) > 0:
|
|
self.cell(0, self.__h3, descripcion, border=0, ln=1, align='L', link=link)
|
|
elif len(link) > 60:
|
|
self.cell(0, self.__h3, u"{}...".format(link[:60]), border=0, ln=1, align='L', link=link)
|
|
else:
|
|
self.cell(0, self.__h3, link, border=0, ln=1, align='L', link=link)
|
|
self.set_text_color(r=0, g=0, b=0)
|
|
|
|
def FotoEvidencia(self, fotos):
|
|
self.add_page()
|
|
|
|
nfotos = len(fotos)
|
|
|
|
filas = int(nfotos/2)
|
|
sobran = nfotos % 2
|
|
|
|
|
|
seq = 0
|
|
self.set_font('dejavu', '', self.__h2)
|
|
|
|
for fila in range(filas):
|
|
primera = seq
|
|
segunda = primera + 1
|
|
seq = seq + 2
|
|
|
|
|
|
# Obtenemos el tamaño de la imagen
|
|
im1 = Image.open(os.path.abspath(fotos[primera].documento.get_file()))
|
|
w1, h1 = im1.size
|
|
im2 = Image.open(os.path.abspath(fotos[segunda].documento.get_file()))
|
|
w2, h2 = im2.size
|
|
#Calculamos la altura a medio espacio
|
|
y1 = self.__columna * h1 / w1
|
|
y2 = self.__columna * h2 / w2
|
|
# Vemos si tenemos suficiente espacio en la hoja para poner ambas imagenes
|
|
ymax = max(y1, y2)
|
|
if ymax + self.get_y() > self.__limiteT3:
|
|
self.add_page()
|
|
# Guardamos la posición inicial antes de pegar las imagenes y sus captions
|
|
posicionYinicial = self.get_y()
|
|
|
|
## Primera imagen
|
|
yImagenCentrada = posicionYinicial + ymax - y1
|
|
xColumna1 = 10
|
|
_, extension = os.path.splitext(fotos[primera].documento.nombre)
|
|
self.image(fotos[primera].documento.get_file(), x=xColumna1, y=yImagenCentrada, w=self.__columna, type=extension[1:])
|
|
|
|
yImagenCentrada = posicionYinicial + ymax - y2
|
|
xColumna2 = 25 + self.__columna
|
|
_, extension = os.path.splitext(fotos[segunda].documento.nombre)
|
|
self.image(fotos[segunda].documento.get_file(), x=xColumna2, y=yImagenCentrada, w=self.__columna, type=extension[1:])
|
|
|
|
# Captions de las imagenes
|
|
self.set_x(10)
|
|
self.set_y(posicionYinicial + ymax + self.__h3)
|
|
self.multi_cell(w=self.__columna, h=self.__h3, txt=fotos[primera].documento.descripcion or fotos[primera].documento.nombre, border=0, align='C')
|
|
|
|
y1 = self.get_y()
|
|
|
|
self.set_y(posicionYinicial + ymax + self.__h3)
|
|
self.set_x(xColumna2)
|
|
self.multi_cell(w=self.__columna, h=self.__h3, txt=fotos[segunda].documento.descripcion or fotos[segunda].documento.nombre, border=0, align='C')
|
|
|
|
y2 = self.get_y()
|
|
|
|
# Dejamos el cursor bajo ambos captions
|
|
self.set_y(max(y1,y2))
|
|
self.ln(self.__h3)
|
|
|
|
if sobran > 0:
|
|
seq = nfotos-1
|
|
|
|
im1 = Image.open(os.path.abspath(fotos[seq].documento.get_file()))
|
|
w1, h1 = im1.size
|
|
|
|
y1 = self.__columna * h1 / w1
|
|
|
|
if y1 + self.get_y() > self.__limiteT2:
|
|
self.add_page()
|
|
# Guardamos la posición inicial antes de pegar las imagenes y sus captions
|
|
posicionYinicial = self.get_y()
|
|
|
|
xColumna1 = 10 + self.__columna / 2
|
|
_, extension = os.path.splitext(fotos[seq].documento.nombre)
|
|
self.image(fotos[seq].documento.get_file(), x=xColumna1, y=posicionYinicial, w=self.__columna, type=extension[1:])
|
|
|
|
self.set_y(posicionYinicial + y1 + self.__h3)
|
|
self.set_x(xColumna1)
|
|
self.multi_cell(w=self.__columna, h=self.__h3, txt=fotos[seq].documento.descripcion or fotos[seq].documento.nombre, border=0, align='C')
|