diff --git a/app/but/jury_but_recap.py b/app/but/jury_but_recap.py index 0fafa02b..1a74f929 100644 --- a/app/but/jury_but_recap.py +++ b/app/but/jury_but_recap.py @@ -14,49 +14,23 @@ from app import db from app.but import jury_but from app.comp.res_but import ResultatsSemestreBUT from app.comp import res_sem +from app.models.but_validations import RegroupementCoherentUE from app.models.etudiants import Identite from app.models.formsemestre import FormSemestre from app.models.ues import UniteEns +from app.scodoc.sco_codes_parcours import ( + BUT_BARRE_RCUE, + BUT_BARRE_UE, + BUT_BARRE_UE8, + BUT_RCUE_SUFFISANT, +) from app.scodoc import sco_formsemestre_status from app.scodoc import html_sco_header from app.scodoc import sco_utils as scu from app.scodoc.sco_exceptions import ScoException, ScoValueError -class RowCollector: - def __init__(self, cells: dict = None, titles: dict = None): - self.titles = titles - self.row = cells or {} # col_id : str - self.idx = 0 - - def add_cell( - self, - col_id: str, - title: str, - content: str, - classes: str = "", - idx: int = None, - ): - "Add a row to our table. classes is a list of css class names" - self.idx = idx if idx is not None else self.idx - self.row[col_id] = content - if classes: - self.row[f"_{col_id}_class"] = classes + f" c{self.idx}" - if not col_id in self.titles: - self.titles[col_id] = title - self.titles[f"_{col_id}_col_order"] = self.idx - if classes: - self.titles[f"_{col_id}_class"] = classes - self.idx += 1 - - def __setitem__(self, key, value): - self.row[key] = value - - def __getitem__(self, key): - return self.row[key] - - def formsemestre_saisie_jury_but( formsemestre2: FormSemestre, readonly: bool = False ) -> str: @@ -140,6 +114,77 @@ def build_table_jury_but_html(filename: str, rows, titles, column_ids) -> str: return "".join(H) +class RowCollector: + """Une ligne de la table""" + + def __init__(self, cells: dict = None, titles: dict = None, convert_values=True): + self.titles = titles + self.row = cells or {} # col_id : str + self.idx = 0 + if convert_values: + self.fmt_note = scu.fmt_note + else: + self.fmt_note = lambda x: x + + def __setitem__(self, key, value): + self.row[key] = value + + def __getitem__(self, key): + return self.row[key] + + def add_cell( + self, + col_id: str, + title: str, + content: str, + classes: str = "", + idx: int = None, + ): + "Add a row to our table. classes is a list of css class names" + self.idx = idx if idx is not None else self.idx + self.row[col_id] = content + if classes: + self.row[f"_{col_id}_class"] = classes + f" c{self.idx}" + if not col_id in self.titles: + self.titles[col_id] = title + self.titles[f"_{col_id}_col_order"] = self.idx + if classes: + self.titles[f"_{col_id}_class"] = classes + self.idx += 1 + + def add_ue_cell(self, ue: UniteEns, val): + "cell de moyenne d'UE" + col_id = f"moy_ue_{ue.id}" + note_class = "" + if isinstance(val, float): + if val < BUT_BARRE_UE: + note_class = " moy_inf" + elif val >= BUT_BARRE_UE: + note_class = " moy_ue_valid" + if val < BUT_BARRE_UE8: + note_class = " moy_ue_warning" # notes très basses + self.add_cell(col_id, ue.acronyme, self.fmt_note(val), "col_ue" + note_class) + + def add_rcue_cell(self, rcue: RegroupementCoherentUE): + "cell de moyenne d'UE" + col_id = f"moy_rcue_{rcue.ue_1.niveau_competence_id}" # le niveau_id + note_class = "" + val = rcue.moy_rcue + if isinstance(val, float): + if val < BUT_BARRE_RCUE: + note_class = " moy_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_1.acronyme}", + self.fmt_note(val), + "col_ue" + note_class, + ) + + def get_table_jury_but( formsemestre2: FormSemestre, readonly: bool = False ) -> tuple[list[dict], list[str], list[str]]: @@ -156,7 +201,7 @@ def get_table_jury_but( # --- Codes (seront cachés, mais exportés en excel) row.add_cell("etudid", "etudid", etudid, "codes") row.add_cell("code_nip", "code_nip", etud.code_nip or "", "codes") - # --- Identité étudiant (adapté de res_comon/get_table_recap, à factoriser) + # --- Identité étudiant (adapté de res_comon/get_table_recap, à factoriser XXX TODO) row.add_cell("civilite_str", "Civ.", etud.civilite_str, "identite_detail") row.add_cell("nom_disp", "Nom", etud.nom_disp(), "identite_detail") row["_nom_disp_order"] = etud.sort_key @@ -172,7 +217,25 @@ def get_table_jury_but( row["_nom_short_target_attrs"] = f'class="etudinfo" id="{etudid}"' row["_nom_disp_target"] = row["_nom_short_target"] row["_nom_disp_target_attrs"] = row["_nom_short_target_attrs"] + # --- Les RCUEs + for rcue in deca.rcues_annee: + row.add_ue_cell(rcue.ue_1, rcue.moy_ue_1) + row.add_ue_cell(rcue.ue_2, rcue.moy_ue_2) + row.add_rcue_cell(rcue) + # Le lien de saisie + if not readonly: + row.add_cell( + "lien_saisie", + "", + f"""saisie décision + """, + ) rows.append(row.row) 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)) diff --git a/app/scodoc/sco_codes_parcours.py b/app/scodoc/sco_codes_parcours.py index b9e4943e..cfc44015 100644 --- a/app/scodoc/sco_codes_parcours.py +++ b/app/scodoc/sco_codes_parcours.py @@ -193,7 +193,8 @@ CODES_UE_VALIDES = {ADM: True, CMP: True} # UE validée # Pour le BUT: CODES_ANNEE_ARRET = {DEF, DEM, ABAN, ABL} CODES_RCUE = {ADM, AJ, CMP} -BUT_BARRE_RCUE = 10.0 - NOTES_TOLERANCE +BUT_BARRE_UE8 = 8.0 - NOTES_TOLERANCE +BUT_BARRE_UE = BUT_BARRE_RCUE = 10.0 - NOTES_TOLERANCE BUT_RCUE_SUFFISANT = 8.0 - NOTES_TOLERANCE