forked from ScoDoc/ScoDoc
Billets absences: modernisation
This commit is contained in:
parent
f31ccbee9a
commit
f5ee63dd5c
@ -101,6 +101,7 @@ def sidebar(etudid: int = None):
|
||||
etudid = request.form.get("etudid", None)
|
||||
|
||||
if etudid is not None:
|
||||
etudi = int(etudid)
|
||||
etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
|
||||
params.update(etud)
|
||||
params["fiche_url"] = url_for(
|
||||
|
@ -39,7 +39,7 @@ from app.scodoc import sco_preferences
|
||||
def query_billets_etud(
|
||||
etudid: int = None, etat: bool = None
|
||||
) -> flask_sqlalchemy.BaseQuery:
|
||||
"""Billets d'absences pour un étudiant.
|
||||
"""Billets d'absences pour un étudiant, ou tous si etudid is None.
|
||||
Si etat, filtre par état.
|
||||
Si dans un département et que la gestion des billets n'a pas été activée
|
||||
dans ses préférences, table toujours vide.
|
||||
@ -48,9 +48,11 @@ def query_billets_etud(
|
||||
"handle_billets_abs"
|
||||
):
|
||||
return []
|
||||
billets = BilletAbsence.query.filter_by(etudid=etudid)
|
||||
billets = BilletAbsence.query
|
||||
if etudid is not None:
|
||||
billets = billets.filter_by(etudid=etudid)
|
||||
if etat is not None:
|
||||
billets = billets.query.filter_by(etat=False)
|
||||
billets = billets.filter_by(etat=False)
|
||||
if g.scodoc_dept is not None:
|
||||
# jointure avec departement de l'étudiant
|
||||
billets = billets.join(BilletAbsence.etudiant).filter_by(
|
||||
|
@ -57,7 +57,7 @@ from xml.etree import ElementTree
|
||||
|
||||
import flask
|
||||
from flask import g, request
|
||||
from flask import url_for
|
||||
from flask import abort, flash, url_for
|
||||
from flask_login import current_user
|
||||
|
||||
from app import db, log
|
||||
@ -70,7 +70,7 @@ from app.decorators import (
|
||||
permission_required,
|
||||
permission_required_compat_scodoc7,
|
||||
)
|
||||
from app.models import FormSemestre, GroupDescr
|
||||
from app.models import FormSemestre, GroupDescr, Partition
|
||||
from app.models.absences import BilletAbsence
|
||||
from app.models.etudiants import Identite
|
||||
from app.views import absences_bp as bp
|
||||
@ -162,7 +162,13 @@ def index_html():
|
||||
@scodoc7func
|
||||
def choix_semaine(group_id):
|
||||
"""Page choix semaine sur calendrier pour saisie absences d'un groupe"""
|
||||
group = GroupDescr.query.get_or_404(group_id)
|
||||
group = (
|
||||
GroupDescr.query.filter_by(id=group_id)
|
||||
.join(Partition)
|
||||
.join(FormSemestre)
|
||||
.filter_by(dept_id=g.scodoc_dept_id)
|
||||
.first_or_404()
|
||||
)
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title="Saisie des absences",
|
||||
@ -357,6 +363,9 @@ def SignaleAbsenceGrHebdo(
|
||||
)
|
||||
|
||||
formsemestre_id = groups_infos.formsemestre_id
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
if formsemestre.dept_id != g.scodoc_dept_id:
|
||||
abort(404, "groupes inexistants dans ce département")
|
||||
require_module = sco_preferences.get_preference(
|
||||
"abs_require_module", formsemestre_id
|
||||
)
|
||||
@ -381,11 +390,8 @@ def SignaleAbsenceGrHebdo(
|
||||
# Si aucun etudiant n'est inscrit au module choisi...
|
||||
moduleimpl_id = None
|
||||
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
|
||||
sem = formsemestre.to_dict()
|
||||
# sem = sco_formsemestre.do_formsemestre_list({"formsemestre_id": formsemestre_id})[0]
|
||||
|
||||
# calcule dates jours de cette semaine
|
||||
# liste de dates iso "yyyy-mm-dd"
|
||||
@ -506,6 +512,8 @@ def SignaleAbsenceGrSemestre(
|
||||
)
|
||||
formsemestre_id = groups_infos.formsemestre_id
|
||||
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
if formsemestre.dept_id != g.scodoc_dept_id:
|
||||
return abort(404, "groupes inexistants dans ce département")
|
||||
sem = formsemestre.to_dict()
|
||||
require_module = sco_preferences.get_preference(
|
||||
"abs_require_module", formsemestre_id
|
||||
@ -1217,7 +1225,9 @@ def XMLgetBilletsEtud(etudid=False, code_nip=False):
|
||||
"""Liste billets pour un etudiant"""
|
||||
log("Warning: called deprecated XMLgetBilletsEtud")
|
||||
if etudid is False:
|
||||
etud = Identite.query.filter_by(code_nip=str(code_nip)).first_or_404()
|
||||
etud = Identite.query.filter_by(
|
||||
code_nip=str(code_nip), dept_id=g.scodoc_dept_id
|
||||
).first_or_404()
|
||||
etudid = etud.id
|
||||
table = sco_abs_billets.table_billets_etud(etudid)
|
||||
if table:
|
||||
@ -1243,7 +1253,8 @@ def list_billets():
|
||||
tf = TrivialFormulator(
|
||||
request.base_url,
|
||||
scu.get_request_args(),
|
||||
(("billet_id", {"input_type": "text", "title": "Numéro du billet"}),),
|
||||
(("billet_id", {"input_type": "text", "title": "Numéro du billet :"}),),
|
||||
method="get",
|
||||
submitbutton=False,
|
||||
)
|
||||
if tf[0] == 0:
|
||||
@ -1264,14 +1275,14 @@ def list_billets():
|
||||
@scodoc7func
|
||||
def delete_billets_absence(billet_id, dialog_confirmed=False):
|
||||
"""Supprime un billet."""
|
||||
cnx = ndb.GetDBConnexion()
|
||||
billets = sco_abs.billet_absence_list(cnx, {"billet_id": billet_id})
|
||||
if not billets:
|
||||
return flask.redirect(
|
||||
"list_billets?head_message=Billet%%20%s%%20inexistant !" % billet_id
|
||||
billet: BilletAbsence = (
|
||||
BilletAbsence.query.filter_by(id=billet_id)
|
||||
.join(Identite)
|
||||
.filter_by(dept_id=g.scodoc_dept_id)
|
||||
.first_or_404()
|
||||
)
|
||||
if not dialog_confirmed:
|
||||
tab = sco_abs_billets.table_billets(billets)
|
||||
tab = sco_abs_billets.table_billets([billet])
|
||||
return scu.confirm_dialog(
|
||||
"""<h2>Supprimer ce billet ?</h2>""" + tab.html(),
|
||||
dest_url="",
|
||||
@ -1279,30 +1290,35 @@ def delete_billets_absence(billet_id, dialog_confirmed=False):
|
||||
parameters={"billet_id": billet_id},
|
||||
)
|
||||
|
||||
sco_abs.billet_absence_delete(cnx, billet_id)
|
||||
db.session.delete(billet)
|
||||
db.session.commit()
|
||||
|
||||
return flask.redirect("list_billets?head_message=Billet%20supprimé")
|
||||
flash("Billet supprimé")
|
||||
return flask.redirect(url_for("absences.list_billets", scodoc_dept=g.scodoc_dept))
|
||||
|
||||
|
||||
def _ProcessBilletAbsence(billet, estjust, description):
|
||||
def _ProcessBilletAbsence(
|
||||
billet: BilletAbsence, estjust: bool, description: str
|
||||
) -> int:
|
||||
"""Traite un billet: ajoute absence(s) et éventuellement justificatifs,
|
||||
et change l'état du billet à 1.
|
||||
NB: actuellement, les heures ne sont utilisées que pour déterminer si matin et/ou après-midi.
|
||||
et change l'état du billet à True.
|
||||
return: nombre de demi-journées d'absence ajoutées, -1 si billet déjà traité.
|
||||
NB: actuellement, les heures ne sont utilisées que pour déterminer
|
||||
si matin et/ou après-midi.
|
||||
"""
|
||||
cnx = ndb.GetDBConnexion()
|
||||
if billet["etat"] != 0:
|
||||
log("billet=%s" % billet)
|
||||
log("billet deja traité !")
|
||||
if billet.etat:
|
||||
log(f"billet deja traite: {billet} !")
|
||||
return -1
|
||||
n = 0 # nombre de demi-journées d'absence ajoutées
|
||||
# 1-- ajout des absences (et justifs)
|
||||
datedebut = billet["abs_begin"].strftime("%d/%m/%Y")
|
||||
datefin = billet["abs_end"].strftime("%d/%m/%Y")
|
||||
|
||||
# 1-- Ajout des absences (et justifs)
|
||||
datedebut = billet.abs_begin.strftime("%d/%m/%Y")
|
||||
datefin = billet.abs_end.strftime("%d/%m/%Y")
|
||||
dates = sco_abs.DateRangeISO(datedebut, datefin)
|
||||
# commence après-midi ?
|
||||
if dates and billet["abs_begin"].hour > 11:
|
||||
if dates and billet.abs_begin.hour > 11:
|
||||
sco_abs.add_absence(
|
||||
billet["etudid"],
|
||||
billet.etudid,
|
||||
dates[0],
|
||||
0,
|
||||
estjust,
|
||||
@ -1311,9 +1327,9 @@ def _ProcessBilletAbsence(billet, estjust, description):
|
||||
n += 1
|
||||
dates = dates[1:]
|
||||
# termine matin ?
|
||||
if dates and billet["abs_end"].hour < 12:
|
||||
if dates and billet.abs_end.hour < 12:
|
||||
sco_abs.add_absence(
|
||||
billet["etudid"],
|
||||
billet.etudid,
|
||||
dates[-1],
|
||||
1,
|
||||
estjust,
|
||||
@ -1324,14 +1340,14 @@ def _ProcessBilletAbsence(billet, estjust, description):
|
||||
|
||||
for jour in dates:
|
||||
sco_abs.add_absence(
|
||||
billet["etudid"],
|
||||
billet.etudid,
|
||||
jour,
|
||||
0,
|
||||
estjust,
|
||||
description=description,
|
||||
)
|
||||
sco_abs.add_absence(
|
||||
billet["etudid"],
|
||||
billet.etudid,
|
||||
jour,
|
||||
1,
|
||||
estjust,
|
||||
@ -1339,9 +1355,10 @@ def _ProcessBilletAbsence(billet, estjust, description):
|
||||
)
|
||||
n += 2
|
||||
|
||||
# 2- change etat du billet
|
||||
sco_abs.billet_absence_edit(cnx, {"billet_id": billet["billet_id"], "etat": 1})
|
||||
|
||||
# 2- Change état du billet
|
||||
billet.etat = True
|
||||
db.session.add(billet)
|
||||
db.session.commit()
|
||||
return n
|
||||
|
||||
|
||||
@ -1351,26 +1368,27 @@ def _ProcessBilletAbsence(billet, estjust, description):
|
||||
@scodoc7func
|
||||
def process_billet_absence_form(billet_id):
|
||||
"""Formulaire traitement d'un billet"""
|
||||
cnx = ndb.GetDBConnexion()
|
||||
billets = sco_abs.billet_absence_list(cnx, {"billet_id": billet_id})
|
||||
if not billets:
|
||||
return flask.redirect(
|
||||
"list_billets?head_message=Billet%%20%s%%20inexistant !" % billet_id
|
||||
billet: BilletAbsence = (
|
||||
BilletAbsence.query.filter_by(id=billet_id)
|
||||
.join(Identite)
|
||||
.filter_by(dept_id=g.scodoc_dept_id)
|
||||
.first()
|
||||
)
|
||||
billet = billets[0]
|
||||
etudid = billet["etudid"]
|
||||
etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
|
||||
if billet is None:
|
||||
raise ScoValueError(
|
||||
f"Aucun billet avec le numéro <tt>{billet_id}</tt> dans ce département.",
|
||||
dest_url=url_for("absences.list_billets", scodoc_dept=g.scodoc_dept),
|
||||
)
|
||||
etud = billet.etudiant
|
||||
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title="Traitement billet d'absence de %s" % etud["nomprenom"],
|
||||
),
|
||||
'<h2>Traitement du billet %s : <a class="discretelink" href="%s">%s</a></h2>'
|
||||
% (
|
||||
billet_id,
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
etud["nomprenom"],
|
||||
page_title=f"Traitement billet d'absence de {etud.nomprenom}",
|
||||
),
|
||||
f"""<h2>Traitement du billet {billet.id} : <a class="discretelink" href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}">{etud.nomprenom}</a></h2>
|
||||
""",
|
||||
]
|
||||
|
||||
tf = TrivialFormulator(
|
||||
@ -1381,7 +1399,7 @@ def process_billet_absence_form(billet_id):
|
||||
(
|
||||
"etudid",
|
||||
{"input_type": "hidden"},
|
||||
), # pour centrer l'UI sur l'étudiant
|
||||
),
|
||||
(
|
||||
"estjust",
|
||||
{"input_type": "boolcheckbox", "title": "Absences justifiées"},
|
||||
@ -1389,24 +1407,31 @@ def process_billet_absence_form(billet_id):
|
||||
("description", {"input_type": "text", "size": 42, "title": "Raison"}),
|
||||
),
|
||||
initvalues={
|
||||
"description": billet["description"],
|
||||
"estjust": billet["justified"],
|
||||
"etudid": etudid,
|
||||
"description": billet.description or "",
|
||||
"estjust": billet.justified,
|
||||
"etudid": etud.id,
|
||||
},
|
||||
submitlabel="Enregistrer ces absences",
|
||||
)
|
||||
if tf[0] == 0:
|
||||
tab = sco_abs_billets.table_billets([billet], etud=etud)
|
||||
H.append(tab.html())
|
||||
if billet["justified"]:
|
||||
if billet.justified:
|
||||
H.append(
|
||||
"""<p>L'étudiant pense pouvoir justifier cette absence.<br/><em>Vérifiez le justificatif avant d'enregistrer.</em></p>"""
|
||||
"""<p>L'étudiant pense pouvoir justifier cette absence.<br/>
|
||||
<em>Vérifiez le justificatif avant d'enregistrer.</em></p>"""
|
||||
)
|
||||
F = (
|
||||
"""<p><a class="stdlink" href="delete_billets_absence?billet_id=%s">Supprimer ce billet</a> (utiliser en cas d'erreur, par ex. billet en double)</p>"""
|
||||
% billet_id
|
||||
)
|
||||
F += '<p><a class="stdlink" href="list_billets">Liste de tous les billets en attente</a></p>'
|
||||
F = f"""<p><a class="stdlink" href="{
|
||||
url_for("absences.delete_billets_absence",
|
||||
scodoc_dept=g.scodoc_dept, billet_id=billet_id)
|
||||
}">Supprimer ce billet</a>
|
||||
(utiliser en cas d'erreur, par ex. billet en double)
|
||||
</p>
|
||||
<p><a class="stdlink" href="{
|
||||
url_for("absences.list_billets", scodoc_dept=g.scodoc_dept)
|
||||
}">Liste de tous les billets en attente</a>
|
||||
</p>
|
||||
"""
|
||||
|
||||
return "\n".join(H) + "<br/>" + tf[1] + F + html_sco_header.sco_footer()
|
||||
elif tf[0] == -1:
|
||||
@ -1425,10 +1450,18 @@ def process_billet_absence_form(billet_id):
|
||||
elif n < 0:
|
||||
H.append("Ce billet avait déjà été traité !")
|
||||
H.append(
|
||||
'</div><p><a class="stdlink" href="list_billets">Autre billets en attente</a></p><h4>Billets déclarés par %s</h4>'
|
||||
% (etud["nomprenom"])
|
||||
f"""</div><p><a class="stdlink" href="{
|
||||
url_for("absences.list_billets", scodoc_dept=g.scodoc_dept)
|
||||
}">Autre billets en attente</a>
|
||||
</p>
|
||||
<h4>Billets déclarés par {etud.nomprenom}</h4>
|
||||
"""
|
||||
)
|
||||
billets = (
|
||||
BilletAbsence.query.filter_by(etudid=etud.id)
|
||||
.join(Identite)
|
||||
.filter_by(dept_id=g.scodoc_dept_id)
|
||||
)
|
||||
billets = sco_abs.billet_absence_list(cnx, {"etudid": etud["etudid"]})
|
||||
tab = sco_abs_billets.table_billets(billets, etud=etud)
|
||||
H.append(tab.html())
|
||||
return "\n".join(H) + html_sco_header.sco_footer()
|
||||
|
Loading…
Reference in New Issue
Block a user