diff --git a/app/but/jury_but.py b/app/but/jury_but.py index f994544b11..6cc201b684 100644 --- a/app/but/jury_but.py +++ b/app/but/jury_but.py @@ -204,6 +204,7 @@ class DecisionsProposeesAnnee(DecisionsProposees): etud: Identite, formsemestre: FormSemestre, ): + assert formsemestre.formation.is_apc() super().__init__(etud=etud) self.formsemestre = formsemestre "le formsemestre utilisé pour construire ce deca" diff --git a/app/but/jury_but_recap.py b/app/but/jury_but_recap.py index 95e32855ac..e3c5df9c32 100644 --- a/app/but/jury_but_recap.py +++ b/app/but/jury_but_recap.py @@ -7,6 +7,7 @@ """Jury BUT: table recap annuelle et liens saisie """ +import collections import time import numpy as np from flask import g, url_for @@ -71,7 +72,7 @@ def formsemestre_saisie_jury_but( """ ) - rows, titles, column_ids = get_jury_but_table( + rows, titles, column_ids, jury_stats = get_jury_but_table( formsemestre2, read_only=read_only, mode=mode ) if not rows: @@ -153,6 +154,28 @@ def formsemestre_saisie_jury_but( f""" +
+
Nb d'étudiants avec décision annuelle: + {sum(jury_stats["codes_annuels"].values())} / {jury_stats["nb_etuds"]} +
+
Codes annuels octroyés:
+ + """ + ) + for code in sorted(jury_stats["codes_annuels"].keys()): + H.append( + f""" + + + + """ + ) + H.append( + f""" +
{code}{jury_stats["codes_annuels"][code]}{ + (100*jury_stats["codes_annuels"][code] / jury_stats["nb_etuds"]):2.1f}% +
+
{html_sco_header.sco_footer()} """ ) @@ -377,10 +400,17 @@ class RowCollector: def get_jury_but_table( formsemestre2: FormSemestre, read_only: bool = False, mode="jury", with_links=True -) -> tuple[list[dict], list[str], list[str]]: - """Construit la table des résultats annuels pour le jury BUT""" +) -> tuple[list[dict], list[str], list[str], dict]: + """Construit la table des résultats annuels pour le jury BUT + => rows_dict, titles, column_ids, jury_stats + où jury_stats est un dict donnant des comptages sur le jury. + """ res2: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre2) titles = {} # column_id : title + jury_stats = { + "nb_etuds": len(formsemestre2.etuds_inscriptions), + "codes_annuels": collections.Counter(), + } column_classes = {} rows = [] for etudid in formsemestre2.etuds_inscriptions: @@ -417,6 +447,8 @@ def get_jury_but_table( f"""{deca.code_valide or ''}""", "col_code_annee", ) + if deca.code_valide: + jury_stats["codes_annuels"][deca.code_valide] += 1 # --- Le lien de saisie if mode != "recap" and with_links: row.add_cell( @@ -446,7 +478,7 @@ def get_jury_but_table( 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_dict.sort(key=lambda row: row["_nom_disp_order"]) - return rows_dict, titles, column_ids + return rows_dict, titles, column_ids, jury_stats def get_jury_but_results(formsemestre: FormSemestre) -> list[dict]: diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 795901f035..c3e30a19a3 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -4171,6 +4171,30 @@ div.table_jury_but_links { margin-bottom: 16px; } + +/* ------------- Tableau stats jury BUT -------- */ +table.jury_stats_codes { + margin-top: 8px; + margin-left: 42px; + border: 3px solid #000000; + text-align: left; + border-collapse: collapse; +} + +table.jury_stats_codes td { + margin-right: 12px; + border-top: 1px solid #000000; + padding: 5px 8px; +} + +div.jury_stats { + background-color: #c7f6c7; + border-radius: 12px; + border: 1px solid black; + padding: 8px; + width: fit-content; +} + /* ------------- Tableau etat evals ------------ */ div.evaluations_recap table.evaluations_recap {