diff --git a/app/models/assiduites.py b/app/models/assiduites.py
index 745dfdbb6..2b8742874 100644
--- a/app/models/assiduites.py
+++ b/app/models/assiduites.py
@@ -660,6 +660,24 @@ class Justificatif(ScoDocModel):
return assiduites_dejustifiees
+ def get_assiduites(self) -> Query:
+ """
+ get_assiduites Récupère les assiduités qui sont concernées par le justificatif
+ (Concernée ≠ Justifiée, mais qui sont sur la même période)
+ Ne prends pas en compte les Présences
+ Returns:
+ Query: Les assiduités concernées
+ """
+
+ assiduites_query = Assiduite.query.filter(
+ Assiduite.etudid == self.etudid,
+ Assiduite.date_debut >= self.date_debut,
+ Assiduite.date_fin <= self.date_fin,
+ Assiduite.etat != EtatAssiduite.PRESENT,
+ )
+
+ return assiduites_query
+
def is_period_conflicting(
date_debut: datetime,
diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py
index f17669e7b..9f1581dc3 100755
--- a/app/scodoc/sco_formsemestre_status.py
+++ b/app/scodoc/sco_formsemestre_status.py
@@ -25,8 +25,7 @@
#
##############################################################################
-"""Tableau de bord semestre
-"""
+"""Tableau de bord semestre"""
import datetime
@@ -1128,6 +1127,19 @@ def formsemestre_status(formsemestre_id=None, check_parcours=True):
_make_listes_sem(formsemestre),
"",
]
+
+ # --- Lien Traitement Justificatifs:
+
+ if current_user.has_permission(Permission.AbsJustifView):
+ H.append(
+ f"""
+
+ Traitement des justificatifs d'absence
+
"""
+ )
+
# --- Lien mail enseignants:
adrlist = list(mails_enseignants - {None, ""})
if adrlist:
diff --git a/app/static/css/assiduites.css b/app/static/css/assiduites.css
index d23a9ef4c..1cb99e386 100644
--- a/app/static/css/assiduites.css
+++ b/app/static/css/assiduites.css
@@ -756,4 +756,12 @@ tr.row-justificatif.non_valide td.assi-type {
var(--color-justi-attente-stripe) 4px,
var(--color-justi-attente) 4px,
var(--color-justi-attente) 7px) !important;
+}
+
+#gtrcontent .pdp {
+ display: none;
+}
+
+#gtrcontent[data-pdp="true"] .pdp {
+ display: block;
}
\ No newline at end of file
diff --git a/app/static/js/assiduites.js b/app/static/js/assiduites.js
index 8054f3de3..afcc29854 100644
--- a/app/static/js/assiduites.js
+++ b/app/static/js/assiduites.js
@@ -908,3 +908,19 @@ function setupAssiduiteBubble(el, assiduite) {
el.appendChild(bubble);
}
+
+/**
+ * Permet d'afficher ou non les photos des étudiants
+ * @param {boolean} checked
+ */
+function afficherPDP(checked) {
+ if (checked) {
+ gtrcontent.setAttribute("data-pdp", "true");
+ } else {
+ gtrcontent.removeAttribute("data-pdp");
+ }
+
+ // On sauvegarde le choix dans le localStorage
+ localStorage.setItem("scodoc-etud-pdp", `${checked}`);
+ pdp.checked = checked;
+}
diff --git a/app/templates/assiduites/pages/signal_assiduites_diff.j2 b/app/templates/assiduites/pages/signal_assiduites_diff.j2
index 120369fee..6847259e6 100644
--- a/app/templates/assiduites/pages/signal_assiduites_diff.j2
+++ b/app/templates/assiduites/pages/signal_assiduites_diff.j2
@@ -49,14 +49,6 @@
width: 10em;
}
- #gtrcontent .pdp {
- display: none;
- }
-
- #gtrcontent[data-pdp="true"] .pdp {
- display: block;
- }
-
#tableau-periode {
display: flex;
flex-direction: column;
@@ -142,22 +134,6 @@
+
+
+
+
+
+{% endblock %}
+
+{% block app_content %}
+
+Traitement des justificatifs {{formsemestre.titre_num()}}
+
+
+
+
+
+
+
+
+
+
Etudiant
+
Abs
+
Plage
+
Description
+
Fichiers
+
Validation
+
+
+ {% for ligne in lignes %}
+
+
+
+
{{ ligne.etud.nomprenom }}
+
+
+
+ NJ : {{ligne.etud.stats[0]}}
+
+
+ J : {{ligne.etud.stats[1]}}
+
+
+
+ {% if ligne.justif.date_debut.date() == ligne.justif.date_fin.date() %}
+
+ {{ligne.justif.date_debut.strftime("%d/%m/%y")}} de {{ligne.justif.date_debut.strftime("%Hh%M")}} à
+ {{ligne.justif.date_fin.strftime("%Hh%M")}}
+
+ {% else %}
+
+ du {{ligne.justif.date_debut.strftime("%d/%m/%y")}}
+
+
+ au {{ligne.justif.date_fin.strftime("%d/%m/%y")}}
+
+ {% endif %}
+
+ {{ligne.justif.entry_date.strftime("%d/%m/%y %Hh%M")}}
+
+ {% if ligne.assiduites.__len__() == 0 %}
+
Aucune assiduité concernée
+ {% else %}
+
+
+ Assiduités concernées
+
+
+ {% for assi in ligne.assiduites %}
+ -
+ {{scu.EtatAssiduite(assi.etat).version_lisible()}}
+ {% if assi.date_debut.date() == assi.date_fin.date() %}
+ du {{assi.date_debut.strftime("%d/%m/%y")}} de {{assi.date_debut.strftime("%Hh%M")}} à
+ {{assi.date_fin.strftime("%Hh%M")}}
+ {% else %}
+ du {{assi.date_debut.strftime("%d/%m/%y %Hh%M")}} au {{assi.date_fin.strftime("%d/%m/%y
+ %Hh%M")}}
+ {% endif %}
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+
+
{{ligne.justif.raison}}
+ {% if ligne.etat == "modifie" %}
+
le justificatif a été modifié
+ {% endif %}
+
+
+ {% if ligne.fichiers.total == 0 %}
+
Aucun fichier joint
+ {% else %}
+
+ Fichiers joints
+
+ {% for filename in ligne.fichiers.filenames %}
+ -
+ {{filename}}
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+ {% endfor %}
+
+
+{% include "assiduites/widgets/toast.j2" %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/app/templates/assiduites/widgets/toast.j2 b/app/templates/assiduites/widgets/toast.j2
index f7946f1bf..6081d227f 100644
--- a/app/templates/assiduites/widgets/toast.j2
+++ b/app/templates/assiduites/widgets/toast.j2
@@ -10,17 +10,18 @@
width: 20vw;
display: flex;
flex-direction: column;
- flex-wrap: wrap;
+ align-items: end;
transition: all 0.3s ease-in-out;
pointer-events: none;
z-index: 999;
+ overflow: hidden;
}
.toast {
margin: 0.5vh 0;
display: flex;
- width: 100%;
+ width: fit-content;
height: fit-content;
justify-content: flex-start;
align-items: center;
diff --git a/app/views/assiduites.py b/app/views/assiduites.py
index 08a5e2504..527d04043 100644
--- a/app/views/assiduites.py
+++ b/app/views/assiduites.py
@@ -2036,6 +2036,75 @@ def signale_evaluation_abs(etudid: int = None, evaluation_id: int = None):
)
+@bp.route("traitement_justificatifs")
+@scodoc
+@permission_required(Permission.AbsJustifView)
+def traitement_justificatifs():
+ """Page de traitement des justificatifs
+ On traite les justificatifs par formsemestre
+ On peut Valider, Invalider ou mettre en ATT
+ """
+ # Récupération du formsemestre
+ formsemestre_id: int = request.args.get("formsemestre_id", -1)
+ formsemestre: FormSemestre = FormSemestre.get_formsemestre(formsemestre_id)
+
+ lignes: list[dict] = []
+
+ # Récupération des justificatifs
+ justificatifs_query: Query = scass.filter_by_formsemestre(
+ Justificatif.query, Justificatif, formsemestre
+ )
+ justificatifs_query = justificatifs_query.filter(
+ Justificatif.etat.in_(
+ [scu.EtatJustificatif.ATTENTE, scu.EtatJustificatif.MODIFIE]
+ )
+ ).order_by(Justificatif.date_debut)
+
+ justif: Justificatif
+ for justif in justificatifs_query:
+ etud: Identite = justif.etudiant
+ assi_stats: tuple[int, int, int] = scass.get_assiduites_count(
+ etud.id, formsemestre.to_dict()
+ )
+ etud_dict: dict = {
+ "id": etud.id,
+ "nom": etud.nom,
+ "prenom": etud.prenom,
+ "nomprenom": etud.nomprenom,
+ "stats": assi_stats,
+ "sort_key": etud.sort_key,
+ }
+
+ assiduites_justifiees: list[Assiduite] = justif.get_assiduites().all()
+
+ # fichiers justificatifs archivés:
+ filenames, nb_files = justif.get_fichiers()
+ fichiers = {
+ "total": nb_files,
+ "filenames": filenames,
+ }
+
+ lignes.append(
+ {
+ "etud": etud_dict,
+ "justif": justif,
+ "assiduites": assiduites_justifiees,
+ "fichiers": fichiers,
+ "etat": scu.EtatJustificatif(justif.etat).name.lower(),
+ }
+ )
+
+ # Tri en fonction du nom des étudiants
+ lignes = sorted(lignes, key=lambda x: x["etud"]["sort_key"])
+
+ return render_template(
+ "assiduites/pages/traitement_justificatifs.j2",
+ formsemestre=formsemestre,
+ sco=ScoData(formsemestre=formsemestre),
+ lignes=lignes,
+ )
+
+
def generate_bul_list(etud: Identite, semestre: FormSemestre) -> str:
"""Génère la liste des assiduités d'un étudiant pour le bulletin mail"""