From 501d43f7096b2f265d6681e634e058b17b5fb68b Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Tue, 29 Mar 2022 00:03:38 +0200 Subject: [PATCH] Table recap: admission, partitions, ... --- app/comp/res_common.py | 87 ++++++++++++++++++++++++++++++++---- app/models/formsemestre.py | 3 ++ app/static/css/scodoc.css | 16 ++++++- app/static/js/table_recap.js | 26 +++++++++-- 4 files changed, 118 insertions(+), 14 deletions(-) diff --git a/app/comp/res_common.py b/app/comp/res_common.py index 839f6315..30468da3 100644 --- a/app/comp/res_common.py +++ b/app/comp/res_common.py @@ -397,7 +397,17 @@ class ResultatsSemestre(ResultatsCache): barre_valid_ue = self.formsemestre.formation.get_parcours().NOTES_BARRE_VALID_UE NO_NOTE = "-" # contenu des cellules sans notes rows = [] - titles = {"rang": "Rg"} # column_id : title + # column_id : title + titles = { + "rang": "Rg", + # ordre des colonnes: + "_rang_col_order": 1, + "_civilite_str_col_order": 2, + "_nom_disp_col_order": 3, + "_prenom_col_order": 4, + "_nom_short_col_order": 5, + "_rang_col_order": 6, + } # les titres en footer: les mêmes, mais avec des bulles et liens: titles_bot = {} @@ -436,7 +446,6 @@ class ResultatsSemestre(ResultatsCache): 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"] - self._recap_etud_groups_infos(etudid, row, titles) # --- Moyenne générale moy_gen = self.etud_moy_gen.get(etudid, False) note_class = "" @@ -523,7 +532,8 @@ class ResultatsSemestre(ResultatsCache): modimpl_ids.add(modimpl.id) rows.append(row) - + self._recap_add_partitions(rows, titles) + self._recap_add_admissions(rows, titles) # tri par rang croissant rows.sort(key=lambda e: e["_rang_order"]) @@ -547,12 +557,9 @@ class ResultatsSemestre(ResultatsCache): footer_rows.append(row) titles_bot.update(titles) footer_rows.append(titles_bot) - return ( - rows, - footer_rows, - titles, - [title for title in titles if not title.startswith("_")], - ) + column_ids = [title for title in titles if not title.startswith("_")] + column_ids.sort(key=lambda col_id: titles.get("_" + col_id + "_col_order", 100)) + return (rows, footer_rows, titles, column_ids) def _recap_bottom_infos(self, ues, modimpl_ids: set, fmt_note) -> dict: """Les informations à mettre en bas de la table: min, max, moy, ECTS""" @@ -631,3 +638,65 @@ class ResultatsSemestre(ResultatsCache): if row_class: row["_tr_class"] = " ".join([row.get("_tr_class", ""), row_class]) titles["group"] = "Gr" + + def _recap_add_admissions(self, rows: list[dict], titles: dict): + """Ajoute les colonnes "admission" + rows est une liste de dict avec un clé "etudid" + Les colonnes ont la classe css "admission" + """ + fields = { + "bac": "Bac", + "specialite": "Spécialité", + "type_admission": "Type Adm.", + "classement": "Rg. Adm.", + } + titles.update(fields) + for row in rows: + etud = Identite.query.get(row["etudid"]) + admission = etud.admission.first() + first = True + for cid in fields: + row[cid] = getattr(admission, cid) or "" + if first: + row[f"_{cid}_class"] = "admission admission_first" + first = False + else: + row[f"_{cid}_class"] = "admission" + titles[f"_{cid}_class"] = row[f"_{cid}_class"] + titles[f"_{cid}_col_order"] = 1000 # à la fin + + def _recap_add_partitions(self, rows: list[dict], titles: dict): + """Ajoute les colonnes indiquant les groupes + rows est une liste de dict avec un clé "etudid" + Les colonnes ont la classe css "partition" + """ + partitions, partitions_etud_groups = sco_groups.get_formsemestre_groups( + self.formsemestre.id + ) + first_partition = True + for partition in partitions: + cid = f"part_{partition['partition_id']}" + titles[cid] = partition["partition_name"] + if first_partition: + klass = "partition" + else: + klass = "partition partition_aux" + titles[f"_{cid}_class"] = klass + titles[f"_{cid}_col_order"] = 10 + partition_etud_groups = partitions_etud_groups[partition["partition_id"]] + for row in rows: + # dans NotesTableCompat, à revoir + etud_etat = self.get_etud_etat(row["etudid"]) + if etud_etat == "D": + gr_name = "Dém." + row["_tr_class"] = "dem" + elif etud_etat == DEF: + gr_name = "Déf." + row["_tr_class"] = "def" + else: + group = partition_etud_groups.get(row["etudid"]) + gr_name = group["group_name"] if group else "" + if gr_name: + row[f"{cid}"] = gr_name + row[f"_{cid}_class"] = klass + first_partition = False diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index 3b1c35d0..4ec90052 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -580,6 +580,9 @@ class FormSemestreInscription(db.Model): # etape apogee d'inscription (experimental 2020) etape = db.Column(db.String(APO_CODE_STR_LEN)) + def __repr__(self): + return f"<{self.__class__.__name__} {self.id} etudid={self.etudid} sem={self.formsemestre_id} etat={self.etat}>" + class NotesSemSet(db.Model): """semsets: ensemble de formsemestres pour exports Apogée""" diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 2196b4da..85c6574d 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -3178,7 +3178,13 @@ table.table_recap .group { border-left: 1px dashed rgb(160, 160, 160); white-space:nowrap; } - +table.table_recap .admission { + white-space:nowrap; + color:rgb(6, 73, 6); +} +table.table_recap .admission_first { + border-left: 1px solid blue; +} table.table_recap tbody tr td a:hover { color: red; text-decoration: underline; @@ -3215,4 +3221,12 @@ table.table_recap tr.max td, table.table_recap tr.moy td { font-size: 80%; padding-top: 3px; padding-bottom: 3px; +} +table.table_recap tr.dem td { + color: rgb(100,100,100); + font-style: italic; +} +table.table_recap tr.def td { + color: rgb(121, 74, 74); + font-style: italic; } \ No newline at end of file diff --git a/app/static/js/table_recap.js b/app/static/js/table_recap.js index 2b41cf5a..04acb30e 100644 --- a/app/static/js/table_recap.js +++ b/app/static/js/table_recap.js @@ -13,6 +13,15 @@ $(function () { dt.buttons('toggle_ident:name').text(visible ? "Civ/Nom/Prénom" : "Nom"); } }, + { + name: "toggle_partitions", + text: "Toutes les partitions", + action: function (e, dt, node, config) { + let visible = dt.columns(".partition_aux").visible()[0]; + dt.columns(".partition_aux").visible(!visible); + dt.buttons('toggle_partitions:name').text(visible ? "Toutes les partitions" : "Cacher les partitions"); + } + }, $('table.table_recap').hasClass("apc") ? { name: "toggle_res", @@ -44,6 +53,15 @@ $(function () { }) } + buttons.push({ + name: "toggle_admission", + text: "Montrer infos admission", + action: function (e, dt, node, config) { + let visible = dt.columns(".admission").visible()[0]; + dt.columns(".admission").visible(!visible); + dt.buttons('toggle_admission:name').text(visible ? "Montrer infos admission" : "Cacher infos admission"); + } + }) $('table.table_recap').DataTable( { paging: false, @@ -59,8 +77,8 @@ $(function () { colReorder: true, "columnDefs": [ { - // cache le détail de l'identité (pas réussi à le faire avec le sélecteur css) - "targets": [1, 2, 3], // ".identite_detail", + // cache le détail de l'identité et les colonnes admission + "targets": ["identite_detail", "partition_aux", "admission"], "visible": false, }, ], @@ -68,10 +86,10 @@ $(function () { buttons: ['copy', 'excel', 'pdf', { extend: 'collection', - text: 'Réglages affichage', + text: 'Colonnes affichées', autoClose: true, buttons: buttons, - } + }, ] } );