From 06cbd65365d9f3606718603b56f37866deb75c92 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sat, 1 Oct 2022 18:55:32 +0200 Subject: [PATCH] =?UTF-8?q?Tableau=20bord=20module:=20avertissement=20si?= =?UTF-8?q?=20poids=20d'=C3=A9valuation=20nuls.=20D=C3=A9but=20de=20#411.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/evaluations.py | 17 +- app/scodoc/sco_moduleimpl_status.py | 606 +++++++++++++++------------- app/static/css/scodoc.css | 8 + 3 files changed, 348 insertions(+), 283 deletions(-) diff --git a/app/models/evaluations.py b/app/models/evaluations.py index a77d3f531..0cf036807 100644 --- a/app/models/evaluations.py +++ b/app/models/evaluations.py @@ -44,7 +44,9 @@ class Evaluation(db.Model): ues = db.relationship("UniteEns", secondary="evaluation_ue_poids", viewonly=True) def __repr__(self): - return f"""""" + return f"""""" def to_dict(self) -> dict: "Représentation dict, pour json" @@ -74,6 +76,17 @@ class Evaluation(db.Model): if k != "_sa_instance_state" and k != "id" and k in data: setattr(self, k, data[k]) + def descr_heure(self) -> str: + "Description de la plage horaire pour affichages" + if self.heure_debut and ( + not self.heure_fin or self.heure_fin == self.heure_debut + ): + return f"""à {self.heure_debut.strftime("%H:%M")}""" + elif self.heure_debut and self.heure_fin: + return f"""de {self.heure_debut.strftime("%H:%M")} à {self.heure_fin.strftime("%H:%M")}""" + else: + return "" + def clone(self, not_copying=()): """Clone, not copying the given attrs Attention: la copie n'a pas d'id avant le prochain commit @@ -164,7 +177,7 @@ class EvaluationUEPoids(db.Model): # Fonction héritée de ScoDoc7 à refactorer -def evaluation_enrich_dict(e): +def evaluation_enrich_dict(e: dict): """add or convert some fields in an evaluation dict""" # For ScoDoc7 compat heure_debut_dt = e["heure_debut"] or datetime.time( diff --git a/app/scodoc/sco_moduleimpl_status.py b/app/scodoc/sco_moduleimpl_status.py index 2a4a610c6..e91b62cc4 100644 --- a/app/scodoc/sco_moduleimpl_status.py +++ b/app/scodoc/sco_moduleimpl_status.py @@ -37,6 +37,7 @@ from app.comp import res_sem from app.comp.res_compat import NotesTableCompat from app.models import ModuleImpl from app.models.evaluations import Evaluation +from app.models.ues import UniteEns import app.scodoc.sco_utils as scu from app.scodoc.sco_exceptions import ScoInvalidIdType from app.scodoc.sco_cursus_dut import formsemestre_has_decisions @@ -337,8 +338,8 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None): group_id = sco_groups.get_default_group(formsemestre_id) H.append( f""" - Saisie Absences hebdo. @@ -350,7 +351,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None): if not modimpl.check_apc_conformity(): H.append( """
Les poids des évaluations de ce module ne sont - pas encore conformes au PN. + pas encore conformes au PN. Ses notes ne peuvent pas être prises en compte dans les moyennes d'UE.
""" ) @@ -425,272 +426,26 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None): H.append("""""") eval_index = len(mod_evals) - 1 first_eval = True - for eval in mod_evals: - evaluation: Evaluation = Evaluation.query.get( - eval["evaluation_id"] - ) # TODO unifier - etat = sco_evaluations.do_evaluation_etat( - eval["evaluation_id"], - partition_id=partition_id, - select_first_partition=True, + for eval_dict in mod_evals: + H.append( + _ligne_evaluation( + modimpl, + eval_dict, + first_eval=first_eval, + partition_id=partition_id, + arrow_down=arrow_down, + arrow_none=arrow_none, + arrow_up=arrow_up, + can_edit_evals=can_edit_evals, + can_edit_notes=can_edit_notes, + eval_index=eval_index, + has_expression=has_expression, + nb_evals=len(mod_evals), + ) ) - if eval["evaluation_type"] in ( - scu.EVALUATION_RATTRAPAGE, - scu.EVALUATION_SESSION2, - ): - tr_class = "mievr mievr_rattr" - else: - tr_class = "mievr" - tr_class_1 = "mievr" - if not first_eval: - H.append("""""") - tr_class_1 += " mievr_spaced" - H.append("""""") - H.append( - """""") - - H.append("""") - # - H.append( - """ -""" - % (eval["duree"], "%g" % eval["coefficient"]) - ) - H.append( - """ - - -""") - # - if etat["nb_notes"] == 0: - H.append("""""" % tr_class) - if modimpl.module.is_apc(): - H.append( - f"""""" - ) - else: - H.append('') - H.append("""""") - else: # il y a deja des notes saisies - gr_moyennes = etat["gr_moyennes"] - first_group = True - for gr_moyenne in gr_moyennes: - H.append("""""" % tr_class) - H.append("""""") - if first_group and modimpl.module.is_apc(): - H.append( - f"""""" - ) - else: - H.append("""""") - first_group = False - if gr_moyenne["group_name"] is None: - name = "Tous" # tous - else: - name = "Groupe %s" % gr_moyenne["group_name"] - H.append( - """""") first_eval = False - # - H.append(""" + f"""
 
""" % tr_class_1) - if eval["jour"]: - H.append("""Le %(jour)s%(descrheure)s""" % eval) - else: - H.append( - """Evaluation sans date""" - % eval - ) - H.append("    %(description)s" % eval) - if eval["evaluation_type"] == scu.EVALUATION_RATTRAPAGE: - H.append( - """rattrapage""" - ) - elif eval["evaluation_type"] == scu.EVALUATION_SESSION2: - H.append( - """session 2""" - ) - if etat["last_modif"]: - H.append( - """(dernière modif le %s)""" - % etat["last_modif"].strftime("%d/%m/%Y à %Hh%M") - ) - H.append('') - if has_expression or True: - H.append( - """%2d""" - % eval_index - ) - # Fleches: - H.append('') - if eval_index != (len(mod_evals) - 1) and can_edit_evals: - H.append( - '%s' - % (eval["evaluation_id"], arrow_up) - ) - else: - H.append(arrow_none) - if (eval_index > 0) and can_edit_evals: - H.append( - '%s' - % (eval["evaluation_id"], arrow_down) - ) - else: - H.append(arrow_none) - H.append("") - eval_index -= 1 - H.append("""
 DuréeCoef.NotesAbsNMoyenne """ - % tr_class - ) - - if etat["evalcomplete"]: - etat_txt = """(prise en compte)""" - etat_descr = "notes utilisées dans les moyennes" - elif eval["publish_incomplete"]: - etat_txt = """(prise en compte immédiate)""" - etat_descr = ( - "il manque des notes, mais la prise en compte immédiate a été demandée" - ) - elif etat["nb_notes"] != 0: - etat_txt = "(non prise en compte)" - etat_descr = "il manque des notes" - else: - etat_txt = "" - if can_edit_evals and etat_txt: - etat_txt = ( - '%s' - % (eval["evaluation_id"], etat_descr, etat_txt) - ) - H.append(etat_txt) - H.append("""
