From 332600128968d5b9496c4a4f129d654c0969e62f Mon Sep 17 00:00:00 2001 From: iziram Date: Mon, 10 Jul 2023 17:38:50 +0200 Subject: [PATCH] =?UTF-8?q?Assiduites=20:=20Visualisation=20des=20assiduit?= =?UTF-8?q?=C3=A9s=20d'un=20groupe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scodoc/sco_assiduites.py | 1 + app/scodoc/sco_formsemestre_status.py | 8 +- app/tables/visu_assiduites.py | 146 ++++++++++++++++++++ app/templates/assiduites/pages/visu_assi.j2 | 29 ++++ app/views/assiduites.py | 56 ++++++++ 5 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 app/tables/visu_assiduites.py create mode 100644 app/templates/assiduites/pages/visu_assi.j2 diff --git a/app/scodoc/sco_assiduites.py b/app/scodoc/sco_assiduites.py index 96d12865..3bac9796 100644 --- a/app/scodoc/sco_assiduites.py +++ b/app/scodoc/sco_assiduites.py @@ -126,6 +126,7 @@ class CountCalculator: self.add_half_day(period[0].date()) while pointer_date < assi.date_fin.date(): + # TODO : Utiliser la préférence de département : workdays if pointer_date.weekday() < (6 - self.skip_saturday): self.add_day(pointer_date) self.add_half_day(pointer_date) diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index e9fdfc14..41308847 100755 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -835,11 +835,11 @@ def _make_listes_sem(formsemestre: FormSemestre, with_absences=True): first_monday = sco_abs.ddmmyyyy( formsemestre.date_debut.strftime("%d/%m/%Y") ).prev_monday() - form_abs_tmpl = """ - + form_abs_tmpl = f""" + """ form_abs_tmpl += f""" dict[str, list[str, float, float]]: + retour: dict[str, tuple[str, float, float]] = { + "present": ["Présence(s)", 0.0, 0.0], + "retard": ["Retard(s)", 0.0, 0.0], + "absent": ["Absence(s)", 0.0, 0.0], + } + + assi_metric = { + "H.": "heure", + "J.": "journee", + "1/2 J.": "demi", + }.get(sco_preferences.get_preference("assi_metrique", dept_id=g.scodoc_dept_id)) + + for etat, valeur in retour.items(): + compte_etat = scass.get_assiduites_stats( + assiduites=etud.assiduites, + metric=assi_metric, + filtered={ + "date_debut": self.dates[0], + "date_fin": self.dates[1], + "etat": etat, + }, + ) + + compte_etat_just = scass.get_assiduites_stats( + assiduites=etud.assiduites, + metric=assi_metric, + filtered={ + "date_debut": self.dates[0], + "date_fin": self.dates[1], + "etat": etat, + "est_just": True, + }, + ) + + valeur[1] = compte_etat[assi_metric] + valeur[2] = compte_etat_just[assi_metric] + return retour + + +def etuds_sorted_from_ids(etudids) -> list[Identite]: + "Liste triée d'etuds à partir d'une collections d'etudids" + etuds = [Identite.get_etud(etudid) for etudid in etudids] + return sorted(etuds, key=lambda etud: etud.sort_key) diff --git a/app/templates/assiduites/pages/visu_assi.j2 b/app/templates/assiduites/pages/visu_assi.j2 new file mode 100644 index 00000000..250c884e --- /dev/null +++ b/app/templates/assiduites/pages/visu_assi.j2 @@ -0,0 +1,29 @@ +

Visualisation de l'assiduité {{gr_tit|safe}}

+ +
+ + + +
+ +{{tableau | safe}} + + \ No newline at end of file diff --git a/app/views/assiduites.py b/app/views/assiduites.py index b78954eb..d467879d 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -26,6 +26,8 @@ from flask_login import current_user from app.scodoc import sco_utils as scu from app.scodoc import sco_assiduites as scass +from app.tables.visu_assiduites import TableAssi, etuds_sorted_from_ids + CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS @@ -639,6 +641,60 @@ def get_etat_abs_date(): ).build() +@bp.route("/VisualisationAssiduitesGroupe") +@scodoc +@permission_required(Permission.ScoView) +def visu_assi_group(): + dates = { + "debut": request.args.get("date_debut"), + "fin": request.args.get("date_fin"), + } + + group_ids: list[int] = request.args.get("group_ids", None) + etudiants: list[dict] = [] + + if group_ids is None: + group_ids = [] + else: + group_ids = group_ids.split(",") + map(str, group_ids) + + groups_infos = sco_groups_view.DisplayedGroupsInfos(group_ids) + + etuds = etuds_sorted_from_ids([m["etudid"] for m in groups_infos.members]) + + header: str = html_sco_header.sco_header( + page_title="Visualisation des assiduités", + init_qtip=True, + ) + + table: TableAssi = TableAssi(etuds=etuds, dates=list(dates.values())) + + if groups_infos.tous_les_etuds_du_sem: + gr_tit = "en" + else: + if len(groups_infos.group_ids) > 1: + grp = "des groupes" + else: + grp = "du groupe" + gr_tit = ( + grp + ' ' + groups_infos.groups_titles + "" + ) + + return HTMLBuilder( + header, + render_template( + "assiduites/pages/visu_assi.j2", + tableau=table.html(), + gr_tit=gr_tit, + date_debut=dates["debut"], + date_fin=dates["fin"], + group_ids=request.args.get("group_ids", None), + ), + html_sco_header.sco_footer(), + ).build() + + @bp.route("/SignalAssiduiteDifferee") @scodoc @permission_required(Permission.ScoAssiduiteChange)