From 8be3ecfeafbcdeb8261364ec0fe17dfc459689cf Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 10 Mar 2022 09:28:59 +0100 Subject: [PATCH 1/4] Bul. BUT: versions + nettoyage --- app/but/bulletin_but.py | 6 ++- app/but/bulletin_but_pdf.py | 11 +++-- app/scodoc/sco_bulletins.py | 95 +------------------------------------ 3 files changed, 13 insertions(+), 99 deletions(-) diff --git a/app/but/bulletin_but.py b/app/but/bulletin_but.py index a533fb801..13af9dea5 100644 --- a/app/but/bulletin_but.py +++ b/app/but/bulletin_but.py @@ -330,11 +330,13 @@ class BulletinBUT: return d - def bulletin_etud_complet(self, etud: Identite) -> dict: + def bulletin_etud_complet(self, etud: Identite, version="long") -> dict: """Bulletin dict complet avec toutes les infos pour les bulletins BUT pdf Résultat compatible avec celui de sco_bulletins.formsemestre_bulletinetud_dict """ - d = self.bulletin_etud(etud, self.res.formsemestre, force_publishing=True) + d = self.bulletin_etud( + etud, self.res.formsemestre, version=version, force_publishing=True + ) d["etudid"] = etud.id d["etud"] = d["etudiant"] d["etud"]["nomprenom"] = etud.nomprenom diff --git a/app/but/bulletin_but_pdf.py b/app/but/bulletin_but_pdf.py index 6a3176847..5263091a3 100644 --- a/app/but/bulletin_but_pdf.py +++ b/app/but/bulletin_but_pdf.py @@ -35,11 +35,14 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): tables_infos = [ # ---- TABLE SYNTHESE UES self.but_table_synthese_ues(), - # ---- TABLE RESSOURCES - self.but_table_ressources(), - # ---- TABLE SAE - self.but_table_saes(), ] + if self.version != "short": + tables_infos += [ + # ---- 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( diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py index 65dcb3a91..b9ebdfcc1 100644 --- a/app/scodoc/sco_bulletins.py +++ b/app/scodoc/sco_bulletins.py @@ -885,7 +885,7 @@ def do_formsemestre_bulletinetud( if formsemestre.formation.is_apc(): etud = Identite.query.get(etudid) r = bulletin_but.BulletinBUT(formsemestre) - I = r.bulletin_etud_complet(etud) + I = r.bulletin_etud_complet(etud, version=version) else: I = formsemestre_bulletinetud_dict(formsemestre.id, etudid) etud = I["etud"] @@ -980,7 +980,7 @@ def mail_bulletin(formsemestre_id, I, pdfdata, filename, recipient_addr): except KeyError as e: raise ScoValueError( "format 'Message d'accompagnement' (bul_intro_mail) invalide, revoir les réglages dans les préférences" - ) + ) from e else: hea = "" @@ -1011,97 +1011,6 @@ def mail_bulletin(formsemestre_id, I, pdfdata, filename, recipient_addr): ) -def _formsemestre_bulletinetud_header_html_old_XXX( - etud: Identite, - formsemestre: FormSemestre, - format=None, - version=None, -): - H = [ - html_sco_header.sco_header( - page_title=f"Bulletin de {etud.nomprenom}", - javascripts=[ - "js/bulletin.js", - "libjs/d3.v3.min.js", - "js/radar_bulletin.js", - ], - cssstyles=["css/radar_bulletin.css"], - ), - f""" -
-

{etud.nomprenom}

- -
- Bulletin {formsemestre.titre_mois()} -
- - - """) - # Menu - endpoint = "notes.formsemestre_bulletinetud" - menu_autres_operations = make_menu_autres_operations( - formsemestre, etud, endpoint, version - ) - - H.append("""""") - H.append( - '' - % ( - url_for( - "notes.formsemestre_bulletinetud", - scodoc_dept=g.scodoc_dept, - formsemestre_id=formsemestre.id, - etudid=etud.id, - format="pdf", - version=version, - ), - scu.ICON_PDF, - ) - ) - H.append("""
établi le {time.strftime("%d/%m/%Y à %Hh%M")} (notes sur 20) - - - -
""") - H.append(menu_autres_operations) - H.append("""
%s
""") - # - H.append( - """
%s - """ - % ( - url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id), - sco_photos.etud_photo_html(etud, title="fiche de " + etud.nomprenom), - ) - ) - H.append( - """
- """ - ) - - return "".join(H) - - def make_menu_autres_operations( formsemestre: FormSemestre, etud: Identite, endpoint: str, version: str ) -> str: From 462c084bf40ac73fe13958ed949dd8c4b15ae7bb Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 10 Mar 2022 19:35:12 +0100 Subject: [PATCH 2/4] =?UTF-8?q?Bul.=20BUT:=20Poids=20des=20evals=20avec=20?= =?UTF-8?q?valeurs=20par=20d=C3=A9faut.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/but/bulletin_but.py | 8 ++++++-- app/comp/moy_ue.py | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/but/bulletin_but.py b/app/but/bulletin_but.py index 13af9dea5..cba3732b0 100644 --- a/app/but/bulletin_but.py +++ b/app/but/bulletin_but.py @@ -11,7 +11,7 @@ import datetime from flask import url_for, g from app.comp.res_but import ResultatsSemestreBUT -from app.models import FormSemestre, Identite, formsemestre +from app.models import FormSemestre, Identite from app.scodoc import sco_bulletins, sco_utils as scu from app.scodoc import sco_bulletins_json from app.scodoc import sco_bulletins_pdf @@ -171,6 +171,10 @@ class BulletinBUT: # eval_notes est une pd.Series avec toutes les notes des étudiants inscrits eval_notes = self.res.modimpls_results[e.moduleimpl_id].evals_notes[e.id] notes_ok = eval_notes.where(eval_notes > scu.NOTES_ABSENCE).dropna() + poids = { + ue.acronyme: self.res.modimpls_evals_poids[e.moduleimpl_id][ue.id][e.id] + for ue in self.res.ues + } d = { "id": e.id, "description": e.description, @@ -178,7 +182,7 @@ class BulletinBUT: "heure_debut": e.heure_debut.strftime("%H:%M") if e.heure_debut else None, "heure_fin": e.heure_fin.strftime("%H:%M") if e.heure_debut else None, "coef": fmt_note(e.coefficient), - "poids": {p.ue.acronyme: p.poids for p in e.ue_poids}, + "poids": poids, "note": { "value": fmt_note( eval_notes[etud.id], diff --git a/app/comp/moy_ue.py b/app/comp/moy_ue.py index efbe7cd34..6d80f0b7b 100644 --- a/app/comp/moy_ue.py +++ b/app/comp/moy_ue.py @@ -197,6 +197,7 @@ def notes_sem_load_cube(formsemestre: FormSemestre) -> tuple: evals_poids, _ = moy_mod.load_evaluations_poids(modimpl.id) etuds_moy_module = mod_results.compute_module_moy(evals_poids) modimpls_results[modimpl.id] = mod_results + modimpls_evals_poids[modimpl.id] = evals_poids modimpls_notes.append(etuds_moy_module) if len(modimpls_notes): cube = notes_sem_assemble_cube(modimpls_notes) From 5a56138e5524dad5a415b9281eff63c400055fd8 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 10 Mar 2022 19:36:30 +0100 Subject: [PATCH 3/4] PDF tables: fix mix tags/Platypus markup --- app/scodoc/gen_tables.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/scodoc/gen_tables.py b/app/scodoc/gen_tables.py index 72326132b..0a4b65ca7 100644 --- a/app/scodoc/gen_tables.py +++ b/app/scodoc/gen_tables.py @@ -63,12 +63,15 @@ from app.scodoc.sco_pdf import SU from app import log -def mark_paras(L, tags): - """Put each (string) element of L between """ +def mark_paras(L, tags) -> list[str]: + """Put each (string) element of L between ..., + for each supplied tag. + Leave non string elements untouched. + """ for tag in tags: - b = "<" + tag + ">" - c = "" - L = [b + (x or "") + c for x in L] + start = "<" + tag + ">" + end = "" + L = [(start + (x or "") + end) if isinstance(x, str) else x for x in L] return L From f61a528d126061c2af644a8e113a4de58a394cc8 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 10 Mar 2022 20:44:01 +0100 Subject: [PATCH 4/4] =?UTF-8?q?Bul.=20BUT:=20am=C3=A9lioration,=20inverse?= =?UTF-8?q?=20colonnes=20droites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/but/bulletin_but_pdf.py | 99 +++++++++++++++++++++++++------------ app/views/notes.py | 1 - 2 files changed, 68 insertions(+), 32 deletions(-) diff --git a/app/but/bulletin_but_pdf.py b/app/but/bulletin_but_pdf.py index 5263091a3..ea3291c8d 100644 --- a/app/but/bulletin_but_pdf.py +++ b/app/but/bulletin_but_pdf.py @@ -6,8 +6,7 @@ """Génération bulletin BUT au format PDF standard """ -import itertools -from reportlab.platypus import KeepInFrame, Paragraph, Spacer +from reportlab.platypus import Paragraph, Spacer from app.scodoc.sco_pdf import blue, cm, mm @@ -85,6 +84,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): "titre": "Unités d'enseignement", "moyenne": "Note/20", "coef": "Coef.", + "_coef_pdf": Paragraph("Coef."), "_css_row_class": "note_bold", "_pdf_row_markup": ["b"], "_pdf_style": [ @@ -100,7 +100,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): ], } ] - col_keys = ["titre", "moyenne", "coef"] # noms des colonnes à afficher + col_keys = ["titre", "coef", "moyenne"] # noms des colonnes à afficher for ue_acronym, ue in self.infos["ues"].items(): # 1er ligne titre UE moy_ue = ue.get("moyenne") @@ -123,16 +123,16 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): } rows.append(t) # 2eme ligne titre UE (bonus/malus/ects) + ects_txt = f'ECTS: {ue["ECTS"]["acquis"]:.3g} / {ue["ECTS"]["total"]:.3g}' t = { "titre": f"""Bonus: {ue['bonus']} - Malus: { ue["malus"]}""", - "moyenne": f"""ECTS: {ue["ECTS"]["acquis"]} / {ue["ECTS"]["total"]}""", - "_moyenne_colspan": 2, + "coef": ects_txt, + "_coef_pdf": Paragraph(f"""{ects_txt}"""), + "_coef_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", @@ -141,6 +141,14 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): self.PDF_LINEWIDTH, self.PDF_LINECOLOR, ), + # cadre autour du bonus/malus + ( + "BOX", + (0, 0), + (0, 0), + self.PDF_LINEWIDTH, + (0.7, 0.7, 0.7), # gris clair + ), ], } rows.append(t) @@ -195,40 +203,54 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): - pdf_style : commandes table Platypus - largeurs de colonnes pour PDF """ + poids_fontsize = "8" + # UE à utiliser pour les poids (# colonne/UE) + ue_acros = list(self.infos["ues"].keys()) # ['RT1.1', 'RT2.1', 'RT3.1'] + # Colonnes à afficher: + col_keys = ["titre"] + ue_acros + ["coef", "moyenne"] + # Largeurs des colonnes: col_widths = { "titre": None, + # "poids": None, "moyenne": 2 * cm, "coef": 2 * cm, } + for ue_acro in ue_acros: + col_widths[ue_acro] = 12 * mm # largeur col. poids + 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 + # Ligne de titres + t = { + "titre": title, + # "_titre_colspan": 1 + len(ue_acros), + "moyenne": "Note/20", + "coef": "Coef.", + "_coef_pdf": Paragraph("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, + ), + ], + } + for ue_acro in ue_acros: + t[ue_acro] = Paragraph( + f"{ue_acro}" + ) + rows = [t] 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 + "_titre_colspan": 2 + len(ue_acros), "_css_row_class": "note_bold", "_pdf_row_markup": ["b"], "_pdf_style": [ @@ -251,7 +273,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): "moyenne": e["note"]["value"], "coef": e["coef"], "_coef_pdf": Paragraph( - f"{e['coef']}" + f"{e['coef']}" ), "_pdf_style": [ ( @@ -263,6 +285,21 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard): ) ], } + col_idx = 1 # 1ere col. poids + for ue_acro in ue_acros: + t[ue_acro] = Paragraph( + f"""{e["poids"].get(ue_acro, "")}""" + ) + t["_pdf_style"].append( + ( + "BOX", + (col_idx, 0), + (col_idx, 0), + self.PDF_LINEWIDTH, + (0.7, 0.7, 0.7), # gris clair + ), + ) + col_idx += 1 rows.append(t) # Global pdf style commands: pdf_style = [ diff --git a/app/views/notes.py b/app/views/notes.py index dfc8e644c..345511ce5 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -1885,7 +1885,6 @@ def formsemestre_bulletins_choice( formsemestre_id, title="", explanation="", choose_mail=False ): """Choix d'une version de bulletin""" - sem = sco_formsemestre.get_formsemestre(formsemestre_id) H = [ html_sco_header.html_sem_header(title), """