Modernise code en-tete evaluation et 'absences ce jour'

This commit is contained in:
Emmanuel Viennet 2023-08-29 19:30:56 +02:00
parent 98f6ba2dd7
commit 4f40fbd028
3 changed files with 87 additions and 74 deletions

View File

@ -118,6 +118,32 @@ class ModuleImpl(db.Model):
return False
def can_edit_notes(self, user: "User", allow_ens=True) -> bool:
"""True if authuser can enter or edit notes in this module.
If allow_ens, grant access to all ens in this module
Si des décisions de jury ont déjà été saisies dans ce semestre,
seul le directeur des études peut saisir des notes (et il ne devrait pas).
"""
# was sco_permissions_check.can_edit_notes
from app.scodoc import sco_cursus_dut
if not self.formsemestre.etat:
return False # semestre verrouillé
is_dir_etud = user.id in (u.id for u in self.formsemestre.responsables)
can_edit_all_notes = user.has_permission(Permission.ScoEditAllNotes)
if sco_cursus_dut.formsemestre_has_decisions(self.formsemestre_id):
# il y a des décisions de jury dans ce semestre !
return can_edit_all_notes or is_dir_etud
if (
not can_edit_all_notes
and user.id != self.responsable_id
and not is_dir_etud
):
# enseignant (chargé de TD) ?
return allow_ens and user.id in (ens.id for ens in self.enseignants)
return True
def can_change_ens_by(self, user: User, raise_exc=False) -> bool:
"""Check if user can modify module resp.
If raise_exc, raises exception (AccessDenied or ScoLockedSemError) if not.

View File

@ -30,16 +30,17 @@
import collections
import datetime
import operator
import time
from flask import url_for
from flask import g
from flask_login import current_user
from flask import request
from app import db
from app.auth.models import User
from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre
from app.models import Evaluation, FormSemestre
import app.scodoc.sco_utils as scu
from app.scodoc.sco_utils import ModuleType
@ -645,78 +646,64 @@ def evaluation_describe(evaluation_id="", edit_in_place=True, link_saisie=True):
"""HTML description of evaluation, for page headers
edit_in_place: allow in-place editing when permitted (not implemented)
"""
E = sco_evaluation_db.get_evaluation_dict({"evaluation_id": evaluation_id})[0]
moduleimpl_id = E["moduleimpl_id"]
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0]
Mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
formsemestre_id = M["formsemestre_id"]
u = sco_users.user_info(M["responsable_id"])
resp = u["prenomnom"]
nomcomplet = u["nomcomplet"]
can_edit = sco_permissions_check.can_edit_notes(
current_user, moduleimpl_id, allow_ens=False
)
evaluation: Evaluation = Evaluation.query.get_or_404(evaluation_id)
modimpl = evaluation.moduleimpl
responsable: User = db.session.get(User, modimpl.responsable_id)
resp_nomprenom = responsable.get_prenomnom()
resp_nomcomplet = responsable.get_nomcomplet()
can_edit = modimpl.can_edit_notes(current_user, allow_ens=False)
link = (
'<span class="evallink"><a class="stdlink" href="evaluation_listenotes?moduleimpl_id=%s">voir toutes les notes du module</a></span>'
% moduleimpl_id
)
mod_descr = (
'<a href="moduleimpl_status?moduleimpl_id=%s">%s %s</a> <span class="resp">(resp. <a title="%s">%s</a>)</span> %s'
% (
moduleimpl_id,
Mod["code"] or "",
Mod["titre"] or "?",
nomcomplet,
resp,
link,
)
)
mod_descr = f"""<a href="{url_for("notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept,
moduleimpl_id=modimpl.id,
)}">{modimpl.module.code or ""} {modimpl.module.abbrev or modimpl.module.titre or "?"}</a>
<span class="resp">(resp. <a title="{resp_nomcomplet}">{resp_nomprenom}</a>)</span>
<span class="evallink"><a class="stdlink"
href="{url_for(
"notes.evaluation_listenotes",
scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id)
}">voir toutes les notes du module</a></span>
"""
etit = E["description"] or ""
if etit:
etit = ' "' + etit + '"'
if Mod["module_type"] == ModuleType.MALUS:
etit += ' <span class="eval_malus">(points de malus)</span>'
eval_titre = f' "{evaluation.description}"' if evaluation.description else ""
if modimpl.module.module_type == ModuleType.MALUS:
eval_titre += ' <span class="eval_malus">(points de malus)</span>'
H = [
'<span class="eval_title">Évaluation%s</span><p><b>Module : %s</b></p>'
% (etit, mod_descr)
f"""<span class="eval_title">Évaluation{eval_titre}</span>
<p><b>Module : {mod_descr}</b>
</p>"""
]
if Mod["module_type"] == ModuleType.MALUS:
if modimpl.module.module_type == ModuleType.MALUS:
# Indique l'UE
ue = sco_edit_ue.ue_list(args={"ue_id": Mod["ue_id"]})[0]
H.append("<p><b>UE : %(acronyme)s</b></p>" % ue)
ue = modimpl.module.ue
H.append(f"<p><b>UE : {ue.acronyme}</b></p>")
# store min/max values used by JS client-side checks:
H.append(
'<span id="eval_note_min" class="sco-hidden">-20.</span><span id="eval_note_max" class="sco-hidden">20.</span>'
"""<span id="eval_note_min" class="sco-hidden">-20.</span>
<span id="eval_note_max" class="sco-hidden">20.</span>"""
)
else:
# date et absences (pas pour evals de malus)
if E["jour"]:
jour = E["jour"]
H.append("<p>Réalisée le <b>%s</b> " % (jour))
if E["heure_debut"] != E["heure_fin"]:
H.append("de %s à %s " % (E["heure_debut"], E["heure_fin"]))
group_id = sco_groups.get_default_group(formsemestre_id)
if evaluation.date_debut is not None:
H.append(f"<p>Réalisée le <b>{evaluation.descr_date()}</b> ")
group_id = sco_groups.get_default_group(modimpl.formsemestre_id)
H.append(
f"""<span class="noprint"><a href="{url_for(
'assiduites.get_etat_abs_date',
f"""<span class="noprint"><a class="stdlink" href="{url_for(
'assiduites.get_etat_abs_date',
scodoc_dept=g.scodoc_dept,
group_ids=group_id,
desc=E["description"],
jour=E["jour"],
heure_debut=E["heure_debut"],
heure_fin=E["heure_fin"],
desc=evaluation.description or "",
date_debut=evaluation.date_debut.isoformat(),
date_fin=evaluation.date_fin.isoformat(),
)
}">(absences ce jour)</a></span>"""
)
else:
jour = "<em>pas de date</em>"
H.append("<p>Réalisée le <b>%s</b> " % (jour))
H.append("<p><em>sans date</em> ")
H.append(
'</p><p>Coefficient dans le module: <b>%s</b>, notes sur <span id="eval_note_max">%g</span> '
% (E["coefficient"], E["note_max"])
f"""</p><p>Coefficient dans le module: <b>{evaluation.coefficient or "0"}</b>,
notes sur <span id="eval_note_max">{(evaluation.note_max or 0):g}</span> """
)
H.append('<span id="eval_note_min" class="sco-hidden">0.</span>')
if can_edit:
@ -730,7 +717,7 @@ def evaluation_describe(evaluation_id="", edit_in_place=True, link_saisie=True):
if link_saisie:
H.append(
f"""
<a class="stdlink" href="{url_for(
<a style="margin-left: 12px;" class="stdlink" href="{url_for(
"notes.saisie_notes", scodoc_dept=g.scodoc_dept, evaluation_id=evaluation_id)
}">saisie des notes</a>
"""

View File

@ -1,8 +1,8 @@
import datetime
from flask import g, request, render_template
from flask import abort, url_for
from flask_login import current_user
from app import db
from app.comp import res_sem
@ -25,14 +25,16 @@ from app.views import ScoData
# ---------------
from app.scodoc.sco_permissions import Permission
from app.scodoc import html_sco_header
from app.scodoc import safehtml
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_preferences
from app.scodoc import sco_groups_view
from app.scodoc import sco_etud
from app.scodoc import sco_find_etud
from flask_login import current_user
from app.scodoc import sco_utils as scu
from app.scodoc import sco_assiduites as scass
from app.scodoc import sco_utils as scu
from app.scodoc.sco_exceptions import ScoValueError
from app.tables.visu_assiduites import TableAssi, etuds_sorted_from_ids
@ -735,13 +737,19 @@ def visu_assiduites_group():
@scodoc
@permission_required(Permission.ScoView)
def get_etat_abs_date():
infos_date = {
"jour": request.args.get("jour"),
"heure_debut": request.args.get("heure_debut"),
"heure_fin": request.args.get("heure_fin"),
"title": request.args.get("desc"),
}
"""date_debut, date_fin en ISO"""
date_debut_str = request.args.get("date_debut")
date_fin_str = request.args.get("date_fin")
title = request.args.get("desc")
group_ids: list[int] = request.args.get("group_ids", None)
try:
date_debut = datetime.datetime.fromisoformat(date_debut_str)
except ValueError as exc:
raise ScoValueError("date_debut invalide") from exc
try:
date_fin = datetime.datetime.fromisoformat(date_fin_str)
except ValueError as exc:
raise ScoValueError("date_fin invalide") from exc
if group_ids is None:
group_ids = []
else:
@ -754,14 +762,6 @@ def get_etat_abs_date():
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
for m in groups_infos.members
]
date_debut = scu.is_iso_formated(
f"{infos_date['jour']}T{infos_date['heure_debut'].replace('h',':')}", True
)
date_fin = scu.is_iso_formated(
f"{infos_date['jour']}T{infos_date['heure_fin'].replace('h',':')}", True
)
assiduites: Assiduite = Assiduite.query.filter(
Assiduite.etudid.in_([e["etudid"] for e in etuds])
)
@ -791,7 +791,7 @@ def get_etat_abs_date():
etudiants = list(sorted(etudiants, key=lambda x: x["nom"]))
header: str = html_sco_header.sco_header(
page_title=infos_date["title"],
page_title=safehtml.html_to_safe_html(title),
init_qtip=True,
)