forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -449,7 +449,7 @@
|
|||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.assiduite-infos {
|
.assiduite-actions {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
|
@ -217,13 +217,11 @@ function creerLigneEtudiant(etud, index) {
|
|||||||
const nameField = document.createElement("div");
|
const nameField = document.createElement("div");
|
||||||
nameField.classList.add("name_field");
|
nameField.classList.add("name_field");
|
||||||
|
|
||||||
if ($("#pdp").is(":checked")) {
|
const pdp = document.createElement("img");
|
||||||
const pdp = document.createElement("img");
|
pdp.src = `../../api/etudiant/etudid/${etud.id}/photo?size=small`;
|
||||||
pdp.src = `../../api/etudiant/etudid/${etud.id}/photo?size=small`;
|
pdp.alt = `${etud.nom} ${etud.prenom}`;
|
||||||
pdp.alt = `${etud.nom} ${etud.prenom}`;
|
pdp.classList.add("pdp");
|
||||||
pdp.classList.add("pdp");
|
nameField.appendChild(pdp);
|
||||||
nameField.appendChild(pdp);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nameSet = document.createElement("a");
|
const nameSet = document.createElement("a");
|
||||||
nameSet.classList.add("name_set");
|
nameSet.classList.add("name_set");
|
||||||
@ -857,13 +855,25 @@ function setupAssiduiteBubble(el, assiduite) {
|
|||||||
|
|
||||||
// Ajout d'un lien pour plus d'informations
|
// Ajout d'un lien pour plus d'informations
|
||||||
const infos = document.createElement("a");
|
const infos = document.createElement("a");
|
||||||
infos.className = "assiduite-infos";
|
infos.className = "";
|
||||||
infos.textContent = `ℹ️`;
|
infos.textContent = `ℹ️`;
|
||||||
infos.title = "Cliquez pour plus d'informations";
|
infos.title = "Cliquez pour plus d'informations";
|
||||||
infos.target = "_blank";
|
infos.target = "_blank";
|
||||||
infos.href = `tableau_assiduite_actions?type=assiduite&action=details&obj_id=${assiduite.assiduite_id}`;
|
infos.href = `tableau_assiduite_actions?type=assiduite&action=details&obj_id=${assiduite.assiduite_id}`;
|
||||||
|
|
||||||
bubble.appendChild(infos);
|
// Ajout d'un lien pour modifier l'assiduité
|
||||||
|
const modifs = document.createElement("a");
|
||||||
|
modifs.className = "";
|
||||||
|
modifs.textContent = `📝`;
|
||||||
|
modifs.title = "Cliquez pour modifier l'assiduité";
|
||||||
|
modifs.target = "_blank";
|
||||||
|
modifs.href = `tableau_assiduite_actions?type=assiduite&action=modifier&obj_id=${assiduite.assiduite_id}`;
|
||||||
|
|
||||||
|
const actionsDiv = document.createElement("div");
|
||||||
|
actionsDiv.className = "assiduite-actions";
|
||||||
|
actionsDiv.appendChild(modifs);
|
||||||
|
actionsDiv.appendChild(infos);
|
||||||
|
bubble.appendChild(actionsDiv);
|
||||||
|
|
||||||
const idDiv = document.createElement("div");
|
const idDiv = document.createElement("div");
|
||||||
idDiv.className = "assiduite-id";
|
idDiv.className = "assiduite-id";
|
||||||
|
@ -391,11 +391,11 @@ class RowAssiJusti(tb.Row):
|
|||||||
multi_days = self.ligne["date_debut"].date() != self.ligne["date_fin"].date()
|
multi_days = self.ligne["date_debut"].date() != self.ligne["date_fin"].date()
|
||||||
|
|
||||||
date_affichees: list[str] = [
|
date_affichees: list[str] = [
|
||||||
self.ligne["date_debut"].strftime("%d/%m/%y de %H:%M"), # date début
|
self.ligne["date_debut"].strftime("%d/%m/%y %H:%M"), # date début
|
||||||
self.ligne["date_fin"].strftime("%d/%m/%y de %H:%M"), # date fin
|
self.ligne["date_fin"].strftime("%d/%m/%y %H:%M"), # date fin
|
||||||
]
|
]
|
||||||
|
|
||||||
if multi_days:
|
if multi_days and self.ligne["type"] != "justificatif":
|
||||||
date_affichees[0] = self.ligne["date_debut"].strftime("%d/%m/%y")
|
date_affichees[0] = self.ligne["date_debut"].strftime("%d/%m/%y")
|
||||||
date_affichees[1] = self.ligne["date_fin"].strftime("%d/%m/%y")
|
date_affichees[1] = self.ligne["date_fin"].strftime("%d/%m/%y")
|
||||||
|
|
||||||
|
@ -74,8 +74,6 @@ div.submit > input {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
{{ form.date_fin.label }} : {{ form.date_fin }}
|
{{ form.date_fin.label }} : {{ form.date_fin }}
|
||||||
<span class="help">si le jour de fin est différent,
|
|
||||||
les heures seront ignorées (journées complètes)</span>
|
|
||||||
{{ render_field_errors(form, 'date_fin') }}
|
{{ render_field_errors(form, 'date_fin') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#actions {
|
#actions {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 5px;
|
margin: 5px 0;
|
||||||
}
|
}
|
||||||
#actions label{
|
#actions label{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -174,6 +174,48 @@ async function nouvellePeriode(period = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vérification de la plage horaire
|
||||||
|
// On génère une date de début et de fin de la période
|
||||||
|
const date_debut = new Date(
|
||||||
|
$("#date").datepicker("getDate").format("YYYY-MM-DD") + "T" + debut
|
||||||
|
);
|
||||||
|
const date_fin = new Date(
|
||||||
|
$("#date").datepicker("getDate").format("YYYY-MM-DD") + "T" + fin
|
||||||
|
);
|
||||||
|
date_debut.add(1, "seconds");
|
||||||
|
|
||||||
|
// On vérifie que les dates sont valides
|
||||||
|
if (!date_debut.isValid()){
|
||||||
|
const p = document.createElement("p");
|
||||||
|
p.textContent = "La date de début n'est pas valide.";
|
||||||
|
openAlertModal(
|
||||||
|
"Erreur",
|
||||||
|
p,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!date_fin.isValid()){
|
||||||
|
const p = document.createElement("p");
|
||||||
|
p.textContent = "La date de fin n'est pas valide.";
|
||||||
|
openAlertModal(
|
||||||
|
"Erreur",
|
||||||
|
p,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On vérifie que l'heure de fin est supérieure à l'heure de début
|
||||||
|
if (date_debut >= date_fin) {
|
||||||
|
const p = document.createElement("p");
|
||||||
|
p.textContent = "La plage horaire n'est pas valide. L'heure de fin doit être "+
|
||||||
|
"supérieure à l'heure de début.";
|
||||||
|
openAlertModal(
|
||||||
|
"Erreur",
|
||||||
|
p,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// On ajoute la nouvelle période au tableau
|
// On ajoute la nouvelle période au tableau
|
||||||
let periodeDiv = document.createElement("div");
|
let periodeDiv = document.createElement("div");
|
||||||
periodeDiv.classList.add("cell", "header");
|
periodeDiv.classList.add("cell", "header");
|
||||||
@ -211,15 +253,6 @@ async function nouvellePeriode(period = null) {
|
|||||||
...document.querySelectorAll(".ligne[data-etudid]"),
|
...document.querySelectorAll(".ligne[data-etudid]"),
|
||||||
].map((e) => e.getAttribute("data-etudid"));
|
].map((e) => e.getAttribute("data-etudid"));
|
||||||
|
|
||||||
// On génère une date de début et de fin de la période
|
|
||||||
const date_debut = new Date(
|
|
||||||
$("#date").datepicker("getDate").format("YYYY-MM-DD") + "T" + debut
|
|
||||||
);
|
|
||||||
const date_fin = new Date(
|
|
||||||
$("#date").datepicker("getDate").format("YYYY-MM-DD") + "T" + fin
|
|
||||||
);
|
|
||||||
date_debut.add(1, "seconds");
|
|
||||||
|
|
||||||
// Préparation de la requête
|
// Préparation de la requête
|
||||||
const url =
|
const url =
|
||||||
`../../api/assiduites/group/query?date_debut=${date_debut.toFakeIso()}` +
|
`../../api/assiduites/group/query?date_debut=${date_debut.toFakeIso()}` +
|
||||||
|
@ -54,7 +54,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("pdp").addEventListener("change", (e) => {
|
document.getElementById("pdp").addEventListener("change", (e) => {
|
||||||
creerTousLesEtudiants(etuds);
|
afficherPDP(e.target.checked);
|
||||||
|
//creerTousLesEtudiants(etuds);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#date').on('change', async function(d) {
|
$('#date').on('change', async function(d) {
|
||||||
@ -87,6 +88,8 @@
|
|||||||
}
|
}
|
||||||
creerTousLesEtudiants(etuds);
|
creerTousLesEtudiants(etuds);
|
||||||
|
|
||||||
|
// affichage ou non des PDP
|
||||||
|
afficherPDP(localStorage.getItem("scodoc-etud-pdp") == "true" )
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(main, 0);
|
setTimeout(main, 0);
|
||||||
|
@ -83,6 +83,7 @@ table.semlist tbody tr td.modalite {
|
|||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
div.modalite {
|
div.modalite {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -147,6 +148,8 @@ span.effectif {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> b1055a4ebe841f17860d2556cc4b03aa12ec3ab1
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{# News #}
|
{# News #}
|
||||||
|
@ -299,7 +299,7 @@ def ajout_assiduite_etud() -> str | Response:
|
|||||||
|
|
||||||
def _get_dates_from_assi_form(
|
def _get_dates_from_assi_form(
|
||||||
form: AjoutAssiOrJustForm,
|
form: AjoutAssiOrJustForm,
|
||||||
all_day: bool = False,
|
from_justif: bool = False,
|
||||||
) -> tuple[
|
) -> tuple[
|
||||||
bool, datetime.datetime | None, datetime.datetime | None, datetime.datetime | None
|
bool, datetime.datetime | None, datetime.datetime | None, datetime.datetime | None
|
||||||
]:
|
]:
|
||||||
@ -327,32 +327,15 @@ def _get_dates_from_assi_form(
|
|||||||
date_fin = None
|
date_fin = None
|
||||||
form.set_error("date fin invalide", form.date_fin)
|
form.set_error("date fin invalide", form.date_fin)
|
||||||
|
|
||||||
if date_fin:
|
if not from_justif and date_fin:
|
||||||
# ignore les heures si plusieurs jours
|
# Ne prends pas en compte les heures pour les assiduités sur plusieurs jours
|
||||||
|
heure_debut = datetime.time.fromisoformat(debut_jour)
|
||||||
# Assiduité : garde les heures inscritent dans le formulaire
|
heure_fin = datetime.time.fromisoformat(fin_jour)
|
||||||
# Justificatif : ignore les heures inscrites dans le formulaire (0h -> 23h59)
|
|
||||||
|
|
||||||
heure_debut = (
|
|
||||||
datetime.time.fromisoformat(debut_jour)
|
|
||||||
if not all_day
|
|
||||||
else datetime.time(0, 0, 0)
|
|
||||||
) # 0h ou ConfigAssiduite.MorningTime
|
|
||||||
heure_fin = (
|
|
||||||
datetime.time.fromisoformat(fin_jour)
|
|
||||||
if not all_day
|
|
||||||
else datetime.time(23, 59, 59)
|
|
||||||
) # 23h59 ou ConfigAssiduite.AfternoonTime
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
if all_day:
|
heure_debut = datetime.time.fromisoformat(
|
||||||
heure_debut = datetime.time.fromisoformat(
|
form.heure_debut.data or debut_jour
|
||||||
form.heure_debut.data or "00:00"
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
heure_debut = datetime.time.fromisoformat(
|
|
||||||
form.heure_debut.data or debut_jour
|
|
||||||
)
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
form.set_error("heure début invalide", form.heure_debut)
|
form.set_error("heure début invalide", form.heure_debut)
|
||||||
if bool(form.heure_debut.data) != bool(form.heure_fin.data):
|
if bool(form.heure_debut.data) != bool(form.heure_fin.data):
|
||||||
@ -360,10 +343,7 @@ def _get_dates_from_assi_form(
|
|||||||
"Les deux heures début et fin doivent être spécifiées, ou aucune"
|
"Les deux heures début et fin doivent être spécifiées, ou aucune"
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
if all_day:
|
heure_fin = datetime.time.fromisoformat(form.heure_fin.data or fin_jour)
|
||||||
heure_fin = datetime.time.fromisoformat(form.heure_fin.data or "23:59")
|
|
||||||
else:
|
|
||||||
heure_fin = datetime.time.fromisoformat(form.heure_fin.data or fin_jour)
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
form.set_error("heure fin invalide", form.heure_fin)
|
form.set_error("heure fin invalide", form.heure_fin)
|
||||||
|
|
||||||
@ -398,6 +378,19 @@ def _get_dates_from_assi_form(
|
|||||||
# Ajoute time zone serveur
|
# Ajoute time zone serveur
|
||||||
dt_debut_tz_server = scu.TIME_ZONE.localize(dt_debut)
|
dt_debut_tz_server = scu.TIME_ZONE.localize(dt_debut)
|
||||||
dt_fin_tz_server = scu.TIME_ZONE.localize(dt_fin)
|
dt_fin_tz_server = scu.TIME_ZONE.localize(dt_fin)
|
||||||
|
|
||||||
|
if from_justif:
|
||||||
|
cas: list[bool] = [
|
||||||
|
# cas 1 (date de fin vide et pas d'heure de début)
|
||||||
|
not form.date_fin.data and not form.heure_debut.data,
|
||||||
|
# cas 2 (date de fin et pas d'heures)
|
||||||
|
form.date_fin.data != "" and not form.heure_debut.data,
|
||||||
|
]
|
||||||
|
|
||||||
|
if any(cas):
|
||||||
|
dt_debut_tz_server = dt_debut_tz_server.replace(hour=0, minute=0)
|
||||||
|
dt_fin_tz_server = dt_fin_tz_server.replace(hour=23, minute=59)
|
||||||
|
|
||||||
dt_entry_date_tz_server = (
|
dt_entry_date_tz_server = (
|
||||||
scu.TIME_ZONE.localize(dt_entry_date) if dt_entry_date else None
|
scu.TIME_ZONE.localize(dt_entry_date) if dt_entry_date else None
|
||||||
)
|
)
|
||||||
@ -753,6 +746,34 @@ def ajout_justificatif_etud():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _verif_date_form_justif(
|
||||||
|
form: AjoutJustificatifEtudForm, deb: datetime.datetime, fin: datetime.datetime
|
||||||
|
) -> tuple[datetime.datetime, datetime.datetime]:
|
||||||
|
"""Gère les cas suivants :
|
||||||
|
- si on indique seulement une date de debut : journée 0h-23h59
|
||||||
|
- si on indique date de debut et heures : journée +heure deb/fin
|
||||||
|
(déjà géré par _get_dates_from_assi_form)
|
||||||
|
- Si on indique une date de début et de fin sans heures : Journées 0h-23h59
|
||||||
|
- Si on indique une date de début et de fin avec heures : On fait un objet avec
|
||||||
|
datedeb/heuredeb + datefin/heurefin (déjà géré par _get_dates_from_assi_form)
|
||||||
|
"""
|
||||||
|
|
||||||
|
cas: list[bool] = [
|
||||||
|
# cas 1
|
||||||
|
not form.date_fin.data and not form.heure_debut.data,
|
||||||
|
# cas 3
|
||||||
|
form.date_fin.data != "" and not form.heure_debut.data,
|
||||||
|
]
|
||||||
|
|
||||||
|
if any(cas):
|
||||||
|
deb = deb.replace(hour=0, minute=0)
|
||||||
|
fin = fin.replace(hour=23, minute=59)
|
||||||
|
|
||||||
|
print(f"DEBUG {cas=}")
|
||||||
|
|
||||||
|
return deb, fin
|
||||||
|
|
||||||
|
|
||||||
def _record_justificatif_etud(
|
def _record_justificatif_etud(
|
||||||
etud: Identite, form: AjoutJustificatifEtudForm, justif: Justificatif | None = None
|
etud: Identite, form: AjoutJustificatifEtudForm, justif: Justificatif | None = None
|
||||||
) -> bool:
|
) -> bool:
|
||||||
@ -769,7 +790,7 @@ def _record_justificatif_etud(
|
|||||||
dt_debut_tz_server,
|
dt_debut_tz_server,
|
||||||
dt_fin_tz_server,
|
dt_fin_tz_server,
|
||||||
dt_entry_date_tz_server,
|
dt_entry_date_tz_server,
|
||||||
) = _get_dates_from_assi_form(form, all_day=True)
|
) = _get_dates_from_assi_form(form, from_justif=True)
|
||||||
if not ok:
|
if not ok:
|
||||||
log("_record_justificatif_etud: dates invalides")
|
log("_record_justificatif_etud: dates invalides")
|
||||||
form.set_error("Erreur: dates invalides")
|
form.set_error("Erreur: dates invalides")
|
||||||
@ -831,11 +852,6 @@ def _record_justificatif_etud(
|
|||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
return False
|
return False
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
# FIX TEMPORAIRE:
|
|
||||||
# on reprend toutes les assiduités et tous les justificatifs
|
|
||||||
# pour utiliser le "reset" (remise en "non_just") des assiduités
|
|
||||||
# (à terme, il faudrait ne recalculer que les assiduités impactées)
|
|
||||||
# VOIR TODO dans compute_assiduites_justified
|
|
||||||
justif.justifier_assiduites()
|
justif.justifier_assiduites()
|
||||||
scass.simple_invalidate_cache(justif.to_dict(), etud.id)
|
scass.simple_invalidate_cache(justif.to_dict(), etud.id)
|
||||||
flash(message)
|
flash(message)
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
SCOVERSION = "9.6.955"
|
SCOVERSION = "9.6.955"
|
||||||
|
=======
|
||||||
|
SCOVERSION = "9.6.954"
|
||||||
|
>>>>>>> b1055a4ebe841f17860d2556cc4b03aa12ec3ab1
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user