Assiduites : evaluation_check_absences #685
This commit is contained in:
parent
c587c8b7d2
commit
cf74708f83
@ -30,16 +30,17 @@
|
||||
from flask import url_for, g
|
||||
|
||||
from app import db
|
||||
from app.models import Evaluation, FormSemestre, Identite
|
||||
from app.models import Evaluation, FormSemestre, Identite, Assiduite
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_evaluation_db
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc import sco_groups
|
||||
|
||||
from flask_sqlalchemy.query import Query
|
||||
from sqlalchemy import or_, and_
|
||||
|
||||
|
||||
# XXX TODO-ASSIDUITE https://scodoc.org/git/ScoDoc/ScoDoc/issues/685
|
||||
def evaluation_check_absences(evaluation: Evaluation):
|
||||
"""Vérifie les absences au moment de cette évaluation.
|
||||
Cas incohérents que l'on peut rencontrer pour chaque étudiant:
|
||||
@ -50,28 +51,32 @@ def evaluation_check_absences(evaluation: Evaluation):
|
||||
EXC et pas justifie
|
||||
Ramene 5 listes d'etudid
|
||||
"""
|
||||
raise ScoValueError("Fonction non disponible, patience !") # XXX TODO-ASSIDUITE
|
||||
|
||||
if not evaluation.date_debut:
|
||||
return [], [], [], [], [] # evaluation sans date
|
||||
|
||||
am, pm = evaluation.is_matin(), evaluation.is_apresmidi()
|
||||
etudids = [
|
||||
etudid
|
||||
for etudid, _ in sco_groups.do_evaluation_listeetuds_groups(
|
||||
evaluation.id, getallstudents=True
|
||||
)
|
||||
]
|
||||
|
||||
# Liste les absences à ce moment:
|
||||
absences = sco_abs.list_abs_jour(evaluation.date_debut, am=am, pm=pm)
|
||||
abs_etudids = set([x["etudid"] for x in absences]) # ensemble des etudiants absents
|
||||
abs_non_just = sco_abs.list_abs_non_just_jour(
|
||||
evaluation.date_debut.date(), am=am, pm=pm
|
||||
deb, fin = scu.localize_datetime(evaluation.date_debut), scu.localize_datetime(
|
||||
evaluation.date_fin
|
||||
)
|
||||
abs_nj_etudids = set(
|
||||
[x["etudid"] for x in abs_non_just]
|
||||
) # ensemble des etudiants absents non justifies
|
||||
justifs = sco_abs.list_abs_jour(
|
||||
evaluation.date_debut.date(), am=am, pm=pm, is_abs=None, is_just=True
|
||||
|
||||
assiduites: Query = Assiduite.query.filter(
|
||||
Assiduite.etudid.in_(etudids),
|
||||
Assiduite.etat == scu.EtatAssiduite.ABSENT,
|
||||
or_(
|
||||
and_(Assiduite.date_debut >= deb, Assiduite.date_debut <= fin),
|
||||
and_(Assiduite.date_fin >= deb, Assiduite.date_fin <= fin),
|
||||
),
|
||||
)
|
||||
just_etudids = set(
|
||||
[x["etudid"] for x in justifs]
|
||||
) # ensemble des etudiants avec justif
|
||||
|
||||
abs_etudids = set(assi.etudid for assi in assiduites)
|
||||
abs_nj_etudids = set(assi.etudid for assi in assiduites if assi.est_just is False)
|
||||
just_etudids = set(assi.etudid for assi in assiduites if assi.est_just is True)
|
||||
|
||||
# Les notes:
|
||||
notes_db = sco_evaluation_db.do_evaluation_get_all_notes(evaluation.id)
|
||||
@ -80,9 +85,7 @@ def evaluation_check_absences(evaluation: Evaluation):
|
||||
ExcNonSignalee = [] # note EXC mais pas noté absent
|
||||
ExcNonJust = [] # note EXC mais absent non justifie
|
||||
AbsButExc = [] # note ABS mais justifié
|
||||
for etudid, _ in sco_groups.do_evaluation_listeetuds_groups(
|
||||
evaluation.id, getallstudents=True
|
||||
):
|
||||
for etudid in etudids:
|
||||
if etudid in notes_db:
|
||||
val = notes_db[etudid]["value"]
|
||||
if (
|
||||
@ -170,14 +173,10 @@ def evaluation_check_absences_html(
|
||||
)
|
||||
if linkabs:
|
||||
url = url_for(
|
||||
"absences.doSignaleAbsence", # XXX TODO-ASSIDUITE
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
"assiduites.signal_evaluation_abs",
|
||||
etudid=etudid,
|
||||
# par defaut signale le jour du début de l'éval
|
||||
datedebut=evaluation.date_debut.strftime("%d/%m/%Y"),
|
||||
datefin=evaluation.date_debut.strftime("%d/%m/%Y"),
|
||||
demijournee=demijournee,
|
||||
moduleimpl_id=evaluation.moduleimpl_id,
|
||||
evaluation_id=evaluation.id,
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
)
|
||||
H.append(
|
||||
f"""<a class="stdlink" href="{url}">signaler cette absence</a>"""
|
||||
|
@ -32,6 +32,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
{% if saisie_eval %}
|
||||
<div id="saisie_eval">
|
||||
<br>
|
||||
<h3>
|
||||
La saisie de l'assiduité a été préconfigurée en fonction de l'évaluation. <br>
|
||||
Une fois la saisie finie, cliquez sur le lien si dessous pour revenir sur la gestion de l'évaluation
|
||||
</h3>
|
||||
<a href="{{redirect_url}}">retourner sur la page de l'évaluation</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{{diff | safe}}
|
||||
|
||||
<div class="legende">
|
||||
@ -118,7 +130,20 @@
|
||||
window.forceModule = "{{ forcer_module }}"
|
||||
window.forceModule = window.forceModule == "True" ? true : false
|
||||
|
||||
const date_deb = "{{date_deb}}";
|
||||
const date_fin = "{{date_fin}}";
|
||||
|
||||
{% if saisie_eval %}
|
||||
createColumn(
|
||||
date_deb,
|
||||
date_fin,
|
||||
{{ moduleimpl_id }}
|
||||
);
|
||||
window.location.href = "#saisie_eval"
|
||||
getAndUpdateCol(1)
|
||||
{% else %}
|
||||
createColumn();
|
||||
{% endif %}
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -278,7 +278,7 @@
|
||||
currentDate = moment(currentDate).tz(TIMEZONE).format("YYYY-MM-DDTHH:mm");
|
||||
}
|
||||
|
||||
function createColumn(dateStart = "", dateEnd = "") {
|
||||
function createColumn(dateStart = "", dateEnd = "", moduleimpl_id = "") {
|
||||
let table = document.getElementById("studentTable");
|
||||
let th = document.createElement("div");
|
||||
th.classList.add("th", "error");
|
||||
@ -343,6 +343,10 @@
|
||||
editModuleImpl(sl);
|
||||
})
|
||||
|
||||
if (moduleimpl_id != "") {
|
||||
sl.value = moduleimpl_id;
|
||||
}
|
||||
|
||||
let rows = table.querySelector(".tbody").querySelectorAll(".tr");
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let td = document.createElement("div");
|
||||
|
@ -1,7 +1,7 @@
|
||||
import datetime
|
||||
|
||||
from flask import g, request, render_template
|
||||
from flask import abort, url_for
|
||||
from flask import g, request, render_template, flash
|
||||
from flask import abort, url_for, redirect
|
||||
from flask_login import current_user
|
||||
|
||||
from app import db
|
||||
@ -18,6 +18,7 @@ from app.models import (
|
||||
Assiduite,
|
||||
Departement,
|
||||
FormSemestreInscription,
|
||||
Evaluation,
|
||||
)
|
||||
from app.views import assiduites_bp as bp
|
||||
from app.views import ScoData
|
||||
@ -203,6 +204,27 @@ def signal_assiduites_etud():
|
||||
if etud.dept_id != g.scodoc_dept_id:
|
||||
abort(404, "étudiant inexistant dans ce département")
|
||||
|
||||
date = request.args.get("date", datetime.date.today().isoformat())
|
||||
|
||||
# gestion évaluations
|
||||
|
||||
saisie_eval: bool = request.args.get("saisie_eval") is not None
|
||||
|
||||
date_deb: str = request.args.get("date_deb")
|
||||
date_fin: str = request.args.get("date_fin")
|
||||
moduleimpl_id: int = request.args.get("moduleimpl_id", "")
|
||||
evaluation_id: int = request.args.get("evaluation_id")
|
||||
|
||||
redirect_url: str = (
|
||||
"#"
|
||||
if not saisie_eval
|
||||
else url_for(
|
||||
"notes.evaluation_check_absences_html",
|
||||
evaluation_id=evaluation_id,
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
)
|
||||
)
|
||||
|
||||
header: str = html_sco_header.sco_header(
|
||||
page_title="Saisie Assiduités",
|
||||
init_qtip=True,
|
||||
@ -235,7 +257,7 @@ def signal_assiduites_etud():
|
||||
render_template(
|
||||
"assiduites/pages/signal_assiduites_etud.j2",
|
||||
sco=ScoData(etud),
|
||||
date=datetime.date.today().isoformat(),
|
||||
date=date,
|
||||
morning=morning,
|
||||
lunch=lunch,
|
||||
timeline=_timeline(),
|
||||
@ -249,6 +271,11 @@ def signal_assiduites_etud():
|
||||
etudiants=[sco_etud.get_etud_info(etudid=etud.etudid, filled=True)[0]],
|
||||
moduleimpl_select=select,
|
||||
),
|
||||
saisie_eval=saisie_eval,
|
||||
date_deb=date_deb,
|
||||
date_fin=date_fin,
|
||||
redirect_url=redirect_url,
|
||||
moduleimpl_id=moduleimpl_id,
|
||||
),
|
||||
).build()
|
||||
|
||||
@ -995,6 +1022,66 @@ def signal_assiduites_diff():
|
||||
).build()
|
||||
|
||||
|
||||
@bp.route("/SignalEvaluationAbs/<int:evaluation_id>/<int:etudid>")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def signal_evaluation_abs(etudid: int = None, evaluation_id: int = None):
|
||||
"""
|
||||
Signale l'absence d'un étudiant à une évaluation
|
||||
Si la durée de l'évaluation est inférieur à 1 jour
|
||||
Alors l'absence sera sur la période de l'évaluation
|
||||
Sinon L'utilisateur sera redirigé vers la page de saisie des absences de l'étudiant
|
||||
"""
|
||||
etud: Identite = Identite.query.get_or_404(etudid)
|
||||
if etud.dept_id != g.scodoc_dept_id:
|
||||
abort(404, "étudiant inexistant dans ce département")
|
||||
|
||||
evaluation: Evaluation = Evaluation.query.get_or_404(evaluation_id)
|
||||
|
||||
delta: datetime.timedelta = evaluation.date_fin - evaluation.date_debut
|
||||
if delta > datetime.timedelta(days=1):
|
||||
# rediriger vers page saisie
|
||||
flash("Redirection pour saisie abs")
|
||||
return redirect(
|
||||
url_for(
|
||||
"assiduites.signal_assiduites_etud",
|
||||
etudid=etudid,
|
||||
evaluation_id=evaluation.id,
|
||||
date_deb=evaluation.date_debut.strftime("%Y-%m-%dT%H:%M:%S"),
|
||||
date_fin=evaluation.date_fin.strftime("%Y-%m-%dT%H:%M:%S"),
|
||||
moduleimpl_id=evaluation.moduleimpl.id,
|
||||
saisie_eval="true",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
)
|
||||
)
|
||||
|
||||
# créer l'assiduité
|
||||
|
||||
assiduite_unique: Assiduite = Assiduite.create_assiduite(
|
||||
etud=etud,
|
||||
date_debut=scu.localize_datetime(evaluation.date_debut),
|
||||
date_fin=scu.localize_datetime(evaluation.date_fin),
|
||||
etat=scu.EtatAssiduite.ABSENT,
|
||||
moduleimpl=evaluation.moduleimpl,
|
||||
)
|
||||
|
||||
db.session.add(assiduite_unique)
|
||||
db.session.commit()
|
||||
|
||||
flash("L'absence a bien été créée")
|
||||
# rediriger vers la page d'évaluation
|
||||
return redirect(
|
||||
url_for(
|
||||
"notes.evaluation_check_absences_html",
|
||||
evaluation_id=evaluation.id,
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# --- Fonctions internes ---
|
||||
|
||||
|
||||
def _get_days_between_dates(deb: str, fin: str):
|
||||
if deb is None or fin is None:
|
||||
return "null"
|
||||
|
Loading…
Reference in New Issue
Block a user