Merge branch 'main96' of https://scodoc.org/git/iziram/ScoDoc into iziram-main96
This commit is contained in:
commit
2f2e25171e
|
@ -3,14 +3,15 @@
|
||||||
# Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved.
|
# Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved.
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
"""ScoDoc 9 API : Assiduités
|
"""ScoDoc 9 API : Assiduités"""
|
||||||
"""
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
from flask_json import as_json
|
from flask_json import as_json
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
from flask_sqlalchemy.query import Query
|
from flask_sqlalchemy.query import Query
|
||||||
|
from sqlalchemy.orm.exc import ObjectDeletedError
|
||||||
|
|
||||||
from app import db, log, set_sco_dept
|
from app import db, log, set_sco_dept
|
||||||
import app.scodoc.sco_assiduites as scass
|
import app.scodoc.sco_assiduites as scass
|
||||||
|
@ -858,7 +859,10 @@ def assiduite_edit(assiduite_id: int):
|
||||||
msg=f"assiduite: modif {assiduite_unique}",
|
msg=f"assiduite: modif {assiduite_unique}",
|
||||||
)
|
)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
scass.simple_invalidate_cache(assiduite_unique.to_dict())
|
try:
|
||||||
|
scass.simple_invalidate_cache(assiduite_unique.to_dict())
|
||||||
|
except ObjectDeletedError:
|
||||||
|
return json_error(404, "Assiduité supprimée / inexistante")
|
||||||
|
|
||||||
return {"OK": True}
|
return {"OK": True}
|
||||||
|
|
||||||
|
|
|
@ -611,16 +611,17 @@ class BasePreferences:
|
||||||
"explanation": "toute saisie d'absence doit indiquer le module concerné",
|
"explanation": "toute saisie d'absence doit indiquer le module concerné",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
# (
|
(
|
||||||
# "forcer_present",
|
"non_present",
|
||||||
# {
|
{
|
||||||
# "initvalue": 0,
|
"initvalue": 0,
|
||||||
# "title": "Forcer l'appel des présents",
|
"title": "Désactiver la saisie des présences",
|
||||||
# "input_type": "boolcheckbox",
|
"input_type": "boolcheckbox",
|
||||||
# "labels": ["non", "oui"],
|
"labels": ["non", "oui"],
|
||||||
# "category": "assi",
|
"category": "assi",
|
||||||
# },
|
"explanation": "Désactive la saisie et l'affichage des présences",
|
||||||
# ),
|
},
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"periode_defaut",
|
"periode_defaut",
|
||||||
{
|
{
|
||||||
|
@ -644,18 +645,18 @@ class BasePreferences:
|
||||||
"category": "assi",
|
"category": "assi",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
# (
|
||||||
"assi_etat_defaut",
|
# "assi_etat_defaut",
|
||||||
{
|
# {
|
||||||
"explanation": "⚠ non fonctionnel, travaux en cours !",
|
# "explanation": "⚠ non fonctionnel, travaux en cours !",
|
||||||
"initvalue": "aucun",
|
# "initvalue": "aucun",
|
||||||
"input_type": "menu",
|
# "input_type": "menu",
|
||||||
"labels": ["aucun", "present", "retard", "absent"],
|
# "labels": ["aucun", "present", "retard", "absent"],
|
||||||
"allowed_values": ["aucun", "present", "retard", "absent"],
|
# "allowed_values": ["aucun", "present", "retard", "absent"],
|
||||||
"title": "Définir l'état par défaut",
|
# "title": "Définir l'état par défaut",
|
||||||
"category": "assi",
|
# "category": "assi",
|
||||||
},
|
# },
|
||||||
),
|
# ),
|
||||||
(
|
(
|
||||||
"non_travail",
|
"non_travail",
|
||||||
{
|
{
|
||||||
|
|
|
@ -730,31 +730,11 @@ tr.row-justificatif.non_valide td.assi-type {
|
||||||
background-color: var(--color-defaut) !important;
|
background-color: var(--color-defaut) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color.est_just.sans_etat::before {
|
.color.invalide {
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
width: 25%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: var(--color-justi) !important;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color.invalide::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
width: 25%;
|
|
||||||
height: 100%;
|
|
||||||
right: 0;
|
|
||||||
background-color: var(--color-justi-invalide) !important;
|
background-color: var(--color-justi-invalide) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color.attente::before,
|
.color.attente {
|
||||||
.color.modifie::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
width: 25%;
|
|
||||||
height: 100%;
|
|
||||||
right: 0;
|
|
||||||
background: repeating-linear-gradient(to bottom,
|
background: repeating-linear-gradient(to bottom,
|
||||||
var(--color-justi-attente-stripe) 0px,
|
var(--color-justi-attente-stripe) 0px,
|
||||||
var(--color-justi-attente-stripe) 4px,
|
var(--color-justi-attente-stripe) 4px,
|
||||||
|
@ -762,6 +742,10 @@ tr.row-justificatif.non_valide td.assi-type {
|
||||||
var(--color-justi-attente) 7px) !important;
|
var(--color-justi-attente) 7px) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.color.est_just {
|
||||||
|
background-color: var(--color-justi) !important;
|
||||||
|
}
|
||||||
|
|
||||||
#gtrcontent .pdp {
|
#gtrcontent .pdp {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,7 +296,13 @@ function creerLigneEtudiant(etud, index) {
|
||||||
// Création des boutons d'assiduités
|
// Création des boutons d'assiduités
|
||||||
if (readOnly) {
|
if (readOnly) {
|
||||||
} else if (currentAssiduite.type != "conflit") {
|
} else if (currentAssiduite.type != "conflit") {
|
||||||
["present", "retard", "absent"].forEach((abs) => {
|
const etats = ["retard", "absent"];
|
||||||
|
|
||||||
|
if (!window.nonPresent) {
|
||||||
|
etats.splice(0, 0, "present");
|
||||||
|
}
|
||||||
|
|
||||||
|
etats.forEach((abs) => {
|
||||||
const btn = document.createElement("input");
|
const btn = document.createElement("input");
|
||||||
btn.type = "checkbox";
|
btn.type = "checkbox";
|
||||||
btn.value = abs;
|
btn.value = abs;
|
||||||
|
@ -425,7 +431,7 @@ async function getModuleImpl(assiduite) {
|
||||||
return res.json();
|
return res.json();
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
moduleimpls[id] = `${data.module.code} ${data.module.abbrev || ''}`;
|
moduleimpls[id] = `${data.module.code} ${data.module.abbrev || ""}`;
|
||||||
return moduleimpls[id];
|
return moduleimpls[id];
|
||||||
})
|
})
|
||||||
.catch((_) => {
|
.catch((_) => {
|
||||||
|
@ -531,12 +537,7 @@ async function MiseAJourLigneEtud(etud) {
|
||||||
|
|
||||||
async function actionAssiduite(etud, etat, type, assiduite = null) {
|
async function actionAssiduite(etud, etat, type, assiduite = null) {
|
||||||
const modimpl_id = $("#moduleimpl_select").val();
|
const modimpl_id = $("#moduleimpl_select").val();
|
||||||
if (
|
if (assiduite && assiduite.etat.toLowerCase() === etat) type = "suppression";
|
||||||
assiduite &&
|
|
||||||
assiduite.etat.toLowerCase() === etat &&
|
|
||||||
assiduite.moduleimpl_id == modimpl_id
|
|
||||||
)
|
|
||||||
type = "suppression";
|
|
||||||
|
|
||||||
const { deb, fin } = getPeriodAsDate();
|
const { deb, fin } = getPeriodAsDate();
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
"""Liste simple d'étudiants
|
"""Liste simple d'étudiants"""
|
||||||
"""
|
|
||||||
import datetime
|
import datetime
|
||||||
from flask import g, url_for
|
from flask import g, url_for
|
||||||
from app import log
|
from app import log
|
||||||
|
@ -140,6 +140,13 @@ class RowAssi(tb.Row):
|
||||||
)
|
)
|
||||||
stats = self._get_etud_stats(etud)
|
stats = self._get_etud_stats(etud)
|
||||||
for key, value in stats.items():
|
for key, value in stats.items():
|
||||||
|
if key == "present" and sco_preferences.get_preference(
|
||||||
|
"non_present",
|
||||||
|
dept_id=g.scodoc_dept_id,
|
||||||
|
formsemestre_id=self.table.formsemestre.id,
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
self.add_cell(key, value[0], fmt_num(value[1] - value[2]), "assi_stats")
|
self.add_cell(key, value[0], fmt_num(value[1] - value[2]), "assi_stats")
|
||||||
if key != "present":
|
if key != "present":
|
||||||
self.add_cell(
|
self.add_cell(
|
||||||
|
|
|
@ -75,36 +75,7 @@ Calendrier de l'assiduité
|
||||||
|
|
||||||
<div class="help">
|
<div class="help">
|
||||||
<h3>Calendrier</h3>
|
<h3>Calendrier</h3>
|
||||||
<p>Code couleur</p>
|
{% include "assiduites/widgets/legende_couleur.j2" %}
|
||||||
<ul class="couleurs">
|
|
||||||
<li><span title="Vert" class="present demo"></span> → présence de l'étudiant lors de la
|
|
||||||
période
|
|
||||||
</li>
|
|
||||||
<li><span title="Bleu clair" class="nonwork demo"></span> → la période n'est pas travaillée
|
|
||||||
</li>
|
|
||||||
<li><span title="Rouge" class="absent demo"></span> → absence de l'étudiant lors de la
|
|
||||||
période
|
|
||||||
</li>
|
|
||||||
<li><span title="Rose" class="demo color absent est_just"></span> → absence justifiée
|
|
||||||
</li>
|
|
||||||
<li><span title="Orange" class="retard demo"></span> → retard de l'étudiant lors de la
|
|
||||||
période
|
|
||||||
</li>
|
|
||||||
<li><span title="Jaune clair" class="demo color retard est_just"></span> → retard justifié
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><span title="Quart Bleu" class="est_just demo"></span> → la période est couverte par un
|
|
||||||
justificatif valide</li>
|
|
||||||
<li><span title="Justif. non valide" class="invalide demo"></span> → la période est
|
|
||||||
couverte par un justificatif non valide
|
|
||||||
</li>
|
|
||||||
<li><span title="Justif. en attente" class="attente demo"></span> → la période
|
|
||||||
a un justificatif en attente de validation
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
<p>Vous pouvez passer le curseur sur les jours colorés afin de voir les informations supplémentaires</p>
|
|
||||||
</div>
|
</div>
|
||||||
<ul class="couleurs print">
|
<ul class="couleurs print">
|
||||||
<li><span title="Vert" class="present demo"></span> présence
|
<li><span title="Vert" class="present demo"></span> présence
|
||||||
|
@ -180,21 +151,8 @@ Calendrier de l'assiduité
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.demo.invalide {
|
|
||||||
background-color: var(--color-justi-invalide) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.demo.attente {
|
|
||||||
background: repeating-linear-gradient(to bottom,
|
|
||||||
var(--color-justi-attente-stripe) 0px,
|
|
||||||
var(--color-justi-attente-stripe) 4px,
|
|
||||||
var(--color-justi-attente) 4px,
|
|
||||||
var(--color-justi-attente) 7px) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.demo.est_just {
|
|
||||||
background-color: var(--color-justi) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.demi .day.nonwork>span {
|
.demi .day.nonwork>span {
|
||||||
|
|
|
@ -310,8 +310,13 @@ async function nouvellePeriode(period = null) {
|
||||||
|
|
||||||
const assi_btns = document.createElement('div');
|
const assi_btns = document.createElement('div');
|
||||||
assi_btns.classList.add('assi-btns');
|
assi_btns.classList.add('assi-btns');
|
||||||
|
const etats = ["retard", "absent"];
|
||||||
|
|
||||||
["present", "retard", "absent"].forEach((value) => {
|
if(!window.nonPresent){
|
||||||
|
etats.splice(0,0,"present");
|
||||||
|
}
|
||||||
|
|
||||||
|
etats.forEach((value) => {
|
||||||
const cbox = document.createElement("input");
|
const cbox = document.createElement("input");
|
||||||
cbox.type = "checkbox";
|
cbox.type = "checkbox";
|
||||||
cbox.value = value;
|
cbox.value = value;
|
||||||
|
@ -499,6 +504,8 @@ const moduleimpls = new Map();
|
||||||
const inscriptionsModules = new Map();
|
const inscriptionsModules = new Map();
|
||||||
const nonWorkDays = [{{ nonworkdays| safe }}];
|
const nonWorkDays = [{{ nonworkdays| safe }}];
|
||||||
|
|
||||||
|
window.nonPresent = {{ 'true' if non_present else 'false' }};
|
||||||
|
|
||||||
// Vérification du forçage de module
|
// Vérification du forçage de module
|
||||||
window.forceModule = "{{ forcer_module }}" == "True";
|
window.forceModule = "{{ forcer_module }}" == "True";
|
||||||
if (window.forceModule) {
|
if (window.forceModule) {
|
||||||
|
@ -518,12 +525,29 @@ if (window.forceModule) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultPlage = {{ nouv_plage | safe}} || [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fonction exécutée au lancement de la page
|
* Fonction exécutée au lancement de la page
|
||||||
* - On affiche ou non les photos des étudiants
|
* - On affiche ou non les photos des étudiants
|
||||||
* - On vérifie si la date est un jour travaillé
|
* - On vérifie si la date est un jour travaillé
|
||||||
*/
|
*/
|
||||||
async function main() {
|
async function main() {
|
||||||
|
|
||||||
|
// On initialise les sélecteurs avec les valeurs par défaut (si elles existent)
|
||||||
|
if (defaultPlage.every((e) => e)) {
|
||||||
|
$("#date").datepicker("setDate", defaultPlage[0]);
|
||||||
|
$("#debut").val(defaultPlage[1]);
|
||||||
|
$("#fin").val(defaultPlage[2]);
|
||||||
|
|
||||||
|
// On ajoute la période si la date est un jour travaillé
|
||||||
|
if(dateCouranteEstTravaillee()){
|
||||||
|
await nouvellePeriode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const checked = localStorage.getItem("scodoc-etud-pdp") == "true";
|
const checked = localStorage.getItem("scodoc-etud-pdp") == "true";
|
||||||
afficherPDP(checked);
|
afficherPDP(checked);
|
||||||
$("#date").on("change", async function (d) {
|
$("#date").on("change", async function (d) {
|
||||||
|
@ -532,7 +556,7 @@ async function main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
window.addEventListener("load", main);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -600,7 +624,9 @@ main();
|
||||||
Intialiser les étudiants comme :
|
Intialiser les étudiants comme :
|
||||||
<select name="etatDef" id="etatDef">
|
<select name="etatDef" id="etatDef">
|
||||||
<option value="">-</option>
|
<option value="">-</option>
|
||||||
|
{% if not non_present %}
|
||||||
<option value="present">présents</option>
|
<option value="present">présents</option>
|
||||||
|
{% endif %}
|
||||||
<option value="retard">en retard</option>
|
<option value="retard">en retard</option>
|
||||||
<option value="absent">absents</option>
|
<option value="absent">absents</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
const readOnly = {{ readonly }};
|
const readOnly = {{ readonly }};
|
||||||
|
|
||||||
window.forceModule = "{{ forcer_module }}" == "True"
|
window.forceModule = "{{ forcer_module }}" == "True"
|
||||||
|
window.nonPresent = {{ 'true' if non_present else 'false' }};
|
||||||
|
|
||||||
const etudsDefDem = {{ defdem | safe }}
|
const etudsDefDem = {{ defdem | safe }}
|
||||||
|
|
||||||
|
@ -159,8 +160,10 @@
|
||||||
<div class="mass-selection">
|
<div class="mass-selection">
|
||||||
<span>Mettre tout le monde :</span>
|
<span>Mettre tout le monde :</span>
|
||||||
<fieldset class="btns_field mass">
|
<fieldset class="btns_field mass">
|
||||||
|
{% if not non_present %}
|
||||||
<input type="checkbox" value="present" name="mass_btn_assiduites" id="mass_rbtn_present"
|
<input type="checkbox" value="present" name="mass_btn_assiduites" id="mass_rbtn_present"
|
||||||
class="rbtn present" onclick="mettreToutLeMonde('present', this)" title="Present">
|
class="rbtn present" onclick="mettreToutLeMonde('present', this)" title="Present">
|
||||||
|
{% endif %}
|
||||||
<input type="checkbox" value="retard" name="mass_btn_assiduites" id="mass_rbtn_retard"
|
<input type="checkbox" value="retard" name="mass_btn_assiduites" id="mass_rbtn_retard"
|
||||||
class="rbtn retard" onclick="mettreToutLeMonde('retard', this)" title="Retard">
|
class="rbtn retard" onclick="mettreToutLeMonde('retard', this)" title="Retard">
|
||||||
<input type="checkbox" value="absent" name="mass_btn_assiduites" id="mass_rbtn_absent"
|
<input type="checkbox" value="absent" name="mass_btn_assiduites" id="mass_rbtn_absent"
|
||||||
|
@ -178,6 +181,11 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
|
<h3>Calendrier</h3>
|
||||||
|
{% include "assiduites/widgets/legende_couleur.j2" %}
|
||||||
|
</div>
|
||||||
|
|
||||||
{% include "assiduites/widgets/toast.j2" %}
|
{% include "assiduites/widgets/toast.j2" %}
|
||||||
{% include "assiduites/widgets/alert.j2" %}
|
{% include "assiduites/widgets/alert.j2" %}
|
||||||
{% include "assiduites/widgets/prompt.j2" %}
|
{% include "assiduites/widgets/prompt.j2" %}
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
<li><span title="Vert" class="present demo"></span> → présence de l'étudiant lors de la période
|
<p>Code couleur</p>
|
||||||
</li>
|
<ul class="couleurs">
|
||||||
<li><span title="Orange" class="retard demo"></span> → retard de l'étudiant lors de la période
|
<li><span title="Vert" class="present demo"></span> → présence de l'étudiant lors de la
|
||||||
</li>
|
période
|
||||||
<li><span title="Rouge" class="absent demo"></span> → absence de l'étudiant lors de la période
|
</li>
|
||||||
</li>
|
<li><span title="Bleu clair" class="nonwork demo"></span> → la période n'est pas travaillée
|
||||||
|
</li>
|
||||||
|
<li><span title="Rouge" class="absent demo"></span> → absence de l'étudiant lors de la
|
||||||
|
période
|
||||||
|
</li>
|
||||||
|
<li><span title="Rose" class="demo color absent est_just"></span> → absence justifiée
|
||||||
|
</li>
|
||||||
|
<li><span title="Orange" class="retard demo"></span> → retard de l'étudiant lors de la
|
||||||
|
période
|
||||||
|
</li>
|
||||||
|
<li><span title="Jaune clair" class="demo color retard est_just"></span> → retard justifié
|
||||||
|
</li>
|
||||||
|
|
||||||
<li><span title="Hachure Bleue" class="justified demo"></span> → l'assiduité est justifiée par un
|
<li><span title="Quart Bleu" class="est_just demo color"></span> → la période est couverte par un
|
||||||
justificatif valide</li>
|
justificatif valide</li>
|
||||||
<li><span title="Hachure Rouge" class="invalid_justified demo"></span> → l'assiduité est
|
<li><span title="Justif. non valide" class="invalide demo color "></span> → la période est
|
||||||
justifiée par un justificatif non valide / en attente de validation
|
couverte par un justificatif non valide
|
||||||
</li>
|
</li>
|
||||||
|
<li><span title="Justif. en attente" class="attente demo color"></span> → la période
|
||||||
|
a un justificatif en attente de validation
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Vous pouvez passer le curseur sur les jours colorés afin de voir les informations supplémentaires</p>
|
||||||
|
|
|
@ -74,7 +74,13 @@
|
||||||
setupAssiduiteBubble(block, assiduité);
|
setupAssiduiteBubble(block, assiduité);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ajout couleur justificatif
|
// ajout couleur justificatif
|
||||||
|
const justificatifs = assiduité.justificatifs || [];
|
||||||
|
const justified = justificatifs.some(
|
||||||
|
(justificatif) => justificatif.etat === "VALIDE"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(justified) block.classList.add("est_just");
|
||||||
|
|
||||||
block.classList.add(assiduité.etat.toLowerCase());
|
block.classList.add(assiduité.etat.toLowerCase());
|
||||||
if(assiduité.etat != "CRENEAU") block.classList.add("color");
|
if(assiduité.etat != "CRENEAU") block.classList.add("color");
|
||||||
|
|
|
@ -1132,6 +1132,11 @@ def signal_assiduites_group():
|
||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
dept_id=g.scodoc_dept_id,
|
dept_id=g.scodoc_dept_id,
|
||||||
),
|
),
|
||||||
|
non_present=sco_preferences.get_preference(
|
||||||
|
"non_present",
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
|
dept_id=g.scodoc_dept_id,
|
||||||
|
),
|
||||||
formsemestre_date_debut=str(formsemestre.date_debut),
|
formsemestre_date_debut=str(formsemestre.date_debut),
|
||||||
formsemestre_date_fin=str(formsemestre.date_fin),
|
formsemestre_date_fin=str(formsemestre.date_fin),
|
||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
|
@ -1914,8 +1919,29 @@ def _preparer_objet(
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.AbsChange)
|
@permission_required(Permission.AbsChange)
|
||||||
def signal_assiduites_diff():
|
def signal_assiduites_diff():
|
||||||
"""TODO documenter
|
"""
|
||||||
Utilisé notamment par "Saisie différée" sur tableau de bord semetstre"
|
Utilisé notamment par "Saisie différée" sur tableau de bord semetstre"
|
||||||
|
|
||||||
|
Arguments de la requête:
|
||||||
|
|
||||||
|
- group_ids : liste des groupes
|
||||||
|
example : group_ids=1,2,3
|
||||||
|
- formsemestre_id : id du formsemestre
|
||||||
|
example : formsemestre_id=1
|
||||||
|
- moduleimpl_id : id du moduleimpl
|
||||||
|
example : moduleimpl_id=1
|
||||||
|
|
||||||
|
(Permet de pré-générer une plage. Si non renseigné, la plage sera vide)
|
||||||
|
(Les trois valeurs suivantes doivent être renseignées ensemble)
|
||||||
|
- date
|
||||||
|
example : date=01/01/2021
|
||||||
|
- heure_debut
|
||||||
|
example : heure_debut=08:00
|
||||||
|
- heure_fin
|
||||||
|
example : heure_fin=10:00
|
||||||
|
|
||||||
|
Exemple de requête :
|
||||||
|
signal_assiduites_diff?formsemestre_id=67&group_ids=400&moduleimpl_id=1229&date=15/04/2024&heure_debut=12:34&heure_fin=12:55
|
||||||
"""
|
"""
|
||||||
# Récupération des paramètres de la requête
|
# Récupération des paramètres de la requête
|
||||||
group_ids: list[int] = request.args.get("group_ids", None)
|
group_ids: list[int] = request.args.get("group_ids", None)
|
||||||
|
@ -1957,11 +1983,23 @@ def signal_assiduites_diff():
|
||||||
grp + ' <span class="fontred">' + groups_infos.groups_titles + "</span>"
|
grp + ' <span class="fontred">' + groups_infos.groups_titles + "</span>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Pré-remplissage des sélecteurs
|
||||||
moduleimpl_id = request.args.get("moduleimpl_id", -1)
|
moduleimpl_id = request.args.get("moduleimpl_id", -1)
|
||||||
try:
|
try:
|
||||||
moduleimpl_id = int(moduleimpl_id)
|
moduleimpl_id = int(moduleimpl_id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
moduleimpl_id = -1
|
moduleimpl_id = -1
|
||||||
|
# date fra (dd/mm/yyyy)
|
||||||
|
date = request.args.get("date", "")
|
||||||
|
# heures (hh:mm)
|
||||||
|
heure_deb = request.args.get("heure_debut", "")
|
||||||
|
heure_fin = request.args.get("heure_fin", "")
|
||||||
|
|
||||||
|
# vérifications des sélecteurs
|
||||||
|
date = date if re.match(r"^\d{2}\/\d{2}\/\d{4}$", date) else ""
|
||||||
|
heure_deb = heure_deb if re.match(r"^[0-2]\d:[0-5]\d$", heure_deb) else ""
|
||||||
|
heure_fin = heure_fin if re.match(r"^[0-2]\d:[0-5]\d$", heure_fin) else ""
|
||||||
|
nouv_plage: list[str] = [date, heure_deb, heure_fin]
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"assiduites/pages/signal_assiduites_diff.j2",
|
"assiduites/pages/signal_assiduites_diff.j2",
|
||||||
|
@ -1977,6 +2015,12 @@ def signal_assiduites_diff():
|
||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
dept_id=g.scodoc_dept_id,
|
dept_id=g.scodoc_dept_id,
|
||||||
),
|
),
|
||||||
|
non_present=sco_preferences.get_preference(
|
||||||
|
"non_present",
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
|
dept_id=g.scodoc_dept_id,
|
||||||
|
),
|
||||||
|
nouv_plage=nouv_plage,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user