diff --git a/app/but/jury_but.py b/app/but/jury_but.py index 9b1c5e8c..429f96a7 100644 --- a/app/but/jury_but.py +++ b/app/but/jury_but.py @@ -207,6 +207,19 @@ class DecisionsProposeesAnnee(DecisionsProposees): self.code_valide = self.validation.code self.parcour = None "Le parcours considéré (celui du semestre pair, ou à défaut impair)" + if self.formsemestre_pair is not None: + self.res_pair: ResultatsSemestreBUT = res_sem.load_formsemestre_results( + self.formsemestre_pair + ) + else: + self.res_pair = None + if self.formsemestre_impair is not None: + self.res_impair: ResultatsSemestreBUT = res_sem.load_formsemestre_results( + self.formsemestre_impair + ) + else: + self.res_impair = None + self.ues_impair, self.ues_pair = self.compute_ues_annee() # pylint: disable=all self.decisions_ues = { ue.id: DecisionsProposeesUE(etud, formsemestre_impair, ue) @@ -332,14 +345,14 @@ class DecisionsProposeesAnnee(DecisionsProposees): """ etudid = self.etud.id ues_sems = [] - for formsemestre in self.formsemestre_impair, self.formsemestre_pair: + for (formsemestre, res) in ( + (self.formsemestre_impair, self.res_impair), + (self.formsemestre_pair, self.res_pair), + ): if formsemestre is None: ues = [] else: formation: Formation = formsemestre.formation - res: ResultatsSemestreBUT = res_sem.load_formsemestre_results( - formsemestre - ) # Parcour dans lequel l'étudiant est inscrit, et liste des UEs if res.etuds_parcour_id[etudid] is None: # pas de parcour: prend toutes les UEs (non bonus) diff --git a/app/but/jury_but_recap.py b/app/but/jury_but_recap.py index e19d5fc3..346b89e5 100644 --- a/app/but/jury_but_recap.py +++ b/app/but/jury_but_recap.py @@ -11,6 +11,7 @@ import time from flask import g, url_for from app.but import jury_but +from app.but.jury_but import DecisionsProposeesAnnee from app.comp.res_but import ResultatsSemestreBUT from app.comp import res_sem from app.models.but_validations import RegroupementCoherentUE @@ -65,7 +66,7 @@ def formsemestre_saisie_jury_but( ) H = [ html_sco_header.sco_header( - page_title=f"{formsemestre2.sem_modalite()}: moyennes", + page_title=f"{formsemestre2.sem_modalite()}: jury BUT annuel", no_side_bar=True, init_qtip=True, javascripts=["js/etud_info.js", "js/table_recap.js"], @@ -123,6 +124,7 @@ class RowCollector: self.titles = titles self.row = cells or {} # col_id : str self.idx = 0 + self.last_etud_cell_idx = 0 if convert_values: self.fmt_note = scu.fmt_note else: @@ -175,6 +177,7 @@ class RowCollector: self["_nom_short_target_attrs"] = f'class="etudinfo" id="{etud.id}"' self["_nom_disp_target"] = self["_nom_short_target"] self["_nom_disp_target_attrs"] = self["_nom_short_target_attrs"] + self.last_etud_cell_idx = self.idx def add_ue_cell(self, ue: UniteEns, val): "cell de moyenne d'UE" @@ -196,18 +199,48 @@ class RowCollector: val = rcue.moy_rcue if isinstance(val, float): if val < BUT_BARRE_RCUE: - note_class = " moy_inf" + note_class = " moy_ue_inf" elif val >= BUT_BARRE_RCUE: note_class = " moy_ue_valid" if val < BUT_RCUE_SUFFISANT: note_class = " moy_ue_warning" # notes très basses self.add_cell( col_id, - f"{rcue.ue_1.acronyme}-{rcue.ue_2.acronyme}", + f"
{rcue.ue_1.acronyme}
{rcue.ue_2.acronyme}
", self.fmt_note(val), - "col_ue" + note_class, + "col_rcue" + note_class, ) + def add_nb_rcues_cell(self, deca: DecisionsProposeesAnnee): + "cell avec nb niveaux validables / total" + klass = " " + if deca.nb_rcues_under_8 > 0: + klass += "moy_ue_warning" + elif deca.nb_validables < deca.nb_competences: + klass += "moy_ue_inf" + else: + klass += "moy_ue_valid" + self.add_cell( + "rcues_validables", + "RCUEs", + f"""{deca.nb_validables}/{deca.nb_competences}""" + + ((" " + scu.EMO_WARNING) if deca.nb_rcues_under_8 > 0 else ""), + "col_rcue col_rcues_validables" + klass, + ) + if len(deca.rcues_annee) > 0: + # permet un tri par nb de niveaux validables + moyenne gen indicative S_pair + if deca.res_pair and deca.etud.id in deca.res_pair.etud_moy_gen: + moy_gen_d = f"{int(deca.res_pair.etud_moy_gen[deca.etud.id]*1000):05}" + else: + moy_gen_d = "x" + self["_rcues_validables_order"] = f"{deca.nb_validables:04d}-{moy_gen_d}" + else: + # etudiants sans RCUE: pas de semestre impair, ... + # les classe à la fin + self[ + "_rcues_validables_order" + ] = f"{deca.nb_validables:04d}-00000-{deca.etud.sort_key}" + def get_table_jury_but( formsemestre2: FormSemestre, readonly: bool = False @@ -221,7 +254,9 @@ def get_table_jury_but( deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre2) row = RowCollector(titles=titles) row.add_etud_cells(etud, formsemestre2) - + row.idx = 100 # laisse place pour les colonnes de groupes + # --- Nombre de niveaux + row.add_nb_rcues_cell(deca) # --- Les RCUEs for rcue in deca.rcues_annee: row.add_ue_cell(rcue.ue_1, rcue.moy_ue_1) @@ -251,7 +286,8 @@ def get_table_jury_but( """, ) rows.append(row.row) - res2.recap_add_partitions(rows, titles) + if len(rows) > 0: + res2.recap_add_partitions(rows, titles, col_idx=row.last_etud_cell_idx + 1) column_ids = [title for title in titles if not title.startswith("_")] column_ids.sort(key=lambda col_id: titles.get("_" + col_id + "_col_order", 1000)) rows.sort(key=lambda row: row["_nom_disp_order"]) diff --git a/app/comp/res_common.py b/app/comp/res_common.py index 722d4ecb..3b5f0896 100644 --- a/app/comp/res_common.py +++ b/app/comp/res_common.py @@ -829,7 +829,7 @@ class ResultatsSemestre(ResultatsCache): else: row[f"_{cid}_class"] = "admission" - def recap_add_partitions(self, rows: list[dict], titles: dict): + def recap_add_partitions(self, rows: list[dict], titles: dict, col_idx: int = None): """Ajoute les colonnes indiquant les groupes rows est une liste de dict avec une clé "etudid" Les colonnes ont la classe css "partition" @@ -838,7 +838,7 @@ class ResultatsSemestre(ResultatsCache): self.formsemestre.id ) first_partition = True - col_order = 10 + col_order = 10 if col_idx is None else col_idx for partition in partitions: cid = f"part_{partition['partition_id']}" rg_cid = cid + "_rg" # rang dans la partition diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 95e76fb2..6b41b761 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -2371,7 +2371,6 @@ td.recap_col_ue_inf { padding-right: 1.2em; padding-left: 4px; text-align: left; - font-weight: bold; color: rgb(255, 0, 0); border-left: 1px solid blue; } @@ -2380,7 +2379,6 @@ td.recap_col_ue_val { padding-right: 1.2em; padding-left: 4px; text-align: left; - font-weight: bold; color: rgb(0, 140, 0); border-left: 1px solid blue; } @@ -3773,6 +3771,19 @@ table.table_recap .group { border-left: 1px solid blue; } +table.table_recap .col_ue { + font-weight: bold; +} + +table.table_recap.jury .col_ue { + font-weight: normal; +} + +table.table_recap.jury .col_rcue { + font-weight: bold; +} + + table.table_recap .group { border-left: 1px dashed rgb(160, 160, 160); white-space: nowrap; @@ -3817,18 +3828,15 @@ table.table_recap td.moy_inf { } table.table_recap td.moy_ue_valid { - font-weight: bold; color: rgb(0, 140, 0); } table.table_recap td.moy_ue_warning { - font-weight: bold; color: rgb(255, 0, 0); } table.table_recap td.col_ues_validables { white-space: nowrap; - font-weight: bold; font-style: normal !important; }