ScoDoc-Lille/app/but/bulletin_but_pdf.py

269 lines
9.8 KiB
Python

##############################################################################
# ScoDoc
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
# See LICENSE
##############################################################################
"""Génération bulletin BUT au format PDF standard
"""
from reportlab.platypus import KeepInFrame, Paragraph, Spacer
from app.scodoc.sco_pdf import blue, cm, mm
from app.scodoc import gen_tables
from app.scodoc.sco_utils import fmt_note
from app.scodoc.sco_bulletins_standard import BulletinGeneratorStandard
class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
"""Génération du bulletin de BUT au format PDF.
self.infos est le dict issu de BulletinBUT.bulletin_etud_complet()
"""
list_in_menu = False # spécialisation du BulletinGeneratorStandard, ne pas présenter à l'utilisateur
scale_table_in_page = False
def bul_table(self, format="html"):
"""Génère la table centrale du bulletin de notes
Renvoie:
- en HTML: une chaine
- en PDF: une liste d'objets PLATYPUS (eg instance de Table).
"""
tables_infos = [
# ---- TABLE SYNTHESE UES
self.but_table_synthese_ues(),
# ---- TABLE RESSOURCES
self.but_table_ressources(),
# ---- TABLE SAE
self.but_table_saes(),
]
objects = []
for i, (col_keys, rows, pdf_style, col_widths) in enumerate(tables_infos):
table = gen_tables.GenTable(
rows=rows,
columns_ids=col_keys,
pdf_table_style=pdf_style,
pdf_col_widths=[col_widths[k] for k in col_keys],
preferences=self.preferences,
html_class="notes_bulletin",
html_class_ignore_default=True,
html_with_td_classes=True,
)
table_objects = table.gen(format=format)
objects += table_objects
# objects += [KeepInFrame(0, 0, table_objects, mode="shrink")]
if i != 2:
objects.append(Spacer(1, 6 * mm))
return objects
def but_table_synthese_ues(self, title_bg=(182, 235, 255)):
"""La table de synthèse; pour chaque UE, liste des ressources et SAÉs avec leurs notes
et leurs coefs.
Renvoie: colkeys, P, pdf_style, colWidths
- colkeys: nom des colonnes de la table (clés)
- P : table (liste de dicts de chaines de caracteres)
- pdf_style : commandes table Platypus
- largeurs de colonnes pour PDF
"""
col_widths = {
"titre": None,
"moyenne": 2 * cm,
"coef": 2 * cm,
}
title_bg = tuple(x / 255.0 for x in title_bg)
# elems pour générer table avec gen_table (liste de dicts)
rows = [
# Ligne de titres
{
"titre": "Unités d'enseignement",
"moyenne": "Note/20",
"coef": "Coef.",
"_css_row_class": "note_bold",
"_pdf_row_markup": ["b"],
"_pdf_style": [
("BACKGROUND", (0, 0), (-1, 0), title_bg),
("BOTTOMPADDING", (0, 0), (-1, 0), 7),
(
"LINEBELOW",
(0, 0),
(-1, 0),
self.PDF_LINEWIDTH,
blue,
),
],
}
]
col_keys = ["titre", "moyenne", "coef"] # noms des colonnes à afficher
for ue_acronym, ue in self.infos["ues"].items():
# 1er ligne titre UE
moy_ue = ue.get("moyenne")
t = {
"titre": f"{ue_acronym} - {ue['titre']}",
"moyenne": moy_ue.get("value", "-") if moy_ue is not None else "-",
"_css_row_class": "note_bold",
"_pdf_row_markup": ["b"],
"_pdf_style": [
(
"LINEABOVE",
(0, 0),
(-1, 0),
self.PDF_LINEWIDTH,
self.PDF_LINECOLOR,
),
("BACKGROUND", (0, 0), (-1, 0), title_bg),
("BOTTOMPADDING", (0, 0), (-1, 0), 7),
],
}
rows.append(t)
# 2eme ligne titre UE (bonus/malus/ects)
t = {
"titre": f"""Bonus: {ue['bonus']} - Malus: {
ue["malus"]}""",
"moyenne": f"""ECTS: {ue["ECTS"]["acquis"]} / {ue["ECTS"]["total"]}""",
"_moyenne_colspan": 2,
# "_css_row_class": "",
# "_pdf_row_markup": [""],
"_pdf_style": [
("ALIGN", (0, 0), (1, 0), "RIGHT"),
("TEXTCOLOR", (0, 0), (-1, 0), blue),
("BACKGROUND", (0, 0), (-1, 0), title_bg),
(
"LINEBELOW",
(0, 0),
(-1, 0),
self.PDF_LINEWIDTH,
self.PDF_LINECOLOR,
),
],
}
rows.append(t)
# Liste chaque ressource
for mod_code, mod in ue["ressources"].items():
t = {
"titre": f"{mod_code} {self.infos['ressources'][mod_code]['titre']}",
"moyenne": mod["moyenne"],
"coef": mod["coef"],
"_coef_pdf": Paragraph(
f"<para align=right><i>{mod['coef']}</i></para>"
),
"_pdf_style": [
(
"LINEBELOW",
(0, 0),
(-1, 0),
self.PDF_LINEWIDTH,
(0.7, 0.7, 0.7), # gris clair
)
],
}
rows.append(t)
# Global pdf style commands:
pdf_style = [
("VALIGN", (0, 0), (-1, -1), "TOP"),
("BOX", (0, 0), (-1, -1), 0.4, blue), # ajoute cadre extérieur bleu:
]
return col_keys, rows, pdf_style, col_widths
def but_table_ressources(self):
"""La table de synthèse; pour chaque ressources, note et liste d'évaluations
Renvoie: colkeys, P, pdf_style, colWidths
"""
return self.bul_table_modules(
mod_type="ressources", title="Ressources", title_bg=(248, 200, 68)
)
def but_table_saes(self):
"table des SAEs"
return self.bul_table_modules(
mod_type="saes",
title="Situations d'apprentissage et d'évaluation",
title_bg=(198, 255, 171),
)
def bul_table_modules(self, mod_type=None, title="", title_bg=(248, 200, 68)):
"""Table ressources ou SAEs
- colkeys: nom des colonnes de la table (clés)
- P : table (liste de dicts de chaines de caracteres)
- pdf_style : commandes table Platypus
- largeurs de colonnes pour PDF
"""
col_widths = {
"titre": None,
"moyenne": 2 * cm,
"coef": 2 * cm,
}
title_bg = tuple(x / 255.0 for x in title_bg)
# elems pour générer table avec gen_table (liste de dicts)
rows = [
# Ligne de titres
{
"titre": title,
"moyenne": "Note/20",
"coef": "Coef.",
"_css_row_class": "note_bold",
"_pdf_row_markup": ["b"],
"_pdf_style": [
("BACKGROUND", (0, 0), (-1, 0), title_bg),
("BOTTOMPADDING", (0, 0), (-1, 0), 7),
(
"LINEBELOW",
(0, 0),
(-1, 0),
self.PDF_LINEWIDTH,
blue,
),
],
}
]
col_keys = ["titre", "moyenne", "coef"] # noms des colonnes à afficher
for mod_code, mod in self.infos[mod_type].items():
# 1er ligne titre module
t = {
"titre": f"{mod_code} - {mod['titre']}",
"moyenne": "", # pas de moyenne
"_css_row_class": "note_bold",
"_pdf_row_markup": ["b"],
"_pdf_style": [
(
"LINEABOVE",
(0, 0),
(-1, 0),
self.PDF_LINEWIDTH,
self.PDF_LINECOLOR,
),
("BACKGROUND", (0, 0), (-1, 0), title_bg),
("BOTTOMPADDING", (0, 0), (-1, 0), 7),
],
}
rows.append(t)
# Evaluations:
for e in mod["evaluations"]:
t = {
"titre": f"{e['description']}",
"moyenne": e["note"]["value"],
"coef": e["coef"],
"_coef_pdf": Paragraph(
f"<para align=right><i>{e['coef']}</i></para>"
),
"_pdf_style": [
(
"LINEBELOW",
(0, 0),
(-1, 0),
self.PDF_LINEWIDTH,
(0.7, 0.7, 0.7), # gris clair
)
],
}
rows.append(t)
# Global pdf style commands:
pdf_style = [
("VALIGN", (0, 0), (-1, -1), "TOP"),
("BOX", (0, 0), (-1, -1), 0.4, blue), # ajoute cadre extérieur bleu:
]
return col_keys, rows, pdf_style, col_widths