diff --git a/app/scodoc/sco_archives.py b/app/scodoc/sco_archives.py
index 5e09bf96..00e02c9d 100644
--- a/app/scodoc/sco_archives.py
+++ b/app/scodoc/sco_archives.py
@@ -344,7 +344,7 @@ def do_formsemestre_archive(
if data:
PVArchive.store(archive_id, "Tableau_moyennes" + scu.XLSX_SUFFIX, data)
# Tableau recap notes en HTML (pour tous les etudiants, n'utilise pas les groupes)
- table_html, _ = gen_formsemestre_recapcomplet_html_table(
+ table_html, _, _ = gen_formsemestre_recapcomplet_html_table(
formsemestre, res, include_evaluations=True
)
if table_html:
diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py
index 9ebe4e87..791fdb0f 100644
--- a/app/scodoc/sco_recapcomplet.py
+++ b/app/scodoc/sco_recapcomplet.py
@@ -27,6 +27,7 @@
"""Tableau récapitulatif des notes d'un semestre
"""
+import collections
import datetime
import time
from xml.etree import ElementTree
@@ -109,7 +110,7 @@ def formsemestre_recapcomplet(
force_publishing=force_publishing,
)
- table_html, table = _formsemestre_recapcomplet_to_html(
+ table_html, table, freq_codes_annuels = _formsemestre_recapcomplet_to_html(
formsemestre,
filename=filename,
mode_jury=mode_jury,
@@ -215,33 +216,37 @@ def formsemestre_recapcomplet(
"""
)
- if mode_jury and table and sum(table.freq_codes_annuels.values()) > 0:
+ if mode_jury and freq_codes_annuels and sum(freq_codes_annuels.values()) > 0:
+ nb_etud_avec_decision_annuelle = (
+ sum(freq_codes_annuels.values()) - freq_codes_annuels["total"]
+ )
H.append(
f"""
-
Nb d'étudiants avec décision annuelle:
- {sum(table.freq_codes_annuels.values())} / {len(table)}
+
Nb d'étudiants avec décision annuelle:
+ {nb_etud_avec_decision_annuelle} / {freq_codes_annuels["total"]}
-
Codes annuels octroyés:
-
"""
)
- for code in sorted(table.freq_codes_annuels.keys()):
+ if nb_etud_avec_decision_annuelle > 0:
H.append(
- f"""
- {code} |
- {table.freq_codes_annuels[code]} |
- {
- (100*table.freq_codes_annuels[code] / len(table)):2.1f}%
- |
-
"""
+ """Codes annuels octroyés:
+
+ """
)
- H.append(
- """
-
-
- """
- )
+ for code in sorted(freq_codes_annuels.keys()):
+ if code != "total":
+ H.append(
+ f"""
+ {code} |
+ {freq_codes_annuels[code]} |
+ {
+ (100*freq_codes_annuels[code] / freq_codes_annuels["total"]):2.1f}%
+ |
+
"""
+ )
+ H.append("""
""")
+ H.append("""
""")
# Légende
H.append(
"""
@@ -272,12 +277,12 @@ def _formsemestre_recapcomplet_to_html(
filename: str = "",
mode_jury=False, # saisie décisions jury
selected_etudid=None,
-) -> tuple[str, TableRecap]:
+) -> tuple[str, TableRecap, collections.Counter]:
"""Le tableau recap en html"""
if tabformat not in ("html", "evals"):
raise ScoValueError("invalid table format")
res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
- table_html, table = gen_formsemestre_recapcomplet_html_table(
+ table_html, table, freq_codes_annuels = gen_formsemestre_recapcomplet_html_table(
formsemestre,
res,
include_evaluations=(tabformat == "evals"),
@@ -285,7 +290,7 @@ def _formsemestre_recapcomplet_to_html(
filename=filename,
selected_etudid=selected_etudid,
)
- return table_html, table
+ return table_html, table, freq_codes_annuels
def _formsemestre_recapcomplet_to_file(
@@ -447,9 +452,9 @@ def gen_formsemestre_recapcomplet_html_table(
mode_jury=False,
filename="",
selected_etudid=None,
-) -> tuple[str, TableRecap]:
+) -> tuple[str, TableRecap, collections.Counter]:
"""Construit table recap pour le BUT
- Cache le résultat pour le semestre (sauf en mode jury).
+ Cache le résultat pour le semestre.
Note: on cache le HTML et non l'objet Table.
Si mode_jury, occultera colonnes modules (en js)
@@ -461,6 +466,7 @@ def gen_formsemestre_recapcomplet_html_table(
"""
table = None
table_html = None
+ table_html_cached = None
cache_class = {
(True, True): sco_cache.TableJuryWithEvalsCache,
(True, False): sco_cache.TableJuryCache,
@@ -468,8 +474,8 @@ def gen_formsemestre_recapcomplet_html_table(
(False, False): sco_cache.TableRecapCache,
}[(bool(mode_jury), bool(include_evaluations))]
if not selected_etudid:
- table_html = cache_class.get(formsemestre.id)
- if table_html is None:
+ table_html_cached = cache_class.get(formsemestre.id)
+ if table_html_cached is None:
table = _gen_formsemestre_recapcomplet_table(
res,
include_evaluations,
@@ -478,9 +484,14 @@ def gen_formsemestre_recapcomplet_html_table(
selected_etudid=selected_etudid,
)
table_html = table.html()
- cache_class.set(formsemestre.id, table_html)
+ freq_codes_annuels = (
+ table.freq_codes_annuels if hasattr(table, "freq_codes_annuels") else None
+ )
+ cache_class.set(formsemestre.id, (table_html, freq_codes_annuels))
+ else:
+ table_html, freq_codes_annuels = table_html_cached
- return table_html, table
+ return table_html, table, freq_codes_annuels
def _gen_formsemestre_recapcomplet_table(
diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css
index 4f922c9d..172e9008 100644
--- a/app/static/css/scodoc.css
+++ b/app/static/css/scodoc.css
@@ -2773,6 +2773,8 @@ table.notes_recapcomplet a:hover {
div.table_recap_caption {
width: fit-content;
+ margin-top: 8px;
+ margin-bottom: 8px;
padding: 8px;
border-radius: 8px;
background-color: rgb(202, 255, 180);
diff --git a/app/tables/jury_recap.py b/app/tables/jury_recap.py
index 8d02065c..3e6f5d24 100644
--- a/app/tables/jury_recap.py
+++ b/app/tables/jury_recap.py
@@ -78,6 +78,7 @@ class TableJury(TableRecap):
dec_rcue = deca.dec_rcue_by_ue.get(rcue.ue_1.id)
if dec_rcue is not None: # None si l'UE n'est pas associée à un niveau
row.add_rcue_cols(dec_rcue)
+ self.freq_codes_annuels["total"] = len(self.rows)
def add_jury(self):
"""Ajoute la colonne code jury et le lien.