Delete weasyprint file

This commit is contained in:
Gregory Trullemans 2022-11-19 19:19:52 +01:00
parent 97c5081bb3
commit 5122bf98f3
1 changed files with 0 additions and 615 deletions

View File

@ -1,615 +0,0 @@
import locale
import os
import re
from datetime import date, datetime, timedelta
from statistics import mean
import pendulum
import yaml
from django.conf import settings
from django.db.models import Max, Q
from html2rml import html2rml # ####
from PIL import Image
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import cm
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import Paragraph, Table, TableStyle
from ultron.followup.models import (
Accident,
Chrono,
HeightWeight,
MindState,
Plan,
Point,
)
from ultron.objective.models import Skill
from ultron.people.models import Gymnast
from ultron.planning.models import Event
from .date_week_transition import from_date_to_week_number
# EXPENSES = 0
# RECETTES = 1
X = 35
Y = 841.89
INDENT = 5
RIGHT_X = 595.27 - X
TITLED_X = 125
INDENTED_X = X + INDENT
INDENTED_RIGHT_X = RIGHT_X - INDENT
MIDDLE = (RIGHT_X - X) / 2
PRESTATION_COLUMN_2 = INDENTED_X + 65
PRESTATION_COLUMN_3 = INDENTED_X + 400
PRESTATION_COLUMN_4 = INDENTED_X + 455
COMMON_LINE_HEIGHT = -15
SMALL_LINE_HEIGHT = COMMON_LINE_HEIGHT + 5
LARGE_LINE_HEIGHT = COMMON_LINE_HEIGHT - 5
DOUBLE_LINE_HEIGHT = COMMON_LINE_HEIGHT * 2
BIG_LINE_HEIGHT = COMMON_LINE_HEIGHT * 3
HUGE_LINE_HEIGHT = COMMON_LINE_HEIGHT * 4
class PDFDocument(object):
# Create the PDF object, using the response object as its "file."
# http://www.reportlab.com/docs/reportlab-userguide.pdf
# canvas.rect(x, y, width, height, stroke=1, fill=0)
# localhost:8000/billing/contract/pdf/2
def __init__(self, response):
# Create the PDF object, using the response object as its "file."
self.document = Canvas(response, pagesize=A4)
self.y = Y - X
self.styles = getSampleStyleSheet()
self.style = self.styles["Normal"]
self.__load_config()
def __load_config(self):
"""Charge le contenu du fichier SITE_CONFIG.YAML qui contient les données relatives à
l'ASBL.
"""
current_path = os.path.dirname(os.path.realpath(__file__))
self.club_infos = None
with open(os.path.join(current_path, "site_config.yaml"), "r") as stream:
try:
self.club_infos = yaml.load(stream, Loader=yaml.FullLoader)
except yaml.YAMLError as exc:
print(exc)
def add_vspace(self, height=COMMON_LINE_HEIGHT):
"""Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
Args:
height (int): hauteur de la ligne.
Returns:
ne retourne rien.
"""
self.y += height
print(self.y)
# if y < 120;
# document.PageBreak()
# y = 790
def add_string(
self, x, string, font_family="Helvetica", font_decoration=None, font_size=10
):
if font_decoration:
font_family += "-" + font_decoration
self.document.setFont(font_family, font_size)
self.document.drawString(x, self.y, string)
def add_new_line(
self,
x,
string,
height=COMMON_LINE_HEIGHT,
font_family="Helvetica",
font_decoration=None,
font_size=10,
):
self.add_vspace(height)
self.add_string(x, string, font_family, font_decoration, font_size)
def add_header(self, contract=None):
"""Génère le header du document.
Args:
contract (contract): instance de la class Contract.
Returns:
ne retourne rien.
"""
self.document.setFillColorRGB(0.75, 0.75, 0.75)
self.add_vspace(15)
self.add_new_line(
X, self.club_infos["SITE_TITLE"] + " - " + self.club_infos["CLUB_NAME"]
)
self.document.drawRightString(
RIGHT_X,
self.y,
self.club_infos["ADDRESS"]
+ " - "
+ self.club_infos["ZIP"]
+ " "
+ self.club_infos["CITY"],
)
self.add_new_line(X, "Head Coach : " + self.club_infos["HEAD_COACH"])
self.document.drawRightString(RIGHT_X, self.y, self.club_infos["MOBILE_PHONE"])
today = pendulum.now().date()
# print(today)
self.add_new_line(X, str(today))
begin_season = date(today.year, 9, 1)
self.document.drawRightString(
RIGHT_X, self.y, "Week " + str(from_date_to_week_number())
)
self.document.setFillColorRGB(0, 0, 0)
self.add_vspace(BIG_LINE_HEIGHT)
def download(self):
# Close the PDF object cleanly, and we're done.
self.document.showPage()
self.document.save()
class GymnastReportDocument(PDFDocument):
def generate(self, gymnast_id):
"""Genère un document aux normes du SPF Finance.
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
gymnast = Gymnast.objects.get(pk=gymnast_id)
self.document.setTitle(gymnast.first_name + " " + gymnast.last_name)
self.add_header()
self.add_gymnast_personnal_information(gymnast)
self.add_gymnast_physiological_information(gymnast)
self.add_gymnast_best_scores(gymnast)
self.add_gymnast_active_routine(gymnast)
# self.add_gymnast_level_information(gymnast)
self.add_gymnast_next_skills(gymnast)
self.add_gymnast_next_events(gymnast)
self.add_gymnast_week_notes(gymnast)
def add_gymnast_personnal_information(self, gymnast):
"""Ajoute les informations personnelles du gymnast.
Args:
gymnast <Gymnast>: gymnaste
Returns:
ne retourne rien.
"""
self.y = 26 * cm
url = os.path.join(settings.STATICFILES_DIRS[0], "img/default-avatar.png")
self.document.drawImage(url, X, self.y - 65, width=80, height=80)
self.add_string(
130,
str(gymnast),
font_decoration="Bold",
font_size=14,
)
# self.add_vspace()
self.document.setFillColorRGB(0.75, 0.75, 0.75)
self.add_new_line(130, str(gymnast.age))
self.document.setFillColorRGB(0, 0, 0)
self.add_new_line(130, str(gymnast.informations))
# self.add_vspace(HUGE_LINE_HEIGHT)
def analyse_score(self, value, value_list):
"""Analyse une value (value) par rapport à la moyenne de value_list et à la dernière
valeur de value_list
Args:
value
value_list
Returns:
string
Examples:
"""
res = ""
mean_value = mean(value_list)
if value > value_list[-1]:
res += "+"
elif value < value_list[-1]:
res += "-"
else:
res += "="
if value > mean_value:
res = "+" + res
elif value < mean_value:
res = "-" + res
else:
res = "=" + res
return res
def add_gymnast_physiological_information(self, gymnast):
"""Ajoute les informations physique et psychologique.
Args:
gymnast <Gymnast>: gymnaste
Returns:
ne retourne rien
"""
self.y = 26 * cm
self.add_new_line(
13.5 * cm,
"Physics/Mind state",
font_decoration="Bold",
)
data = []
mindstate_queryset = MindState.objects.filter(gymnast=gymnast).order_by("-date")
last_mindstate = mindstate_queryset.first()
lasts_mindstate = list(mindstate_queryset.values_list("score", flat=True)[1:6])
res = self.analyse_score(last_mindstate.score, lasts_mindstate)
data.append(["Mind state", str(last_mindstate.score), res])
height_weight_queryset = HeightWeight.objects.filter(gymnast=gymnast).order_by(
"-date"
)
last_height_weigth = height_weight_queryset.first()
lasts_height = list(
height_weight_queryset.values_list("height", flat=True)[1:6]
)
lasts_weight = list(
height_weight_queryset.values_list("weight", flat=True)[1:6]
)
res = self.analyse_score(last_height_weigth.height, lasts_height)
data.append(["Height", str(last_height_weigth.height), res])
res = self.analyse_score(last_height_weigth.weight, lasts_weight)
data.append(["Weight", str(last_height_weigth.weight), res])
style = TableStyle(
[
("ALIGN", (1, 0), (-1, -1), "RIGHT"),
# ('GRID', (0,0), (-1,-1), 0.25, colors.black),
# ('BOX', (0,0), (-1,-1), 0.25, colors.black),
]
)
table = Table(data, [2 * cm, 1.5 * cm, 1.5 * cm])
table.setStyle(style)
width, height = table.wrapOn(self.document, 19 * cm, 15.5 * cm)
table.drawOn(self.document, 13.3 * cm, self.y - height - 5)
# last_accident = Accident.objects.filter(gymnast=gymnast).order_by("-date").first()
# print(last_accident)
def add_gymnast_best_scores(self, gymnast):
"""Ajoute les meilleurs scores du gymnaste (Tof, compétition, …).
Args:
gymnast <Gymnast>: gymnaste
Returns:
ne retourne rien
"""
self.y = 23 * cm
self.add_new_line(
X,
"Best ToF",
font_decoration="Bold",
)
# self.add_vspace()
best_tof = (
Chrono.objects.filter(gymnast=gymnast)
.filter(chrono_type=0)
.order_by("-score")
.first()
)
data = [
[
"ToF |:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
],
]
best_tof = (
Chrono.objects.filter(gymnast=gymnast)
.filter(chrono_type=1)
.order_by("-score")
.first()
)
data.append(
[
"ToF R1:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
]
)
best_tof = (
Chrono.objects.filter(gymnast=gymnast)
.filter(chrono_type=2)
.order_by("-score")
.first()
)
data.append(
[
"ToF R2:",
str(best_tof.tof),
str(best_tof.score),
"(" + best_tof.date.strftime("%d-%m-%Y") + ")",
]
)
style = TableStyle(
[
("TEXTCOLOR", (-1, 0), (-1, -1), "#AAAAAA"),
]
)
table = Table(data)
table.setStyle(style)
width, height = table.wrapOn(self.document, 19 * cm, 15 * cm)
table.drawOn(self.document, X - 6, self.y - height - 5)
# self.add_vspace(self.y - height - 5)
self.y = 20 * cm
self.add_new_line(
X,
"Best Scores",
font_decoration="Bold",
)
data = [["", "Exe.", "Diff.", "ToF", "HD", "Tot.", ""]]
best_point_routine_1 = (
Point.objects.filter(gymnast=gymnast)
.filter(routine_type=1)
.order_by("-total")
.first()
)
if best_point_routine_1:
data.append(
[
"R1: ",
best_point_routine_1.point_execution,
best_point_routine_1.point_difficulty,
best_point_routine_1.point_time_of_flight,
best_point_routine_1.point_horizontal_displacement,
best_point_routine_1.total,
best_point_routine_1.event.date_begin.strftime("%d-%m-%Y"),
]
)
best_point_routine_2 = (
Point.objects.filter(gymnast=gymnast)
.filter(routine_type=2)
.order_by("-total")
.first()
)
if best_point_routine_2:
data.append(
[
"R2 :",
best_point_routine_2.point_execution,
best_point_routine_2.point_difficulty,
best_point_routine_2.point_time_of_flight,
best_point_routine_2.point_horizontal_displacement,
best_point_routine_2.total,
best_point_routine_2.event.date_begin.strftime("%d-%m-%Y"),
]
)
else:
data.append(
[
"R2:",
"-",
"-",
"-",
"-",
"-",
]
)
style = TableStyle(
[
("ALIGN", (0, 0), (-1, 0), "CENTER"),
("ALIGN", (1, 1), (-1, -1), "RIGHT"),
("TEXTCOLOR", (-1, 0), (-1, -1), "#AAAAAA"),
# ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
# ('LINEABOVE', (0,-1), (-1,-1), 0.25, colors.black),
]
)
table = Table(data)
table.setStyle(style)
width, height = table.wrapOn(self.document, 19 * cm, 15 * cm)
table.drawOn(self.document, X - 6, self.y - height - 5)
# routine_1 = gymnast.has_routine.prefetch_related("routine").filter(
# date_end__isnull=True
# )
self.add_vspace(HUGE_LINE_HEIGHT)
def add_gymnast_active_routine(self, gymnast):
"""Ajoute les routines actives"""
self.y = 23 * cm
self.add_new_line(
15.9 * cm,
"Routines",
font_decoration="Bold",
)
routine_1 = (
gymnast.has_routine.filter(routine_type=1)
.filter(date_begin__lte=date.today())
.filter(Q(date_end__gte=date.today()) | Q(date_end__isnull=True))
.first()
)
routine_2 = (
gymnast.has_routine.filter(routine_type=2)
.filter(date_begin__lte=date.today())
.filter(Q(date_end__gte=date.today()) | Q(date_end__isnull=True))
.first()
)
data = []
for routine_skill in routine_1.routine.skill_links.all():
data.append([routine_skill.skill.notation, routine_skill.skill.difficulty])
data.append([None, routine_1.routine.difficulty])
style = TableStyle(
[
("ALIGN", (1, 0), (1, -1), "RIGHT"),
# ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
("LINEABOVE", (0, -1), (-1, -1), 0.25, colors.black),
]
)
table = Table(data, [2 * cm, 1 * cm])
table.setStyle(style)
width, height = table.wrapOn(self.document, 19 * cm, 15 * cm)
table.drawOn(self.document, 13.5 * cm, self.y - height - 5)
data = []
for routine_skill in routine_2.routine.skill_links.all():
data.append([routine_skill.skill.notation, routine_skill.skill.difficulty])
data.append([None, routine_2.routine.difficulty])
style = TableStyle(
[
("ALIGN", (1, 0), (1, -1), "RIGHT"),
# ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
("LINEABOVE", (0, -1), (-1, -1), 0.25, colors.black),
]
)
table = Table(data, [2 * cm, 1 * cm])
table.setStyle(style)
width, height = table.wrapOn(self.document, 19 * cm, 15.5 * cm)
table.drawOn(self.document, 17 * cm, self.y - height - 5)
def add_gymnast_next_skills(self, gymnast):
"""Ajoute les prochains skill (skill planifié) à apprendre
Args:
gymnast <Gymnast> gymnaste
Returns:
Ne retourne rien
"""
self.y = 17 * cm
self.add_new_line(
X,
"Next skills to learn",
font_decoration="Bold",
)
self.add_vspace(-3)
planified_skills = (
Skill.objects.filter(plan__gymnast=gymnast.id)
.filter(Q(plan__is_done=False) | Q(plan__date__gte=date.today()))
.order_by("-plan__date")[:6]
)
# Ne permet pas de récupérer que les skill, or je voudrais bien.
# planified_skills = (
# Plan.objects.filter(gymnast=gymnast.id)
# .filter(
# Q(is_done=False)
# | Q(date__gte=date.today())
# )
# .order_by("-date")[:6]
# )
for planified_skill in planified_skills:
self.add_new_line(
X,
planified_skill.skill.short_label
+ " ("
+ planified_skill.skill.notation
+ ") for (todo: compute deadline)",
)
def add_gymnast_next_events(self, gymnast):
"""Ajoute les évènements futurs du gymnaste"""
self.y = 13.5 * cm
self.add_new_line(
X,
"Next event",
font_decoration="Bold",
)
self.add_vspace(-3)
today = pendulum.now().date()
next_event_list = Event.objects.filter(
gymnasts=gymnast.id, date_begin__gte=today
).order_by("date_begin")[:5]
data = []
for event in next_event_list:
data.append(
[
event.date_begin.strftime("%d-%m-%Y"),
"in " + str(event.number_of_week_from_today) + " week(s)",
event.name,
]
)
if not data:
return
style = TableStyle(
[
("ALIGN", (1, 0), (1, -1), "CENTER"),
# ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
# ('GRID', (0,0), (-1,-1), 0.25, colors.black),
# ('LINEABOVE', (0,-1), (-1,-1), 0.25, colors.black),
]
)
table = Table(data, [2.3 * cm, 2.2 * cm, 8 * cm])
table.setStyle(style)
width, height = table.wrapOn(self.document, 19 * cm, 15.5 * cm)
table.drawOn(self.document, X - 6, self.y - height - 5)
def add_gymnast_week_notes(self, gymnast):
"""Ajoute les notes de la semaine du gymnaste passé en paramètre"""
self.y = 10.3 * cm
self.add_new_line(
X,
"Notes",
font_decoration="Bold",
)
self.add_vspace(-2 * cm)
today = pendulum.today().date()
begin_week = today
if today.weekday() != 0:
begin_week -= today.weekday()
notes = gymnast.remarks.filter(created_at__gte=begin_week)
html_text = ""
for note in notes:
html_text += "<br />" + note.to_markdown()
html_text = html_text[6:]
print(html_text)
paragraph = Paragraph(html_text, self.style, bulletText="*")
width, height = paragraph.wrap(18 * cm, 18 * cm)
paragraph.drawOn(self.document, X, self.y)