""" % tr_class) - if can_edit_evals: - H.append( - """%s""" - % ( - eval["evaluation_id"], - scu.icontag( - "edit_img", alt="modifier", title="Modifier informations" - ), - ) - ) - if can_edit_notes: - H.append( - """%s""" - % ( - eval["evaluation_id"], - scu.icontag( - "notes_img", alt="saisie notes", title="Saisie des notes" - ), - ) - ) - if etat["nb_notes"] == 0: - if can_edit_evals: - H.append( - """""" - % eval - ) - H.append(scu.icontag("delete_img", alt="supprimer", title="Supprimer")) - if can_edit_evals: - H.append("""""") - elif etat["evalcomplete"]: - H.append( - """%s""" - % (eval["evaluation_id"], scu.icontag("status_green_img", title="ok")) - ) - else: - if etat["evalattente"]: - H.append( - """%s""" - % ( - eval["evaluation_id"], - scu.icontag( - "status_greenorange_img", - file_format="gif", - title="notes en attente", - ), - ) - ) - else: - H.append( - """%s""" - % ( - eval["evaluation_id"], - scu.icontag("status_orange_img", title="il manque des notes"), - ) - ) - # - if eval["visibulletin"]: - H.append( - scu.icontag( - "status_visible_img", title="visible dans bulletins intermédiaires" - ) - ) - else: - H.append(" ") - H.append('') - if can_edit_notes: - H.append( - moduleimpl_evaluation_menu( - eval["evaluation_id"], - nbnotes=etat["nb_notes"], - ) - ) - H.append("%s%s%(nb_notes)s / %(nb_inscrits)s%(nb_abs)s%(nb_neutre)s""" - % etat - ) - if etat["moy"]: - H.append("%s / %g" % (etat["moy"], eval["note_max"])) - H.append( - """  (afficher)""" - % (eval["evaluation_id"],) - ) - else: - H.append( - """saisir notes""" - % (eval["evaluation_id"]) - ) - H.append("""
{ - evaluation.get_ue_poids_str()}
 { - evaluation.get_ue_poids_str()}%s  """ % name - ) - if gr_moyenne["gr_nb_notes"] > 0: - H.append("%(gr_moy)s" % gr_moyenne) - H.append( - """  (%s notes""" - % ( - eval["evaluation_id"], - gr_moyenne["group_id"], - gr_moyenne["gr_nb_notes"], - ) - ) - if gr_moyenne["gr_nb_att"] > 0: - H.append( - """, %s en attente""" - % gr_moyenne["gr_nb_att"] - ) - H.append(""")""") - if gr_moyenne["group_id"] in etat["gr_incomplets"]: - H.append("""[""") - if can_edit_notes: - H.append( - """incomplet]""" - % (eval["evaluation_id"], gr_moyenne["group_id"]) - ) - else: - H.append("""incomplet]""") - else: - H.append("""  """) - if can_edit_notes: - H.append( - """""" - % (eval["evaluation_id"], gr_moyenne["group_id"]) - ) - H.append("pas de notes") - if can_edit_notes: - H.append("""""") - H.append("") - H.append("""
""") if sem_locked: H.append(f"""{scu.icontag("lock32_img")} semestre verrouillé""") @@ -698,7 +453,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None): H.append(top_table_links) H.append( - """
@@ -707,25 +462,314 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):

Légende

    -
  • %s : modifie description de l'évaluation (date, heure, coefficient, ...)
  • -
  • %s : saisie des notes
  • -
  • %s : indique qu'il n'y a aucune note entrée (cliquer pour supprimer cette évaluation)
  • -
  • %s : indique qu'il manque quelques notes dans cette évaluation
  • -
  • %s : toutes les notes sont entrées (cliquer pour les afficher)
  • -
  • %s : indique que cette évaluation sera mentionnée dans les bulletins au format "intermédiaire" +
  • {scu.icontag("edit_img")} : modifie description de l'évaluation + (date, heure, coefficient, ...) +
  • +
  • {scu.icontag("notes_img")} : saisie des notes
  • +
  • {scu.icontag("delete_img")} : indique qu'il n'y a aucune note + entrée (cliquer pour supprimer cette évaluation) +
  • +
  • {scu.icontag("status_orange_img")} : indique qu'il manque + quelques notes dans cette évaluation +
  • +
  • {scu.icontag("status_green_img")} : toutes les notes sont + entrées (cliquer pour les afficher) +
  • +
  • {scu.icontag("status_visible_img")} : indique que cette évaluation + sera mentionnée dans les bulletins au format "intermédiaire" +
-

Rappel : seules les notes des évaluations complètement saisies (affichées en vert) apparaissent dans les bulletins. +

Rappel : seules les notes des évaluations complètement saisies + (affichées en vert) apparaissent dans les bulletins.

""" - % ( - scu.icontag("edit_img"), - scu.icontag("notes_img"), - scu.icontag("delete_img"), - scu.icontag("status_orange_img"), - scu.icontag("status_green_img"), - scu.icontag("status_visible_img"), - ) ) H.append(html_sco_header.sco_footer()) return "".join(H) + + +def _ligne_evaluation( + modimpl: ModuleImpl, + eval_dict: dict, + first_eval: bool = True, + partition_id=None, + arrow_down=None, + arrow_none=None, + arrow_up=None, + can_edit_evals: bool = False, + can_edit_notes: bool = False, + eval_index: int = 0, + has_expression: bool = False, + nb_evals: int = 0, +) -> str: + """Ligne décrivant une évaluation dans le tableau de bord moduleimpl.""" + H = [] + # TODO unifier pour ne plus utiliser eval_dict + evaluation: Evaluation = Evaluation.query.get(eval_dict["evaluation_id"]) + etat = sco_evaluations.do_evaluation_etat( + evaluation.id, + partition_id=partition_id, + select_first_partition=True, + ) + if evaluation.evaluation_type in ( + scu.EVALUATION_RATTRAPAGE, + scu.EVALUATION_SESSION2, + ): + tr_class = "mievr mievr_rattr" + else: + tr_class = "mievr" + tr_class_1 = "mievr" + if not first_eval: + H.append(""" """) + tr_class_1 += " mievr_spaced" + H.append(f"""""") + if evaluation.jour: + H.append( + f"""Le {evaluation.jour.strftime("%d/%m/%Y")} {evaluation.descr_heure()}""" + ) + else: + H.append( + f"""Évaluation sans date""" + ) + H.append(f"    {evaluation.description or ''}") + if evaluation.evaluation_type == scu.EVALUATION_RATTRAPAGE: + H.append( + """rattrapage""" + ) + elif evaluation.evaluation_type == scu.EVALUATION_SESSION2: + H.append( + """session 2""" + ) + # Avertissement si coefs/poids nuls + if ( + evaluation.coefficient * sum(evaluation.get_ue_poids_dict().values()) + < scu.NOTES_PRECISION + ): + H.append("""coef. nul !""") + # + if etat["last_modif"]: + H.append( + f"""(dernière modif le { + etat["last_modif"].strftime("%d/%m/%Y à %Hh%M")})""" + ) + # + H.append('') + if has_expression or True: + H.append( + f"""{ + eval_index:2}""" + ) + # Fleches: + H.append('') + if eval_index != (nb_evals - 1) and can_edit_evals: + H.append( + '%s' + % (evaluation.id, arrow_up) + ) + else: + H.append(arrow_none) + if (eval_index > 0) and can_edit_evals: + H.append( + '%s' + % (evaluation.id, arrow_down) + ) + else: + H.append(arrow_none) + + H.append( + f""" + + +   + Durée + Coef. + Notes + Abs + N + Moyenne """ + ) + + if etat["evalcomplete"]: + etat_txt = """(prise en compte)""" + etat_descr = "notes utilisées dans les moyennes" + elif eval_dict["publish_incomplete"]: + etat_txt = """(prise en compte immédiate)""" + etat_descr = ( + "il manque des notes, mais la prise en compte immédiate a été demandée" + ) + elif etat["nb_notes"] != 0: + etat_txt = "(non prise en compte)" + etat_descr = "il manque des notes" + else: + etat_txt = "" + if can_edit_evals and etat_txt: + etat_txt = f"""{etat_txt}""" + + H.append( + f"""{etat_txt} + + """ + ) + if can_edit_evals: + H.append( + f"""{scu.icontag("edit_img", alt="modifier", title="Modifier informations")}""" + ) + if can_edit_notes: + H.append( + f"""{scu.icontag("notes_img", alt="saisie notes", title="Saisie des notes")}""" + ) + if etat["nb_notes"] == 0: + if can_edit_evals: + H.append( + f"""""" + ) + H.append(scu.icontag("delete_img", alt="supprimer", title="Supprimer")) + if can_edit_evals: + H.append("""""") + elif etat["evalcomplete"]: + H.append( + f"""{scu.icontag("status_green_img", title="ok")}""" + ) + else: + if etat["evalattente"]: + H.append( + f"""{scu.icontag( + "status_greenorange_img", + file_format="gif", + title="notes en attente", + )}""" + ) + else: + H.append( + f"""{scu.icontag("status_orange_img", title="il manque des notes")}""" + ) + # + if eval_dict["visibulletin"]: + H.append( + scu.icontag( + "status_visible_img", title="visible dans bulletins intermédiaires" + ) + ) + else: + H.append(" ") + H.append('') + if can_edit_notes: + H.append( + moduleimpl_evaluation_menu( + evaluation.id, + nbnotes=etat["nb_notes"], + ) + ) + # + H.append( + """ +%s%s""" + % (eval_dict["duree"], "%g" % eval_dict["coefficient"]) + ) + H.append( + """%(nb_notes)s / %(nb_inscrits)s +%(nb_abs)s +%(nb_neutre)s +""" + % etat + ) + if etat["moy"]: + H.append("%s / %g" % (etat["moy"], eval_dict["note_max"])) + H.append( + f"""  (afficher)""" + ) + else: + H.append( + f"""saisir notes + """ + ) + H.append("""""") + # + if etat["nb_notes"] == 0: + H.append(f"""""") + if modimpl.module.is_apc(): + H.append( + f"""{ + evaluation.get_ue_poids_str()}""" + ) + else: + H.append('') + H.append("""""") + else: # il y a deja des notes saisies + gr_moyennes = etat["gr_moyennes"] + first_group = True + for gr_moyenne in gr_moyennes: + H.append(f""" """) + if first_group and modimpl.module.is_apc(): + H.append( + f"""{ + evaluation.get_ue_poids_str()}""" + ) + else: + H.append("""""") + first_group = False + if gr_moyenne["group_name"] is None: + name = "Tous" # tous + else: + name = f"""Groupe {gr_moyenne["group_name"]}""" + H.append(f"""{name}  """) + if gr_moyenne["gr_nb_notes"] > 0: + H.append( + f"""{gr_moyenne["gr_moy"]}  ({gr_moyenne["gr_nb_notes"]} notes""" + ) + if gr_moyenne["gr_nb_att"] > 0: + H.append( + f""", {gr_moyenne["gr_nb_att"]} en attente""" + ) + H.append(""")""") + if gr_moyenne["group_id"] in etat["gr_incomplets"]: + H.append("""[""") + if can_edit_notes: + H.append( + f"""incomplet]""" + ) + else: + H.append("""incomplet]""") + else: + H.append("""  """) + if can_edit_notes: + H.append( + f"""""") + H.append("") + H.append("""""") + return "\n".join(H) diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index ce001b544..0d62e3eb5 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -1862,6 +1862,14 @@ a.mievr_evalnodate:hover { text-decoration: underline; } +span.eval_warning_coef { + color: red; + margin: 2px; + padding-left: 3px; + padding-right: 3px; + background-color: rgb(255, 225, 0); +} + span.evalindex_cont { float: right; }