forked from ScoDoc/ScoDoc
Nettoyage code + exception save note
This commit is contained in:
parent
cf72686ce4
commit
753578813e
@ -306,12 +306,12 @@ class ResultatsSemestreBUT(NotesTableCompat):
|
||||
|
||||
return ues_ids
|
||||
|
||||
def etud_has_decision(self, etudid):
|
||||
def etud_has_decision(self, etudid) -> bool:
|
||||
"""True s'il y a une décision de jury pour cet étudiant émanant de ce formsemestre.
|
||||
prend aussi en compte les autorisations de passage.
|
||||
Sous-classée en BUT pour les RCUEs et années.
|
||||
"""
|
||||
return (
|
||||
return bool(
|
||||
super().etud_has_decision(etudid)
|
||||
or ApcValidationAnnee.query.filter_by(
|
||||
formsemestre_id=self.formsemestre.id, etudid=etudid
|
||||
|
@ -283,12 +283,12 @@ class NotesTableCompat(ResultatsSemestre):
|
||||
]
|
||||
return etudids
|
||||
|
||||
def etud_has_decision(self, etudid):
|
||||
def etud_has_decision(self, etudid) -> bool:
|
||||
"""True s'il y a une décision de jury pour cet étudiant émanant de ce formsemestre.
|
||||
prend aussi en compte les autorisations de passage.
|
||||
Sous-classée en BUT pour les RCUEs et années.
|
||||
"""
|
||||
return (
|
||||
return bool(
|
||||
self.get_etud_decisions_ue(etudid)
|
||||
or self.get_etud_decision_sem(etudid)
|
||||
or ScolarAutorisationInscription.query.filter_by(
|
||||
|
@ -145,6 +145,18 @@ class Evaluation(db.Model):
|
||||
db.session.add(copy)
|
||||
return copy
|
||||
|
||||
def is_matin(self) -> bool:
|
||||
"Evaluation ayant lieu le matin (faux si pas de date)"
|
||||
heure_debut_dt = self.heure_debut or datetime.time(8, 00)
|
||||
# 8:00 au cas ou pas d'heure (note externe?)
|
||||
return bool(self.jour) and heure_debut_dt < datetime.time(12, 00)
|
||||
|
||||
def is_apresmidi(self) -> bool:
|
||||
"Evaluation ayant lieu l'après midi (faux si pas de date)"
|
||||
heure_debut_dt = self.heure_debut or datetime.time(8, 00)
|
||||
# 8:00 au cas ou pas d'heure (note externe?)
|
||||
return bool(self.jour) and heure_debut_dt >= datetime.time(12, 00)
|
||||
|
||||
def set_default_poids(self) -> bool:
|
||||
"""Initialize les poids bvers les UE à leurs valeurs par défaut
|
||||
C'est à dire à 1 si le coef. module/UE est non nul, 0 sinon.
|
||||
|
@ -255,9 +255,8 @@ def do_evaluation_get_all_notes(
|
||||
"""Toutes les notes pour une evaluation: { etudid : { 'value' : value, 'date' : date ... }}
|
||||
Attention: inclut aussi les notes des étudiants qui ne sont plus inscrits au module.
|
||||
"""
|
||||
do_cache = (
|
||||
filter_suppressed and table == "notes_notes" and (by_uid is None)
|
||||
) # pas de cache pour (rares) appels via undo_notes ou specifiant un enseignant
|
||||
# pas de cache pour (rares) appels via undo_notes ou specifiant un enseignant
|
||||
do_cache = filter_suppressed and table == "notes_notes" and (by_uid is None)
|
||||
if do_cache:
|
||||
r = sco_cache.EvaluationCache.get(evaluation_id)
|
||||
if r is not None:
|
||||
|
@ -433,7 +433,7 @@ def excel_simple_table(
|
||||
return ws.generate()
|
||||
|
||||
|
||||
def excel_feuille_saisie(e, titreannee, description, lines):
|
||||
def excel_feuille_saisie(evaluation: "Evaluation", titreannee, description, lines):
|
||||
"""Genere feuille excel pour saisie des notes.
|
||||
E: evaluation (dict)
|
||||
lines: liste de tuples
|
||||
@ -512,18 +512,20 @@ def excel_feuille_saisie(e, titreannee, description, lines):
|
||||
# description evaluation
|
||||
ws.append_single_cell_row(scu.unescape_html(description), style_titres)
|
||||
ws.append_single_cell_row(
|
||||
"Evaluation du %s (coef. %g)" % (e["jour"], e["coefficient"]), style
|
||||
"Evaluation du %s (coef. %g)"
|
||||
% (evaluation.jour or "sans date", evaluation.coefficient or 0.0),
|
||||
style,
|
||||
)
|
||||
# ligne blanche
|
||||
ws.append_blank_row()
|
||||
# code et titres colonnes
|
||||
ws.append_row(
|
||||
[
|
||||
ws.make_cell("!%s" % e["evaluation_id"], style_ro),
|
||||
ws.make_cell("!%s" % evaluation.id, style_ro),
|
||||
ws.make_cell("Nom", style_titres),
|
||||
ws.make_cell("Prénom", style_titres),
|
||||
ws.make_cell("Groupe", style_titres),
|
||||
ws.make_cell("Note sur %g" % e["note_max"], style_titres),
|
||||
ws.make_cell("Note sur %g" % (evaluation.note_max or 0.0), style_titres),
|
||||
ws.make_cell("Remarque", style_titres),
|
||||
]
|
||||
)
|
||||
|
@ -40,7 +40,7 @@ from app.auth.models import User
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models import Evaluation, FormSemestre
|
||||
from app.models import ModuleImpl, ScolarNews
|
||||
from app.models import ModuleImpl, NotesNotes, ScolarNews
|
||||
from app.models.etudiants import Identite
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc.sco_utils import ModuleType
|
||||
@ -50,7 +50,8 @@ from app.scodoc.sco_exceptions import (
|
||||
AccessDenied,
|
||||
InvalidNoteValue,
|
||||
NoteProcessError,
|
||||
ScoGenError,
|
||||
ScoBugCatcher,
|
||||
ScoException,
|
||||
ScoInvalidParamError,
|
||||
ScoValueError,
|
||||
)
|
||||
@ -63,7 +64,6 @@ from app.scodoc import sco_edit_module
|
||||
from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_evaluation_db
|
||||
from app.scodoc import sco_excel
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formsemestre_inscriptions
|
||||
from app.scodoc import sco_groups
|
||||
from app.scodoc import sco_groups_view
|
||||
@ -526,9 +526,8 @@ def notes_add(
|
||||
- si la note existe deja avec valeur distincte, ajoute une entree au log (notes_notes_log)
|
||||
Return tuple (nb_changed, nb_suppress, existing_decisions)
|
||||
"""
|
||||
now = psycopg2.Timestamp(
|
||||
*time.localtime()[:6]
|
||||
) # datetime.datetime.now().isoformat()
|
||||
now = psycopg2.Timestamp(*time.localtime()[:6])
|
||||
|
||||
# Verifie inscription et valeur note
|
||||
inscrits = {
|
||||
x[0]
|
||||
@ -550,11 +549,11 @@ def notes_add(
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
nb_changed = 0
|
||||
nb_suppress = 0
|
||||
E = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})[0]
|
||||
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
||||
existing_decisions = (
|
||||
[]
|
||||
) # etudids pour lesquels il y a une decision de jury et que la note change
|
||||
evaluation: Evaluation = Evaluation.query.get_or_404(evaluation_id)
|
||||
formsemestre: FormSemestre = evaluation.moduleimpl.formsemestre
|
||||
res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
# etudids pour lesquels il y a une decision de jury et que la note change:
|
||||
etudids_with_existing_decision = []
|
||||
try:
|
||||
for etudid, value in notes:
|
||||
changed = False
|
||||
@ -571,20 +570,29 @@ def notes_add(
|
||||
"date": now,
|
||||
}
|
||||
ndb.quote_dict(aa)
|
||||
cursor.execute(
|
||||
"""INSERT INTO notes_notes
|
||||
(etudid, evaluation_id, value, comment, date, uid)
|
||||
VALUES (%(etudid)s,%(evaluation_id)s,%(value)s,%(comment)s,%(date)s,%(uid)s)
|
||||
""",
|
||||
aa,
|
||||
)
|
||||
try:
|
||||
cursor.execute(
|
||||
"""INSERT INTO notes_notes
|
||||
(etudid, evaluation_id, value, comment, date, uid)
|
||||
VALUES (%(etudid)s,%(evaluation_id)s,%(value)s,%(comment)s,%(date)s,%(uid)s)
|
||||
""",
|
||||
aa,
|
||||
)
|
||||
except psycopg2.errors.UniqueViolation as exc:
|
||||
# XXX ne devrait pas arriver mais bug possible ici (non reproductible)
|
||||
existing_note = NotesNotes.query.filter_by(
|
||||
evaluation_id=evaluation_id, etudid=etudid
|
||||
).first()
|
||||
raise ScoBugCatcher(
|
||||
f"dup: existing={existing_note}"
|
||||
) from exc
|
||||
changed = True
|
||||
else:
|
||||
# il y a deja une note
|
||||
oldval = notes_db[etudid]["value"]
|
||||
if type(value) != type(oldval):
|
||||
changed = True
|
||||
elif type(value) == float and (
|
||||
elif isinstance(value, float) and (
|
||||
abs(value - oldval) > scu.NOTES_PRECISION
|
||||
):
|
||||
changed = True
|
||||
@ -646,26 +654,21 @@ def notes_add(
|
||||
nb_suppress += 1
|
||||
if changed:
|
||||
nb_changed += 1
|
||||
if has_existing_decision(M, E, etudid):
|
||||
existing_decisions.append(etudid)
|
||||
if res.etud_has_decision(etudid):
|
||||
etudids_with_existing_decision.append(etudid)
|
||||
except Exception as exc:
|
||||
log("*** exception in notes_add")
|
||||
if do_it:
|
||||
cnx.rollback() # abort
|
||||
# inval cache
|
||||
sco_cache.invalidate_formsemestre(
|
||||
formsemestre_id=M["formsemestre_id"]
|
||||
) # > modif notes (exception)
|
||||
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre.id)
|
||||
sco_cache.EvaluationCache.delete(evaluation_id)
|
||||
raise # XXX
|
||||
raise ScoGenError("Erreur enregistrement note: merci de ré-essayer") from exc
|
||||
raise ScoException from exc
|
||||
if do_it:
|
||||
cnx.commit()
|
||||
sco_cache.invalidate_formsemestre(
|
||||
formsemestre_id=M["formsemestre_id"]
|
||||
) # > modif notes
|
||||
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre.id)
|
||||
sco_cache.EvaluationCache.delete(evaluation_id)
|
||||
return nb_changed, nb_suppress, existing_decisions
|
||||
return nb_changed, nb_suppress, etudids_with_existing_decision
|
||||
|
||||
|
||||
def saisie_notes_tableur(evaluation_id, group_ids=()):
|
||||
@ -868,35 +871,35 @@ def saisie_notes_tableur(evaluation_id, group_ids=()):
|
||||
|
||||
def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
"""Document Excel pour saisie notes dans l'évaluation et les groupes indiqués"""
|
||||
evals = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||
if not evals:
|
||||
evaluation: Evaluation = Evaluation.query.get(evaluation_id)
|
||||
if not evaluation:
|
||||
raise ScoValueError("invalid evaluation_id")
|
||||
eval_dict = evals[0]
|
||||
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=eval_dict["moduleimpl_id"])[0]
|
||||
formsemestre_id = M["formsemestre_id"]
|
||||
Mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
|
||||
sem = sco_formsemestre.get_formsemestre(M["formsemestre_id"])
|
||||
mod_responsable = sco_users.user_info(M["responsable_id"])
|
||||
if eval_dict["jour"]:
|
||||
indication_date = ndb.DateDMYtoISO(eval_dict["jour"])
|
||||
modimpl = evaluation.moduleimpl
|
||||
formsemestre = modimpl.formsemestre
|
||||
mod_responsable = sco_users.user_info(modimpl.responsable_id)
|
||||
if evaluation.jour:
|
||||
indication_date = evaluation.jour.isoformat()
|
||||
else:
|
||||
indication_date = scu.sanitize_filename(eval_dict["description"])[:12]
|
||||
eval_name = "%s-%s" % (Mod["code"], indication_date)
|
||||
indication_date = scu.sanitize_filename(evaluation.description or "")[:12]
|
||||
eval_name = "%s-%s" % (evaluation.moduleimpl.module.code, indication_date)
|
||||
|
||||
if eval_dict["description"]:
|
||||
evaltitre = "%s du %s" % (eval_dict["description"], eval_dict["jour"])
|
||||
if evaluation.description:
|
||||
evaltitre = "%s du %s" % (
|
||||
evaluation.description,
|
||||
evaluation.jour.strftime("%d/%m/%Y"),
|
||||
)
|
||||
else:
|
||||
evaltitre = "évaluation du %s" % eval_dict["jour"]
|
||||
evaltitre = "évaluation du %s" % evaluation.jour.strftime("%d/%m/%Y")
|
||||
description = "%s en %s (%s) resp. %s" % (
|
||||
evaltitre,
|
||||
Mod["abbrev"] or "",
|
||||
Mod["code"] or "",
|
||||
evaluation.moduleimpl.module.abbrev or "",
|
||||
evaluation.moduleimpl.module.code,
|
||||
mod_responsable["prenomnom"],
|
||||
)
|
||||
|
||||
groups_infos = sco_groups_view.DisplayedGroupsInfos(
|
||||
group_ids=group_ids,
|
||||
formsemestre_id=formsemestre_id,
|
||||
formsemestre_id=formsemestre.id,
|
||||
select_all_when_unspecified=True,
|
||||
etat=None,
|
||||
)
|
||||
@ -919,15 +922,15 @@ def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
# une liste de liste de chaines: lignes de la feuille de calcul
|
||||
L = []
|
||||
|
||||
etuds = _get_sorted_etuds(eval_dict, etudids, formsemestre_id)
|
||||
etuds = _get_sorted_etuds(evaluation, etudids, formsemestre.id)
|
||||
for e in etuds:
|
||||
etudid = e["etudid"]
|
||||
groups = sco_groups.get_etud_groups(etudid, formsemestre_id)
|
||||
groups = sco_groups.get_etud_groups(etudid, formsemestre.id)
|
||||
grc = sco_groups.listgroups_abbrev(groups)
|
||||
|
||||
L.append(
|
||||
[
|
||||
"%s" % etudid,
|
||||
str(etudid),
|
||||
e["nom"].upper(),
|
||||
e["prenom"].lower().capitalize(),
|
||||
e["inscr"]["etat"],
|
||||
@ -939,29 +942,9 @@ def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
|
||||
filename = "notes_%s_%s" % (eval_name, gr_title_filename)
|
||||
xls = sco_excel.excel_feuille_saisie(
|
||||
eval_dict, sem["titreannee"], description, lines=L
|
||||
evaluation, formsemestre.titre_annee(), description, lines=L
|
||||
)
|
||||
return scu.send_file(xls, filename, scu.XLSX_SUFFIX, mime=scu.XLSX_MIMETYPE)
|
||||
# return sco_excel.send_excel_file(xls, filename)
|
||||
|
||||
|
||||
def has_existing_decision(M, E, etudid):
|
||||
"""Verifie s'il y a une validation pour cet etudiant dans ce semestre ou UE
|
||||
Si oui, return True
|
||||
"""
|
||||
formsemestre_id = M["formsemestre_id"]
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
if nt.get_etud_decision_sem(etudid):
|
||||
return True
|
||||
dec_ues = nt.get_etud_decisions_ue(etudid)
|
||||
if dec_ues:
|
||||
mod = sco_edit_module.module_list({"module_id": M["module_id"]})[0]
|
||||
ue_id = mod["ue_id"]
|
||||
if ue_id in dec_ues:
|
||||
return True # decision pour l'UE a laquelle appartient cette evaluation
|
||||
|
||||
return False # pas de decision de jury affectee par cette note
|
||||
|
||||
|
||||
# -----------------------------
|
||||
@ -973,20 +956,18 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
|
||||
if not isinstance(evaluation_id, int):
|
||||
raise ScoInvalidParamError()
|
||||
group_ids = [int(group_id) for group_id in (group_ids or [])]
|
||||
evals = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||
if not evals:
|
||||
evaluation: Evaluation = Evaluation.query.get(evaluation_id)
|
||||
if evaluation is None:
|
||||
raise ScoValueError("évaluation inexistante")
|
||||
E = evals[0]
|
||||
M = sco_moduleimpl.moduleimpl_withmodule_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
||||
formsemestre_id = M["formsemestre_id"]
|
||||
modimpl = evaluation.moduleimpl
|
||||
moduleimpl_status_url = url_for(
|
||||
"notes.moduleimpl_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
moduleimpl_id=E["moduleimpl_id"],
|
||||
moduleimpl_id=evaluation.moduleimpl_id,
|
||||
)
|
||||
# Check access
|
||||
# (admin, respformation, and responsable_id)
|
||||
if not sco_permissions_check.can_edit_notes(current_user, E["moduleimpl_id"]):
|
||||
if not sco_permissions_check.can_edit_notes(current_user, evaluation.moduleimpl_id):
|
||||
return f"""
|
||||
{html_sco_header.sco_header()}
|
||||
<h2>Modification des notes impossible pour {current_user.user_name}</h2>
|
||||
@ -1001,16 +982,16 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
|
||||
# Informations sur les groupes à afficher:
|
||||
groups_infos = sco_groups_view.DisplayedGroupsInfos(
|
||||
group_ids=group_ids,
|
||||
formsemestre_id=formsemestre_id,
|
||||
formsemestre_id=modimpl.formsemestre_id,
|
||||
select_all_when_unspecified=True,
|
||||
etat=None,
|
||||
)
|
||||
|
||||
if E["description"]:
|
||||
page_title = 'Saisie "%s"' % E["description"]
|
||||
else:
|
||||
page_title = "Saisie des notes"
|
||||
|
||||
page_title = (
|
||||
f'Saisie "{evaluation.description}"'
|
||||
if evaluation.description
|
||||
else "Saisie des notes"
|
||||
)
|
||||
# HTML page:
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
@ -1036,19 +1017,19 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
|
||||
"id": "menu_saisie_tableur",
|
||||
"endpoint": "notes.saisie_notes_tableur",
|
||||
"args": {
|
||||
"evaluation_id": E["evaluation_id"],
|
||||
"evaluation_id": evaluation.id,
|
||||
"group_ids": groups_infos.group_ids,
|
||||
},
|
||||
},
|
||||
{
|
||||
"title": "Voir toutes les notes du module",
|
||||
"endpoint": "notes.evaluation_listenotes",
|
||||
"args": {"moduleimpl_id": E["moduleimpl_id"]},
|
||||
"args": {"moduleimpl_id": evaluation.moduleimpl_id},
|
||||
},
|
||||
{
|
||||
"title": "Effacer toutes les notes de cette évaluation",
|
||||
"endpoint": "notes.evaluation_suppress_alln",
|
||||
"args": {"evaluation_id": E["evaluation_id"]},
|
||||
"args": {"evaluation_id": evaluation.id},
|
||||
},
|
||||
],
|
||||
alone=True,
|
||||
@ -1077,7 +1058,9 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
|
||||
)
|
||||
|
||||
# Le formulaire de saisie des notes:
|
||||
form = _form_saisie_notes(E, M, groups_infos, destination=moduleimpl_status_url)
|
||||
form = _form_saisie_notes(
|
||||
evaluation, modimpl, groups_infos, destination=moduleimpl_status_url
|
||||
)
|
||||
if form is None:
|
||||
return flask.redirect(moduleimpl_status_url)
|
||||
H.append(form)
|
||||
@ -1101,10 +1084,9 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def _get_sorted_etuds(eval_dict: dict, etudids: list, formsemestre_id: int):
|
||||
notes_db = sco_evaluation_db.do_evaluation_get_all_notes(
|
||||
eval_dict["evaluation_id"]
|
||||
) # Notes existantes
|
||||
def _get_sorted_etuds(evaluation: Evaluation, etudids: list, formsemestre_id: int):
|
||||
# Notes existantes
|
||||
notes_db = sco_evaluation_db.do_evaluation_get_all_notes(evaluation.id)
|
||||
cnx = ndb.GetDBConnexion()
|
||||
etuds = []
|
||||
for etudid in etudids:
|
||||
@ -1123,17 +1105,17 @@ def _get_sorted_etuds(eval_dict: dict, etudids: list, formsemestre_id: int):
|
||||
e["groups"] = sco_groups.get_etud_groups(etudid, formsemestre_id)
|
||||
|
||||
# Information sur absence (tenant compte de la demi-journée)
|
||||
jour_iso = ndb.DateDMYtoISO(eval_dict["jour"])
|
||||
jour_iso = evaluation.jour.isoformat() if evaluation.jour else ""
|
||||
warn_abs_lst = []
|
||||
if eval_dict["matin"]:
|
||||
nbabs = sco_abs.count_abs(etudid, jour_iso, jour_iso, matin=1)
|
||||
nbabsjust = sco_abs.count_abs_just(etudid, jour_iso, jour_iso, matin=1)
|
||||
if evaluation.is_matin():
|
||||
nbabs = sco_abs.count_abs(etudid, jour_iso, jour_iso, matin=True)
|
||||
nbabsjust = sco_abs.count_abs_just(etudid, jour_iso, jour_iso, matin=True)
|
||||
if nbabs:
|
||||
if nbabsjust:
|
||||
warn_abs_lst.append("absent justifié le matin !")
|
||||
else:
|
||||
warn_abs_lst.append("absent le matin !")
|
||||
if eval_dict["apresmidi"]:
|
||||
if evaluation.is_apresmidi():
|
||||
nbabs = sco_abs.count_abs(etudid, jour_iso, jour_iso, matin=0)
|
||||
nbabsjust = sco_abs.count_abs_just(etudid, jour_iso, jour_iso, matin=0)
|
||||
if nbabs:
|
||||
@ -1169,35 +1151,38 @@ def _get_sorted_etuds(eval_dict: dict, etudids: list, formsemestre_id: int):
|
||||
return etuds
|
||||
|
||||
|
||||
def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
def _form_saisie_notes(
|
||||
evaluation: Evaluation, modimpl: ModuleImpl, groups_infos, destination=""
|
||||
):
|
||||
"""Formulaire HTML saisie des notes dans l'évaluation E du moduleimpl M
|
||||
pour les groupes indiqués.
|
||||
|
||||
On charge tous les étudiants, ne seront montrés que ceux
|
||||
des groupes sélectionnés grace a un filtre en javascript.
|
||||
"""
|
||||
evaluation_id = E["evaluation_id"]
|
||||
formsemestre_id = M["formsemestre_id"]
|
||||
|
||||
formsemestre_id = modimpl.formsemestre_id
|
||||
formsemestre: FormSemestre = evaluation.moduleimpl.formsemestre
|
||||
res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
etudids = [
|
||||
x[0]
|
||||
for x in sco_groups.do_evaluation_listeetuds_groups(
|
||||
evaluation_id, getallstudents=True, include_demdef=True
|
||||
evaluation.id, getallstudents=True, include_demdef=True
|
||||
)
|
||||
]
|
||||
if not etudids:
|
||||
return '<div class="ue_warning"><span>Aucun étudiant sélectionné !</span></div>'
|
||||
|
||||
# Decisions de jury existantes ?
|
||||
decisions_jury = {etudid: has_existing_decision(M, E, etudid) for etudid in etudids}
|
||||
# Nb de decisions de jury (pour les inscrits à l'évaluation):
|
||||
# Décisions de jury existantes ?
|
||||
decisions_jury = {etudid: res.etud_has_decision(etudid) for etudid in etudids}
|
||||
|
||||
# Nb de décisions de jury (pour les inscrits à l'évaluation):
|
||||
nb_decisions = sum(decisions_jury.values())
|
||||
|
||||
etuds = _get_sorted_etuds(E, etudids, formsemestre_id)
|
||||
etuds = _get_sorted_etuds(evaluation, etudids, formsemestre_id)
|
||||
|
||||
# Build form:
|
||||
descr = [
|
||||
("evaluation_id", {"default": evaluation_id, "input_type": "hidden"}),
|
||||
("evaluation_id", {"default": evaluation.id, "input_type": "hidden"}),
|
||||
("formsemestre_id", {"default": formsemestre_id, "input_type": "hidden"}),
|
||||
(
|
||||
"group_ids",
|
||||
@ -1207,7 +1192,7 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
("comment", {"size": 44, "title": "Commentaire", "return_focus_next": True}),
|
||||
("changed", {"default": "0", "input_type": "hidden"}), # changed in JS
|
||||
]
|
||||
if M["module"]["module_type"] in (
|
||||
if modimpl.module.module_type in (
|
||||
ModuleType.STANDARD,
|
||||
ModuleType.RESSOURCE,
|
||||
ModuleType.SAE,
|
||||
@ -1220,11 +1205,11 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
"title": "Notes ",
|
||||
"cssclass": "formnote_bareme",
|
||||
"readonly": True,
|
||||
"default": " / %g" % E["note_max"],
|
||||
"default": " / %g" % evaluation.note_max,
|
||||
},
|
||||
)
|
||||
)
|
||||
elif M["module"]["module_type"] == ModuleType.MALUS:
|
||||
elif modimpl.module.module_type == ModuleType.MALUS:
|
||||
descr.append(
|
||||
(
|
||||
"s3",
|
||||
@ -1238,7 +1223,7 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise ValueError("invalid module type (%s)" % M["module"]["module_type"]) # bug
|
||||
raise ValueError(f"invalid module type ({modimpl.module.module_type})") # bug
|
||||
|
||||
initvalues = {}
|
||||
for e in etuds:
|
||||
@ -1248,7 +1233,7 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
if disabled:
|
||||
classdem = " etud_dem"
|
||||
etud_classes.append("etud_dem")
|
||||
disabled_attr = 'disabled="%d"' % disabled
|
||||
disabled_attr = f'disabled="{disabled}"'
|
||||
else:
|
||||
classdem = ""
|
||||
disabled_attr = ""
|
||||
@ -1265,18 +1250,17 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
)
|
||||
|
||||
# Historique des saisies de notes:
|
||||
if not disabled:
|
||||
explanation = (
|
||||
'<span id="hist_%s">' % etudid
|
||||
+ get_note_history_menu(evaluation_id, etudid)
|
||||
+ "</span>"
|
||||
)
|
||||
else:
|
||||
explanation = ""
|
||||
explanation = (
|
||||
""
|
||||
if disabled
|
||||
else f"""<span id="hist_{etudid}">{
|
||||
get_note_history_menu(evaluation.id, etudid)
|
||||
}</span>"""
|
||||
)
|
||||
explanation = e["absinfo"] + explanation
|
||||
|
||||
# Lien modif decision de jury:
|
||||
explanation += '<span id="jurylink_%s" class="jurylink"></span>' % etudid
|
||||
explanation += f'<span id="jurylink_{etudid}" class="jurylink"></span>'
|
||||
|
||||
# Valeur actuelle du champ:
|
||||
initvalues["note_" + str(etudid)] = e["val"]
|
||||
@ -1330,7 +1314,7 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
H.append(tf.getform()) # check and init
|
||||
H.append(
|
||||
f"""<a href="{url_for("notes.moduleimpl_status", scodoc_dept=g.scodoc_dept,
|
||||
moduleimpl_id=M["moduleimpl_id"])
|
||||
moduleimpl_id=modimpl.id)
|
||||
}" class="btn btn-primary">Terminer</a>
|
||||
"""
|
||||
)
|
||||
@ -1345,7 +1329,7 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
Mettre les notes manquantes à
|
||||
<input type="text" size="5" name="value"/>
|
||||
<input type="submit" value="OK"/>
|
||||
<input type="hidden" name="evaluation_id" value="{evaluation_id}"/>
|
||||
<input type="hidden" name="evaluation_id" value="{evaluation.id}"/>
|
||||
<input class="group_ids_str" type="hidden" name="group_ids_str" value="{
|
||||
",".join([str(x) for x in groups_infos.group_ids])
|
||||
}"/>
|
||||
@ -1364,10 +1348,8 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
||||
|
||||
def save_note(etudid=None, evaluation_id=None, value=None, comment=""):
|
||||
"""Enregistre une note (ajax)"""
|
||||
authuser = current_user
|
||||
log(
|
||||
"save_note: evaluation_id=%s etudid=%s uid=%s value=%s"
|
||||
% (evaluation_id, etudid, authuser, value)
|
||||
f"save_note: evaluation_id={evaluation_id} etudid={etudid} uid={current_user} value={value}"
|
||||
)
|
||||
E = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})[0]
|
||||
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
||||
@ -1380,13 +1362,13 @@ def save_note(etudid=None, evaluation_id=None, value=None, comment=""):
|
||||
)
|
||||
result = {"nbchanged": 0} # JSON
|
||||
# Check access: admin, respformation, or responsable_id
|
||||
if not sco_permissions_check.can_edit_notes(authuser, E["moduleimpl_id"]):
|
||||
if not sco_permissions_check.can_edit_notes(current_user, E["moduleimpl_id"]):
|
||||
result["status"] = "unauthorized"
|
||||
else:
|
||||
L, _, _, _, _ = _check_notes([(etudid, value)], E, Mod)
|
||||
if L:
|
||||
nbchanged, _, existing_decisions = notes_add(
|
||||
authuser, evaluation_id, L, comment=comment, do_it=True
|
||||
current_user, evaluation_id, L, comment=comment, do_it=True
|
||||
)
|
||||
ScolarNews.add(
|
||||
typ=ScolarNews.NEWS_NOTE,
|
||||
|
Loading…
Reference in New Issue
Block a user