diff --git a/app/scodoc/sco_assiduites.py b/app/scodoc/sco_assiduites.py
index 96d128658..3bac97967 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 e9fdfc14c..413088477 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 000000000..250c884e7
--- /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 b78954eb8..d467879dd 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)
|