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"""
+ {code} |
+ {jury_stats["codes_annuels"][code]} |
+ {
+ (100*jury_stats["codes_annuels"][code] / jury_stats["nb_etuds"]):2.1f}%
+ |
+
"""
+ )
+ H.append(
+ f"""
+
+
{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 {