Bulletin JSON classique: format 'long_mat' avec matières. Closes #535

This commit is contained in:
Emmanuel Viennet 2022-11-26 00:02:30 +01:00
parent d48bcfa1d5
commit e58298969d
1 changed files with 152 additions and 111 deletions

View File

@ -36,6 +36,7 @@ from flask import abort
from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat
from app.models import but_validations
from app.models import Matiere, ModuleImpl, UniteEns
from app.models.etudiants import Identite
from app.models.formsemestre import FormSemestre
@ -50,6 +51,7 @@ from app.scodoc import sco_groups
from app.scodoc import sco_photos
from app.scodoc import sco_preferences
from app.scodoc import sco_etud
from app.scodoc.sco_preferences import SemPreferences
from app.scodoc.sco_xml import quote_xml_attr
# -------- Bulletin en JSON
@ -88,9 +90,21 @@ def formsemestre_bulletinetud_published_dict(
) -> dict:
"""Dictionnaire representant les informations _publiees_ du bulletin de notes
Utilisé pour JSON, devrait l'être aussi pour XML. (todo)
version:
short (sans les évaluations)
long (avec les évaluations)
short_mat (sans évaluations, et structuration en matières)
long_mat (avec évaluations, et structuration en matières)
"""
from app.scodoc import sco_bulletins
with_matieres = False
if version.endswith("_mat"):
version = version[:-4] # enlève le "_mat"
with_matieres = True
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
prefs = sco_preferences.SemPreferences(formsemestre_id)
etud = Identite.query.get(etudid)
@ -224,107 +238,41 @@ def formsemestre_bulletinetud_published_dict(
code_apogee=quote_xml_attr(ue["code_apogee"]),
)
d["ue"].append(u)
u["module"] = []
# Liste les modules de l'UE
ue_modimpls = [mod for mod in modimpls if mod["module"]["ue_id"] == ue["ue_id"]]
for modimpl in ue_modimpls:
mod_moy = scu.fmt_note(
nt.get_etud_mod_moy(modimpl["moduleimpl_id"], etudid)
if with_matieres:
u["module"] = []
# Structure UE/Matière/Module
# Recodé en 2022
ue = UniteEns.query.get(ue["ue_id"])
u["matiere"] = [
{
"matiere_id": mat.id,
"note": scu.fmt_note(nt.get_etud_mat_moy(mat.id, etudid)),
"titre": mat.titre,
"module": _list_modimpls(
nt,
etudid,
[
mod
for mod in modimpls
if mod["module"]["matiere_id"] == mat.id
],
prefs,
version,
),
}
for mat in ue.matieres.order_by(Matiere.numero)
]
else:
# Liste les modules de l'UE
u["module"] = _list_modimpls(
nt,
etudid,
[mod for mod in modimpls if mod["module"]["ue_id"] == ue["ue_id"]],
prefs,
version,
)
if mod_moy == "NI": # ne mentionne pas les modules ou n'est pas inscrit
continue
mod = modimpl["module"]
# if mod['ects'] is None:
# ects = ''
# else:
# ects = str(mod['ects'])
modstat = nt.get_mod_stats(modimpl["moduleimpl_id"])
m = dict(
id=modimpl["moduleimpl_id"],
code=mod["code"],
coefficient=mod["coefficient"],
numero=mod["numero"],
titre=quote_xml_attr(mod["titre"]),
abbrev=quote_xml_attr(mod["abbrev"]),
# ects=ects, ects des modules maintenant inutilisés
note=dict(value=mod_moy),
code_apogee=quote_xml_attr(mod["code_apogee"]),
matiere_id=mod["matiere_id"],
)
m["note"].update(modstat)
for k in ("min", "max", "moy"): # formatte toutes les notes
m["note"][k] = scu.fmt_note(m["note"][k])
u["module"].append(m)
if prefs["bul_show_mod_rangs"] and nt.mod_rangs is not None:
m["rang"] = dict(
value=nt.mod_rangs[modimpl["moduleimpl_id"]][0][etudid]
)
m["effectif"] = dict(value=nt.mod_rangs[modimpl["moduleimpl_id"]][1])
# --- notes de chaque eval:
evals = nt.get_evals_in_mod(modimpl["moduleimpl_id"])
m["evaluation"] = []
if version != "short":
for e in evals:
if e["visibulletin"] or version == "long":
val = e["notes"].get(etudid, {"value": "NP"})["value"]
# nb: val est NA si etud démissionnaire
val = scu.fmt_note(val, note_max=e["note_max"])
eval_dict = dict(
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=ndb.TimetoISO8601(
e["heure_debut"], null_is_empty=True
),
heure_fin=ndb.TimetoISO8601(
e["heure_fin"], null_is_empty=True
),
coefficient=e["coefficient"],
evaluation_type=e["evaluation_type"],
# CM : ajout pour permettre de faire le lien sur
# les bulletins en ligne avec l'évaluation:
evaluation_id=e["evaluation_id"],
description=quote_xml_attr(e["description"]),
note=val,
)
if prefs["bul_show_minmax_eval"] or prefs["bul_show_moypromo"]:
etat = sco_evaluations.do_evaluation_etat(
e["evaluation_id"]
)
if prefs["bul_show_minmax_eval"]:
eval_dict["min"] = scu.fmt_note(etat["mini"])
eval_dict["max"] = scu.fmt_note(etat["maxi"])
if prefs["bul_show_moypromo"]:
eval_dict["moy"] = scu.fmt_note(etat["moy"])
m["evaluation"].append(eval_dict)
# Evaluations incomplètes ou futures:
complete_eval_ids = set([e["evaluation_id"] for e in evals])
if prefs["bul_show_all_evals"]:
all_evals = sco_evaluation_db.do_evaluation_list(
args={"moduleimpl_id": modimpl["moduleimpl_id"]}
)
all_evals.reverse() # plus ancienne d'abord
for e in all_evals:
if e["evaluation_id"] not in complete_eval_ids:
m["evaluation"].append(
dict(
jour=ndb.DateDMYtoISO(
e["jour"], null_is_empty=True
),
heure_debut=ndb.TimetoISO8601(
e["heure_debut"], null_is_empty=True
),
heure_fin=ndb.TimetoISO8601(
e["heure_fin"], null_is_empty=True
),
coefficient=e["coefficient"],
description=quote_xml_attr(e["description"]),
incomplete="1",
)
)
# UE capitalisee (listee seulement si meilleure que l'UE courante)
if ue_status["is_capitalized"]:
@ -345,23 +293,15 @@ def formsemestre_bulletinetud_published_dict(
)
)
# --- Matières:
# for matiere_id in nt.moyennes_matieres:
d["matiere"] = [
{
"matiere_id": matiere_id,
"note": scu.fmt_note(nt.get_etud_mat_moy(matiere_id, etudid)),
}
for matiere_id in nt.moyennes_matieres
]
# --- Absences
if prefs["bul_show_abs"]:
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
d["absences"] = dict(nbabs=nbabs, nbabsjust=nbabsjust)
# --- Decision Jury
# --- Décision Jury
d.update(dict_decision_jury(etud, formsemestre, with_decisions=xml_with_decisions))
# --- Appreciations
# --- Appréciations
cnx = ndb.GetDBConnexion()
apprecs = sco_etud.appreciations_list(
cnx, args={"etudid": etudid, "formsemestre_id": formsemestre_id}
@ -379,6 +319,107 @@ def formsemestre_bulletinetud_published_dict(
return d
def _list_modimpls(
nt: NotesTableCompat,
etudid: int,
modimpls: list[ModuleImpl],
prefs: SemPreferences,
version: str,
) -> list[dict]:
modules_dict = []
for modimpl in modimpls:
mod_moy = scu.fmt_note(nt.get_etud_mod_moy(modimpl["moduleimpl_id"], etudid))
if mod_moy == "NI": # ne mentionne pas les modules ou n'est pas inscrit
continue
mod = modimpl["module"]
# if mod['ects'] is None:
# ects = ''
# else:
# ects = str(mod['ects'])
modstat = nt.get_mod_stats(modimpl["moduleimpl_id"])
mod_dict = dict(
id=modimpl["moduleimpl_id"],
code=mod["code"],
coefficient=mod["coefficient"],
numero=mod["numero"],
titre=quote_xml_attr(mod["titre"]),
abbrev=quote_xml_attr(mod["abbrev"]),
# ects=ects, ects des modules maintenant inutilisés
note=dict(value=mod_moy),
code_apogee=quote_xml_attr(mod["code_apogee"]),
matiere_id=mod["matiere_id"],
)
mod_dict["note"].update(modstat)
for k in ("min", "max", "moy"): # formatte toutes les notes
mod_dict["note"][k] = scu.fmt_note(mod_dict["note"][k])
if prefs["bul_show_mod_rangs"] and nt.mod_rangs is not None:
mod_dict["rang"] = dict(
value=nt.mod_rangs[modimpl["moduleimpl_id"]][0][etudid]
)
mod_dict["effectif"] = dict(value=nt.mod_rangs[modimpl["moduleimpl_id"]][1])
# --- notes de chaque eval:
evals = nt.get_evals_in_mod(modimpl["moduleimpl_id"])
mod_dict["evaluation"] = []
if version != "short":
for e in evals:
if e["visibulletin"] or version == "long":
val = e["notes"].get(etudid, {"value": "NP"})["value"]
# nb: val est NA si etud démissionnaire
val = scu.fmt_note(val, note_max=e["note_max"])
eval_dict = dict(
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=ndb.TimetoISO8601(
e["heure_debut"], null_is_empty=True
),
heure_fin=ndb.TimetoISO8601(e["heure_fin"], null_is_empty=True),
coefficient=e["coefficient"],
evaluation_type=e["evaluation_type"],
# CM : ajout pour permettre de faire le lien sur
# les bulletins en ligne avec l'évaluation:
evaluation_id=e["evaluation_id"],
description=quote_xml_attr(e["description"]),
note=val,
)
if prefs["bul_show_minmax_eval"] or prefs["bul_show_moypromo"]:
etat = sco_evaluations.do_evaluation_etat(e["evaluation_id"])
if prefs["bul_show_minmax_eval"]:
eval_dict["min"] = scu.fmt_note(etat["mini"])
eval_dict["max"] = scu.fmt_note(etat["maxi"])
if prefs["bul_show_moypromo"]:
eval_dict["moy"] = scu.fmt_note(etat["moy"])
mod_dict["evaluation"].append(eval_dict)
# Evaluations incomplètes ou futures:
complete_eval_ids = set([e["evaluation_id"] for e in evals])
if prefs["bul_show_all_evals"]:
all_evals = sco_evaluation_db.do_evaluation_list(
args={"moduleimpl_id": modimpl["moduleimpl_id"]}
)
all_evals.reverse() # plus ancienne d'abord
for e in all_evals:
if e["evaluation_id"] not in complete_eval_ids:
mod_dict["evaluation"].append(
dict(
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),
heure_debut=ndb.TimetoISO8601(
e["heure_debut"], null_is_empty=True
),
heure_fin=ndb.TimetoISO8601(
e["heure_fin"], null_is_empty=True
),
coefficient=e["coefficient"],
description=quote_xml_attr(e["description"]),
incomplete="1",
)
)
modules_dict.append(mod_dict)
return modules_dict
def dict_decision_jury(
etud: Identite, formsemestre: FormSemestre, with_decisions: bool = False
) -> dict: