From c923a5015b42b02c2dbed1621e62f0154a1ac46d Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sat, 5 Mar 2022 12:47:08 +0100 Subject: [PATCH] Infos pour bulletins BUT pdf --- app/but/bulletin_but.py | 32 +++++++- app/scodoc/sco_abs_notification.py | 56 +++++++------ app/scodoc/sco_bulletins.py | 128 ++++++++++++----------------- app/scodoc/sco_find_etud.py | 4 +- app/scodoc/sco_groups.py | 16 ++-- app/scodoc/sco_import_etuds.py | 2 +- app/scodoc/sco_inscr_passage.py | 5 +- app/scodoc/sco_page_etud.py | 4 +- app/views/scolar.py | 2 +- 9 files changed, 134 insertions(+), 115 deletions(-) diff --git a/app/but/bulletin_but.py b/app/but/bulletin_but.py index 87ec62a28..c0c29bf15 100644 --- a/app/but/bulletin_but.py +++ b/app/but/bulletin_but.py @@ -16,7 +16,7 @@ from app.scodoc import sco_bulletins, sco_utils as scu from app.scodoc import sco_bulletins_json from app.scodoc import sco_bulletins_pdf from app.scodoc import sco_preferences -from app.scodoc.sco_codes_parcours import UE_SPORT +from app.scodoc.sco_codes_parcours import UE_SPORT, DEF from app.scodoc.sco_utils import fmt_note @@ -318,19 +318,42 @@ class BulletinBUT: return d def bulletin_etud_complet(self, etud: Identite) -> dict: - """Bulletin dict complet avec toutes les infos pour les bulletins pdf""" + """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["etudid"] = etud.id d["etud"] = d["etudiant"] d["etud"]["nomprenom"] = etud.nomprenom d.update(self.res.sem) + etud_etat = self.res.get_etud_etat(etud.id) d["filigranne"] = sco_bulletins_pdf.get_filigranne( - self.res.get_etud_etat(etud.id), + etud_etat, self.prefs, decision_sem=d["semestre"].get("decision_sem"), ) + if etud_etat == scu.DEMISSION: + d["demission"] = "(Démission)" + elif etud_etat == DEF: + d["demission"] = "(Défaillant)" + else: + d["demission"] = "" + # --- Absences d["nbabs"], d["nbabsjust"] = self.res.formsemestre.get_abs_count(etud.id) + + # --- Decision Jury + infos, dpv = sco_bulletins.etud_descr_situation_semestre( + etud.id, + self.res.formsemestre.id, + format="html", + show_date_inscr=self.prefs["bul_show_date_inscr"], + show_decisions=self.prefs["bul_show_decision"], + show_uevalid=self.prefs["bul_show_uevalid"], + show_mention=self.prefs["bul_show_mention"], + ) + + d.update(infos) # --- Rangs d[ "rang_nt" @@ -341,5 +364,6 @@ class BulletinBUT: d.update( sco_bulletins.get_appreciations_list(self.res.formsemestre.id, etud.id) ) - # XXX TODO A COMPLETER ? + d.update(sco_bulletins.make_context_dict(self.res.formsemestre, d["etud"])) + return d diff --git a/app/scodoc/sco_abs_notification.py b/app/scodoc/sco_abs_notification.py index f15e7d4c8..466d13df1 100644 --- a/app/scodoc/sco_abs_notification.py +++ b/app/scodoc/sco_abs_notification.py @@ -35,6 +35,7 @@ import datetime from flask import g, url_for from flask_mail import Message +from app.models.formsemestre import FormSemestre import app.scodoc.notesdb as ndb import app.scodoc.sco_utils as scu @@ -55,27 +56,30 @@ def abs_notify(etudid, date): """ from app.scodoc import sco_abs - sem = retreive_current_formsemestre(etudid, date) - if not sem: + formsemestre = retreive_current_formsemestre(etudid, date) + if not formsemestre: return # non inscrit a la date, pas de notification - nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem) - do_abs_notify(sem, etudid, date, nbabs, nbabsjust) + nbabs, nbabsjust = sco_abs.get_abs_count_in_interval( + etudid, formsemestre.date_debut.isoformat(), formsemestre.date_fin.isoformat() + ) + do_abs_notify(formsemestre, etudid, date, nbabs, nbabsjust) -def do_abs_notify(sem, etudid, date, nbabs, nbabsjust): +def do_abs_notify(formsemestre: FormSemestre, etudid, date, nbabs, nbabsjust): """Given new counts of absences, check if notifications are requested and send them.""" # prefs fallback to global pref if sem is None: - if sem: - formsemestre_id = sem["formsemestre_id"] + if formsemestre: + formsemestre_id = formsemestre.id else: formsemestre_id = None - prefs = sco_preferences.SemPreferences(formsemestre_id=sem["formsemestre_id"]) + prefs = sco_preferences.SemPreferences(formsemestre_id=formsemestre_id) destinations = abs_notify_get_destinations( - sem, prefs, etudid, date, nbabs, nbabsjust + formsemestre, prefs, etudid, date, nbabs, nbabsjust ) - msg = abs_notification_message(sem, prefs, etudid, nbabs, nbabsjust) + + msg = abs_notification_message(formsemestre, prefs, etudid, nbabs, nbabsjust) if not msg: return # abort @@ -131,19 +135,19 @@ def abs_notify_send(destinations, etudid, msg, nbabs, nbabsjust, formsemestre_id ) -def abs_notify_get_destinations(sem, prefs, etudid, date, nbabs, nbabsjust): +def abs_notify_get_destinations( + formsemestre: FormSemestre, prefs, etudid, date, nbabs, nbabsjust +) -> set: """Returns set of destination emails to be notified""" - formsemestre_id = sem["formsemestre_id"] destinations = [] # list of email address to notify - if abs_notify_is_above_threshold(etudid, nbabs, nbabsjust, formsemestre_id): - if sem and prefs["abs_notify_respsem"]: + if abs_notify_is_above_threshold(etudid, nbabs, nbabsjust, formsemestre.id): + if prefs["abs_notify_respsem"]: # notifie chaque responsable du semestre - for responsable_id in sem["responsables"]: - u = sco_users.user_info(responsable_id) - if u["email"]: - destinations.append(u["email"]) + for responsable in formsemestre.responsables: + if responsable.email: + destinations.append(responsable.email) if prefs["abs_notify_chief"] and prefs["email_chefdpt"]: destinations.append(prefs["email_chefdpt"]) if prefs["abs_notify_email"]: @@ -156,7 +160,7 @@ def abs_notify_get_destinations(sem, prefs, etudid, date, nbabs, nbabsjust): # Notification (à chaque fois) des resp. de modules ayant des évaluations # à cette date # nb: on pourrait prevoir d'utiliser un autre format de message pour ce cas - if sem and prefs["abs_notify_respeval"]: + if prefs["abs_notify_respeval"]: mods = mod_with_evals_at_date(date, etudid) for mod in mods: u = sco_users.user_info(mod["responsable_id"]) @@ -232,7 +236,9 @@ def user_nbdays_since_last_notif(email_addr, etudid): return None -def abs_notification_message(sem, prefs, etudid, nbabs, nbabsjust): +def abs_notification_message( + formsemestre: FormSemestre, prefs, etudid, nbabs, nbabsjust +): """Mime notification message based on template. returns a Message instance or None if sending should be canceled (empty template). @@ -242,7 +248,7 @@ def abs_notification_message(sem, prefs, etudid, nbabs, nbabsjust): etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] # Variables accessibles dans les balises du template: %(nom_variable)s : - values = sco_bulletins.make_context_dict(sem, etud) + values = sco_bulletins.make_context_dict(formsemestre, etud) values["nbabs"] = nbabs values["nbabsjust"] = nbabsjust @@ -264,9 +270,11 @@ def abs_notification_message(sem, prefs, etudid, nbabs, nbabsjust): return msg -def retreive_current_formsemestre(etudid, cur_date): +def retreive_current_formsemestre(etudid: int, cur_date) -> FormSemestre: """Get formsemestre dans lequel etudid est (ou était) inscrit a la date indiquée date est une chaine au format ISO (yyyy-mm-dd) + + Result: FormSemestre ou None si pas inscrit à la date indiquée """ req = """SELECT i.formsemestre_id FROM notes_formsemestre_inscription i, notes_formsemestre sem @@ -278,8 +286,8 @@ def retreive_current_formsemestre(etudid, cur_date): if not r: return None # s'il y a plusieurs semestres, prend le premier (rarissime et non significatif): - sem = sco_formsemestre.get_formsemestre(r[0]["formsemestre_id"]) - return sem + formsemestre = FormSemestre.query.get(r[0]["formsemestre_id"]) + return formsemestre def mod_with_evals_at_date(date_abs, etudid): diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py index 60cf4931d..6b1afc4a2 100644 --- a/app/scodoc/sco_bulletins.py +++ b/app/scodoc/sco_bulletins.py @@ -78,33 +78,20 @@ from app.scodoc import sco_bulletins_legacy from app.scodoc import sco_bulletins_ucac # format expérimental UCAC Cameroun -def make_context_dict(sem, etud): +def make_context_dict(formsemestre: FormSemestre, etud: dict) -> dict: """Construit dictionnaire avec valeurs pour substitution des textes (preferences bul_pdf_*) """ - C = sem.copy() - C["responsable"] = " ,".join( - [ - sco_users.user_info(responsable_id)["prenomnom"] - for responsable_id in sem["responsables"] - ] - ) - - annee_debut = sem["date_debut"].split("/")[2] - annee_fin = sem["date_fin"].split("/")[2] - if annee_debut != annee_fin: - annee = "%s - %s" % (annee_debut, annee_fin) - else: - annee = annee_debut - C["anneesem"] = annee + C = formsemestre.get_infos_dict() + C["responsable"] = formsemestre.responsables_str() + C["anneesem"] = C["annee"] # backward compat C.update(etud) # copie preferences - # XXX devrait acceder directement à un dict de preferences, à revoir for name in sco_preferences.get_base_preferences().prefs_name: - C[name] = sco_preferences.get_preference(name, sem["formsemestre_id"]) + C[name] = sco_preferences.get_preference(name, formsemestre.id) # ajoute groupes et group_0, group_1, ... - sco_groups.etud_add_group_infos(etud, sem) + sco_groups.etud_add_group_infos(etud, formsemestre.id) C["groupes"] = etud["groupes"] n = 0 for partition_id in etud["partitions"]: @@ -125,7 +112,8 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"): Le contenu du dictionnaire dépend des options (rangs, ...) et de la version choisie (short, long, selectedevals). - Cette fonction est utilisée pour les bulletins HTML et PDF, mais pas ceux en XML. + Cette fonction est utilisée pour les bulletins CLASSIQUES (DUT, ...) + en HTML et PDF, mais pas ceux en XML. """ from app.scodoc import sco_abs @@ -190,7 +178,7 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"): ) I["etud_etat"] = nt.get_etud_etat(etudid) I["filigranne"] = sco_bulletins_pdf.get_filigranne( - I["etud_etat"], prefs, decision_dem=I["decision_sem"] + I["etud_etat"], prefs, decision_sem=I["decision_sem"] ) I["demission"] = "" if I["etud_etat"] == scu.DEMISSION: @@ -384,7 +372,7 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"): I["matieres_modules"].update(_sort_mod_by_matiere(modules, nt, etudid)) # - C = make_context_dict(I["sem"], I["etud"]) + C = make_context_dict(formsemestre, I["etud"]) C.update(I) # # log( 'C = \n%s\n' % pprint.pformat(C) ) # tres pratique pour voir toutes les infos dispo @@ -842,7 +830,7 @@ def formsemestre_bulletinetud( H = [ _formsemestre_bulletinetud_header_html( - etud, etudid, sem, formsemestre_id, format, version + etud, etudid, formsemestre, format, version ), bulletin, ] @@ -1063,8 +1051,7 @@ def mail_bulletin(formsemestre_id, I, pdfdata, filename, recipient_addr): def _formsemestre_bulletinetud_header_html( etud, etudid, - sem, - formsemestre_id=None, + formsemestre: FormSemestre, format=None, version=None, ): @@ -1078,33 +1065,27 @@ def _formsemestre_bulletinetud_header_html( ], cssstyles=["css/radar_bulletin.css"], ), - """
-

%s

- """ - % ( + f"""
+

""" - % request.base_url, - f"""Bulletin {sem["titremois"]} -
""" - % sem, - """""", - """""" % time.strftime("%d/%m/%Y à %Hh%M"), - """
établi le %s (notes sur 20) - """ - % formsemestre_id, - """""" % etudid, - """""" % format, - """ + +
établi le {time.strftime("%d/%m/%Y à %Hh%M")} (notes sur 20) + + + +