forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -273,5 +273,5 @@ def evaluation_delete(evaluation_id: int):
|
|||||||
sco_saisie_notes.evaluation_suppress_alln(
|
sco_saisie_notes.evaluation_suppress_alln(
|
||||||
evaluation_id=evaluation_id, dialog_confirmed=True
|
evaluation_id=evaluation_id, dialog_confirmed=True
|
||||||
)
|
)
|
||||||
sco_evaluation_db.do_evaluation_delete(evaluation_id)
|
evaluation.delete()
|
||||||
return "ok"
|
return "ok"
|
||||||
|
@ -141,6 +141,44 @@ class Evaluation(db.Model):
|
|||||||
n = 0 # the only one
|
n = 0 # the only one
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
"delete evaluation (commit) (check permission)"
|
||||||
|
from app.scodoc import sco_evaluation_db
|
||||||
|
|
||||||
|
modimpl: ModuleImpl = self.moduleimpl
|
||||||
|
if not modimpl.can_edit_evaluation(current_user):
|
||||||
|
raise AccessDenied(
|
||||||
|
f"Modification évaluation impossible pour {current_user.get_nomplogin()}"
|
||||||
|
)
|
||||||
|
notes_db = sco_evaluation_db.do_evaluation_get_all_notes(
|
||||||
|
self.id
|
||||||
|
) # { etudid : value }
|
||||||
|
notes = [x["value"] for x in notes_db.values()]
|
||||||
|
if notes:
|
||||||
|
raise ScoValueError(
|
||||||
|
"Impossible de supprimer cette évaluation: il reste des notes"
|
||||||
|
)
|
||||||
|
log(f"deleting evaluation {self}")
|
||||||
|
db.session.delete(self)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# inval cache pour ce semestre
|
||||||
|
sco_cache.invalidate_formsemestre(formsemestre_id=modimpl.formsemestre_id)
|
||||||
|
# news
|
||||||
|
url = url_for(
|
||||||
|
"notes.moduleimpl_status",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
moduleimpl_id=modimpl.id,
|
||||||
|
)
|
||||||
|
ScolarNews.add(
|
||||||
|
typ=ScolarNews.NEWS_NOTE,
|
||||||
|
obj=modimpl.id,
|
||||||
|
text=f"""Suppression d'une évaluation dans <a href="{
|
||||||
|
url
|
||||||
|
}">{modimpl.module.titre}</a>""",
|
||||||
|
url=url,
|
||||||
|
)
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
"Représentation dict (riche, compat ScoDoc 7)"
|
"Représentation dict (riche, compat ScoDoc 7)"
|
||||||
e_dict = dict(self.__dict__)
|
e_dict = dict(self.__dict__)
|
||||||
|
@ -118,6 +118,32 @@ class ModuleImpl(db.Model):
|
|||||||
|
|
||||||
return False
|
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:
|
def can_change_ens_by(self, user: User, raise_exc=False) -> bool:
|
||||||
"""Check if user can modify module resp.
|
"""Check if user can modify module resp.
|
||||||
If raise_exc, raises exception (AccessDenied or ScoLockedSemError) if not.
|
If raise_exc, raises exception (AccessDenied or ScoLockedSemError) if not.
|
||||||
|
@ -28,19 +28,17 @@
|
|||||||
"""Gestion évaluations (ScoDoc7, code en voie de modernisation)
|
"""Gestion évaluations (ScoDoc7, code en voie de modernisation)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pprint
|
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import url_for, g
|
from flask import url_for, g
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
|
|
||||||
from app.models import Evaluation, ModuleImpl, ScolarNews
|
from app.models import Evaluation
|
||||||
from app.models.evaluations import check_convert_evaluation_args
|
from app.models.evaluations import check_convert_evaluation_args
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError
|
from app.scodoc.sco_exceptions import AccessDenied
|
||||||
|
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
@ -119,42 +117,6 @@ def do_evaluation_edit(args):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def do_evaluation_delete(evaluation_id):
|
|
||||||
"delete evaluation"
|
|
||||||
evaluation: Evaluation = Evaluation.query.get_or_404(evaluation_id)
|
|
||||||
modimpl: ModuleImpl = evaluation.moduleimpl
|
|
||||||
if not modimpl.can_edit_evaluation(current_user):
|
|
||||||
raise AccessDenied(
|
|
||||||
f"Modification évaluation impossible pour {current_user.get_nomplogin()}"
|
|
||||||
)
|
|
||||||
notes_db = do_evaluation_get_all_notes(evaluation_id) # { etudid : value }
|
|
||||||
notes = [x["value"] for x in notes_db.values()]
|
|
||||||
if notes:
|
|
||||||
raise ScoValueError(
|
|
||||||
"Impossible de supprimer cette évaluation: il reste des notes"
|
|
||||||
)
|
|
||||||
log(f"deleting evaluation {evaluation}")
|
|
||||||
db.session.delete(evaluation)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
# inval cache pour ce semestre
|
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id=modimpl.formsemestre_id)
|
|
||||||
# news
|
|
||||||
url = url_for(
|
|
||||||
"notes.moduleimpl_status",
|
|
||||||
scodoc_dept=g.scodoc_dept,
|
|
||||||
moduleimpl_id=modimpl.id,
|
|
||||||
)
|
|
||||||
ScolarNews.add(
|
|
||||||
typ=ScolarNews.NEWS_NOTE,
|
|
||||||
obj=modimpl.id,
|
|
||||||
text=f"""Suppression d'une évaluation dans <a href="{
|
|
||||||
url
|
|
||||||
}">{modimpl.module.titre}</a>""",
|
|
||||||
url=url,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ancien _notes_getall
|
# ancien _notes_getall
|
||||||
def do_evaluation_get_all_notes(
|
def do_evaluation_get_all_notes(
|
||||||
evaluation_id, table="notes_notes", filter_suppressed=True, by_uid=None
|
evaluation_id, table="notes_notes", filter_suppressed=True, by_uid=None
|
||||||
|
@ -30,16 +30,17 @@
|
|||||||
import collections
|
import collections
|
||||||
import datetime
|
import datetime
|
||||||
import operator
|
import operator
|
||||||
import time
|
|
||||||
|
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
from flask import g
|
from flask import g
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
|
from app import db
|
||||||
|
from app.auth.models import User
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
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
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.sco_utils import ModuleType
|
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
|
"""HTML description of evaluation, for page headers
|
||||||
edit_in_place: allow in-place editing when permitted (not implemented)
|
edit_in_place: allow in-place editing when permitted (not implemented)
|
||||||
"""
|
"""
|
||||||
E = sco_evaluation_db.get_evaluation_dict({"evaluation_id": evaluation_id})[0]
|
evaluation: Evaluation = Evaluation.query.get_or_404(evaluation_id)
|
||||||
moduleimpl_id = E["moduleimpl_id"]
|
modimpl = evaluation.moduleimpl
|
||||||
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0]
|
responsable: User = db.session.get(User, modimpl.responsable_id)
|
||||||
Mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
|
resp_nomprenom = responsable.get_prenomnom()
|
||||||
formsemestre_id = M["formsemestre_id"]
|
resp_nomcomplet = responsable.get_nomcomplet()
|
||||||
u = sco_users.user_info(M["responsable_id"])
|
can_edit = modimpl.can_edit_notes(current_user, allow_ens=False)
|
||||||
resp = u["prenomnom"]
|
|
||||||
nomcomplet = u["nomcomplet"]
|
|
||||||
can_edit = sco_permissions_check.can_edit_notes(
|
|
||||||
current_user, moduleimpl_id, allow_ens=False
|
|
||||||
)
|
|
||||||
|
|
||||||
link = (
|
mod_descr = f"""<a class="stdlink" href="{url_for("notes.moduleimpl_status",
|
||||||
'<span class="evallink"><a class="stdlink" href="evaluation_listenotes?moduleimpl_id=%s">voir toutes les notes du module</a></span>'
|
scodoc_dept=g.scodoc_dept,
|
||||||
% moduleimpl_id
|
moduleimpl_id=modimpl.id,
|
||||||
)
|
)}">{modimpl.module.code or ""} {modimpl.module.abbrev or modimpl.module.titre or "?"}</a>
|
||||||
mod_descr = (
|
<span class="resp">(resp. <a title="{resp_nomcomplet}">{resp_nomprenom}</a>)</span>
|
||||||
'<a href="moduleimpl_status?moduleimpl_id=%s">%s %s</a> <span class="resp">(resp. <a title="%s">%s</a>)</span> %s'
|
<span class="evallink"><a class="stdlink"
|
||||||
% (
|
href="{url_for(
|
||||||
moduleimpl_id,
|
"notes.evaluation_listenotes",
|
||||||
Mod["code"] or "",
|
scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id)
|
||||||
Mod["titre"] or "?",
|
}">voir toutes les notes du module</a></span>
|
||||||
nomcomplet,
|
"""
|
||||||
resp,
|
|
||||||
link,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
etit = E["description"] or ""
|
eval_titre = f' "{evaluation.description}"' if evaluation.description else ""
|
||||||
if etit:
|
if modimpl.module.module_type == ModuleType.MALUS:
|
||||||
etit = ' "' + etit + '"'
|
eval_titre += ' <span class="eval_malus">(points de malus)</span>'
|
||||||
if Mod["module_type"] == ModuleType.MALUS:
|
|
||||||
etit += ' <span class="eval_malus">(points de malus)</span>'
|
|
||||||
H = [
|
H = [
|
||||||
'<span class="eval_title">Évaluation%s</span><p><b>Module : %s</b></p>'
|
f"""<span class="eval_title">Évaluation{eval_titre}</span>
|
||||||
% (etit, mod_descr)
|
<p><b>Module : {mod_descr}</b>
|
||||||
|
</p>"""
|
||||||
]
|
]
|
||||||
if Mod["module_type"] == ModuleType.MALUS:
|
if modimpl.module.module_type == ModuleType.MALUS:
|
||||||
# Indique l'UE
|
# Indique l'UE
|
||||||
ue = sco_edit_ue.ue_list(args={"ue_id": Mod["ue_id"]})[0]
|
ue = modimpl.module.ue
|
||||||
H.append("<p><b>UE : %(acronyme)s</b></p>" % ue)
|
H.append(f"<p><b>UE : {ue.acronyme}</b></p>")
|
||||||
# store min/max values used by JS client-side checks:
|
# store min/max values used by JS client-side checks:
|
||||||
H.append(
|
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:
|
else:
|
||||||
# date et absences (pas pour evals de malus)
|
# date et absences (pas pour evals de malus)
|
||||||
if E["jour"]:
|
if evaluation.date_debut is not None:
|
||||||
jour = E["jour"]
|
H.append(f"<p>Réalisée le <b>{evaluation.descr_date()}</b> ")
|
||||||
H.append("<p>Réalisée le <b>%s</b> " % (jour))
|
group_id = sco_groups.get_default_group(modimpl.formsemestre_id)
|
||||||
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)
|
|
||||||
H.append(
|
H.append(
|
||||||
f"""<span class="noprint"><a href="{url_for(
|
f"""<span class="evallink"><a class="stdlink" href="{url_for(
|
||||||
'assiduites.get_etat_abs_date',
|
'assiduites.etat_abs_date',
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
group_ids=group_id,
|
group_ids=group_id,
|
||||||
desc=E["description"],
|
desc=evaluation.description or "",
|
||||||
jour=E["jour"],
|
date_debut=evaluation.date_debut.isoformat(),
|
||||||
heure_debut=E["heure_debut"],
|
date_fin=evaluation.date_fin.isoformat(),
|
||||||
heure_fin=E["heure_fin"],
|
|
||||||
)
|
)
|
||||||
}">(absences ce jour)</a></span>"""
|
}">absences ce jour</a></span>"""
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
jour = "<em>pas de date</em>"
|
H.append("<p><em>sans date</em> ")
|
||||||
H.append("<p>Réalisée le <b>%s</b> " % (jour))
|
|
||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
'</p><p>Coefficient dans le module: <b>%s</b>, notes sur <span id="eval_note_max">%g</span> '
|
f"""</p><p>Coefficient dans le module: <b>{evaluation.coefficient or "0"}</b>,
|
||||||
% (E["coefficient"], E["note_max"])
|
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>')
|
H.append('<span id="eval_note_min" class="sco-hidden">0.</span>')
|
||||||
if can_edit:
|
if can_edit:
|
||||||
@ -730,7 +717,7 @@ def evaluation_describe(evaluation_id="", edit_in_place=True, link_saisie=True):
|
|||||||
if link_saisie:
|
if link_saisie:
|
||||||
H.append(
|
H.append(
|
||||||
f"""
|
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)
|
"notes.saisie_notes", scodoc_dept=g.scodoc_dept, evaluation_id=evaluation_id)
|
||||||
}">saisie des notes</a>
|
}">saisie des notes</a>
|
||||||
"""
|
"""
|
||||||
|
@ -50,7 +50,6 @@ from app.scodoc import htmlutils
|
|||||||
from app.scodoc import sco_cal
|
from app.scodoc import sco_cal
|
||||||
from app.scodoc import sco_compute_moy
|
from app.scodoc import sco_compute_moy
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
from app.scodoc import sco_evaluation_db
|
|
||||||
from app.scodoc import sco_formsemestre_status
|
from app.scodoc import sco_formsemestre_status
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
@ -59,19 +58,15 @@ from app.tables import list_etuds
|
|||||||
|
|
||||||
|
|
||||||
# menu evaluation dans moduleimpl
|
# menu evaluation dans moduleimpl
|
||||||
def moduleimpl_evaluation_menu(evaluation_id, nbnotes=0) -> str:
|
def moduleimpl_evaluation_menu(evaluation: Evaluation, nbnotes: int = 0) -> str:
|
||||||
"Menu avec actions sur une evaluation"
|
"Menu avec actions sur une evaluation"
|
||||||
E = sco_evaluation_db.get_evaluation_dict({"evaluation_id": evaluation_id})[0]
|
modimpl: ModuleImpl = evaluation.moduleimpl
|
||||||
modimpl = sco_moduleimpl.moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
group_id = sco_groups.get_default_group(modimpl.formsemestre_id)
|
||||||
|
evaluation_id = evaluation.id
|
||||||
|
can_edit_notes = modimpl.can_edit_notes(current_user, allow_ens=False)
|
||||||
|
can_edit_notes_ens = modimpl.can_edit_notes(current_user)
|
||||||
|
|
||||||
group_id = sco_groups.get_default_group(modimpl["formsemestre_id"])
|
if can_edit_notes and nbnotes != 0:
|
||||||
|
|
||||||
if (
|
|
||||||
sco_permissions_check.can_edit_notes(
|
|
||||||
current_user, E["moduleimpl_id"], allow_ens=False
|
|
||||||
)
|
|
||||||
and nbnotes != 0
|
|
||||||
):
|
|
||||||
sup_label = "Supprimer évaluation impossible (il y a des notes)"
|
sup_label = "Supprimer évaluation impossible (il y a des notes)"
|
||||||
else:
|
else:
|
||||||
sup_label = "Supprimer évaluation"
|
sup_label = "Supprimer évaluation"
|
||||||
@ -83,9 +78,7 @@ def moduleimpl_evaluation_menu(evaluation_id, nbnotes=0) -> str:
|
|||||||
"args": {
|
"args": {
|
||||||
"evaluation_id": evaluation_id,
|
"evaluation_id": evaluation_id,
|
||||||
},
|
},
|
||||||
"enabled": sco_permissions_check.can_edit_notes(
|
"enabled": can_edit_notes_ens,
|
||||||
current_user, E["moduleimpl_id"]
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Modifier évaluation",
|
"title": "Modifier évaluation",
|
||||||
@ -93,9 +86,7 @@ def moduleimpl_evaluation_menu(evaluation_id, nbnotes=0) -> str:
|
|||||||
"args": {
|
"args": {
|
||||||
"evaluation_id": evaluation_id,
|
"evaluation_id": evaluation_id,
|
||||||
},
|
},
|
||||||
"enabled": sco_permissions_check.can_edit_notes(
|
"enabled": can_edit_notes,
|
||||||
current_user, E["moduleimpl_id"], allow_ens=False
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": sup_label,
|
"title": sup_label,
|
||||||
@ -103,10 +94,7 @@ def moduleimpl_evaluation_menu(evaluation_id, nbnotes=0) -> str:
|
|||||||
"args": {
|
"args": {
|
||||||
"evaluation_id": evaluation_id,
|
"evaluation_id": evaluation_id,
|
||||||
},
|
},
|
||||||
"enabled": nbnotes == 0
|
"enabled": nbnotes == 0 and can_edit_notes,
|
||||||
and sco_permissions_check.can_edit_notes(
|
|
||||||
current_user, E["moduleimpl_id"], allow_ens=False
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Supprimer toutes les notes",
|
"title": "Supprimer toutes les notes",
|
||||||
@ -114,9 +102,7 @@ def moduleimpl_evaluation_menu(evaluation_id, nbnotes=0) -> str:
|
|||||||
"args": {
|
"args": {
|
||||||
"evaluation_id": evaluation_id,
|
"evaluation_id": evaluation_id,
|
||||||
},
|
},
|
||||||
"enabled": sco_permissions_check.can_edit_notes(
|
"enabled": can_edit_notes,
|
||||||
current_user, E["moduleimpl_id"], allow_ens=False
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Afficher les notes",
|
"title": "Afficher les notes",
|
||||||
@ -132,21 +118,18 @@ def moduleimpl_evaluation_menu(evaluation_id, nbnotes=0) -> str:
|
|||||||
"args": {
|
"args": {
|
||||||
"evaluation_id": evaluation_id,
|
"evaluation_id": evaluation_id,
|
||||||
},
|
},
|
||||||
"enabled": sco_permissions_check.can_edit_notes(
|
"enabled": can_edit_notes_ens,
|
||||||
current_user, E["moduleimpl_id"]
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Absences ce jour",
|
"title": "Absences ce jour",
|
||||||
"endpoint": "assiduites.get_etat_abs_date",
|
"endpoint": "assiduites.etat_abs_date",
|
||||||
"args": {
|
"args": {
|
||||||
"group_ids": group_id,
|
"group_ids": group_id,
|
||||||
"desc": E["description"],
|
"desc": evaluation.description or "",
|
||||||
"jour": E["jour"],
|
"date_debut": evaluation.date_debut.isoformat(),
|
||||||
"heure_debut": E["heure_debut"],
|
"date_fin": evaluation.date_fin.isoformat(),
|
||||||
"heure_fin": E["heure_fin"],
|
|
||||||
},
|
},
|
||||||
"enabled": E["jour"],
|
"enabled": evaluation.date_debut is not None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Vérifier notes vs absents",
|
"title": "Vérifier notes vs absents",
|
||||||
@ -154,7 +137,7 @@ def moduleimpl_evaluation_menu(evaluation_id, nbnotes=0) -> str:
|
|||||||
"args": {
|
"args": {
|
||||||
"evaluation_id": evaluation_id,
|
"evaluation_id": evaluation_id,
|
||||||
},
|
},
|
||||||
"enabled": nbnotes > 0 and E["jour"],
|
"enabled": nbnotes > 0 and evaluation.date_debut is not None,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -714,7 +697,7 @@ def _ligne_evaluation(
|
|||||||
if can_edit_notes:
|
if can_edit_notes:
|
||||||
H.append(
|
H.append(
|
||||||
moduleimpl_evaluation_menu(
|
moduleimpl_evaluation_menu(
|
||||||
evaluation.id,
|
evaluation,
|
||||||
nbnotes=etat["nb_notes"],
|
nbnotes=etat["nb_notes"],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -1315,7 +1315,7 @@ a.smallbutton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
span.evallink {
|
span.evallink {
|
||||||
font-size: 80%;
|
margin-left: 16px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from flask import g, request, render_template
|
from flask import g, request, render_template
|
||||||
|
|
||||||
from flask import abort, url_for
|
from flask import abort, url_for
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app.comp import res_sem
|
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.sco_permissions import Permission
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
|
from app.scodoc import safehtml
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_groups_view
|
from app.scodoc import sco_groups_view
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_find_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_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
|
from app.tables.visu_assiduites import TableAssi, etuds_sorted_from_ids
|
||||||
|
|
||||||
@ -731,17 +733,23 @@ def visu_assiduites_group():
|
|||||||
).build()
|
).build()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/EtatAbsencesDate")
|
@bp.route("/etat_abs_date")
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
def get_etat_abs_date():
|
def etat_abs_date():
|
||||||
infos_date = {
|
"""date_debut, date_fin en ISO"""
|
||||||
"jour": request.args.get("jour"),
|
date_debut_str = request.args.get("date_debut")
|
||||||
"heure_debut": request.args.get("heure_debut"),
|
date_fin_str = request.args.get("date_fin")
|
||||||
"heure_fin": request.args.get("heure_fin"),
|
title = request.args.get("desc")
|
||||||
"title": request.args.get("desc"),
|
|
||||||
}
|
|
||||||
group_ids: list[int] = request.args.get("group_ids", None)
|
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:
|
if group_ids is None:
|
||||||
group_ids = []
|
group_ids = []
|
||||||
else:
|
else:
|
||||||
@ -754,14 +762,6 @@ def get_etat_abs_date():
|
|||||||
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
|
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
|
||||||
for m in groups_infos.members
|
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(
|
assiduites: Assiduite = Assiduite.query.filter(
|
||||||
Assiduite.etudid.in_([e["etudid"] for e in etuds])
|
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"]))
|
etudiants = list(sorted(etudiants, key=lambda x: x["nom"]))
|
||||||
|
|
||||||
header: str = html_sco_header.sco_header(
|
header: str = html_sco_header.sco_header(
|
||||||
page_title=infos_date["title"],
|
page_title=safehtml.html_to_safe_html(title),
|
||||||
init_qtip=True,
|
init_qtip=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1656,30 +1656,37 @@ sco_publish(
|
|||||||
@scodoc7func
|
@scodoc7func
|
||||||
def evaluation_delete(evaluation_id):
|
def evaluation_delete(evaluation_id):
|
||||||
"""Form delete evaluation"""
|
"""Form delete evaluation"""
|
||||||
El = sco_evaluation_db.get_evaluation_dict(args={"evaluation_id": evaluation_id})
|
evaluation: Evaluation = (
|
||||||
if not El:
|
Evaluation.query.filter_by(id=evaluation_id)
|
||||||
raise ScoValueError("Evaluation inexistante ! (%s)" % evaluation_id)
|
.join(ModuleImpl)
|
||||||
E = El[0]
|
.join(FormSemestre)
|
||||||
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
Mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
|
.first_or_404()
|
||||||
tit = "Suppression de l'évaluation %(description)s (%(jour)s)" % E
|
)
|
||||||
etat = sco_evaluations.do_evaluation_etat(evaluation_id)
|
|
||||||
|
tit = f"""Suppression de l'évaluation {evaluation.description or ""} ({evaluation.descr_date()})"""
|
||||||
|
etat = sco_evaluations.do_evaluation_etat(evaluation.id)
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.html_sem_header(tit, with_h2=False),
|
f"""
|
||||||
"""<h2 class="formsemestre">Module <tt>%(code)s</tt> %(titre)s</h2>""" % Mod,
|
{html_sco_header.html_sem_header(tit, with_h2=False)}
|
||||||
"""<h3>%s</h3>""" % tit,
|
<h2 class="formsemestre">Module <tt>{evaluation.moduleimpl.module.code}</tt>
|
||||||
"""<p class="help">Opération <span class="redboldtext">irréversible</span>. Si vous supprimez l'évaluation, vous ne pourrez pas retrouver les notes associées.</p>""",
|
{evaluation.moduleimpl.module.titre_str()}</h2>
|
||||||
|
<h3>{tit}</h3>
|
||||||
|
<p class="help">Opération <span class="redboldtext">irréversible</span>.
|
||||||
|
Si vous supprimez l'évaluation, vous ne pourrez pas retrouver les notes associées.
|
||||||
|
</p>
|
||||||
|
""",
|
||||||
]
|
]
|
||||||
warning = False
|
warning = False
|
||||||
if etat["nb_notes_total"]:
|
if etat["nb_notes_total"]:
|
||||||
warning = True
|
warning = True
|
||||||
nb_desinscrits = etat["nb_notes_total"] - etat["nb_notes"]
|
nb_desinscrits = etat["nb_notes_total"] - etat["nb_notes"]
|
||||||
H.append(
|
H.append(
|
||||||
"""<div class="ue_warning"><span>Il y a %s notes""" % etat["nb_notes_total"]
|
f"""<div class="ue_warning"><span>Il y a {etat["nb_notes_total"]} notes"""
|
||||||
)
|
)
|
||||||
if nb_desinscrits:
|
if nb_desinscrits:
|
||||||
H.append(
|
H.append(
|
||||||
""" (dont %s d'étudiants qui ne sont plus inscrits)""" % nb_desinscrits
|
""" (dont {nb_desinscrits} d'étudiants qui ne sont plus inscrits)"""
|
||||||
)
|
)
|
||||||
H.append(""" dans l'évaluation</span>""")
|
H.append(""" dans l'évaluation</span>""")
|
||||||
if etat["nb_notes"] == 0:
|
if etat["nb_notes"] == 0:
|
||||||
@ -1689,8 +1696,13 @@ def evaluation_delete(evaluation_id):
|
|||||||
|
|
||||||
if etat["nb_notes"]:
|
if etat["nb_notes"]:
|
||||||
H.append(
|
H.append(
|
||||||
"""<p>Suppression impossible (effacer les notes d'abord)</p><p><a class="stdlink" href="moduleimpl_status?moduleimpl_id=%s">retour au tableau de bord du module</a></p></div>"""
|
f"""<p>Suppression impossible (effacer les notes d'abord)</p>
|
||||||
% E["moduleimpl_id"]
|
<p><a class="stdlink" href="{
|
||||||
|
url_for("notes.moduleimpl_status",
|
||||||
|
scodoc_dept=g.scodoc_dept, moduleimpl_id=evaluation.moduleimpl_id)
|
||||||
|
}">retour au tableau de bord du module</a>
|
||||||
|
</p>
|
||||||
|
</div>"""
|
||||||
)
|
)
|
||||||
return "\n".join(H) + html_sco_header.sco_footer()
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
if warning:
|
if warning:
|
||||||
@ -1700,7 +1712,7 @@ def evaluation_delete(evaluation_id):
|
|||||||
request.base_url,
|
request.base_url,
|
||||||
scu.get_request_args(),
|
scu.get_request_args(),
|
||||||
(("evaluation_id", {"input_type": "hidden"}),),
|
(("evaluation_id", {"input_type": "hidden"}),),
|
||||||
initvalues=E,
|
initvalues={"evaluation_id": evaluation.id},
|
||||||
submitlabel="Confirmer la suppression",
|
submitlabel="Confirmer la suppression",
|
||||||
cancelbutton="Annuler",
|
cancelbutton="Annuler",
|
||||||
)
|
)
|
||||||
@ -1711,17 +1723,17 @@ def evaluation_delete(evaluation_id):
|
|||||||
url_for(
|
url_for(
|
||||||
"notes.moduleimpl_status",
|
"notes.moduleimpl_status",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
moduleimpl_id=E["moduleimpl_id"],
|
moduleimpl_id=evaluation.moduleimpl_id,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
sco_evaluation_db.do_evaluation_delete(E["evaluation_id"])
|
evaluation.delete()
|
||||||
return (
|
return (
|
||||||
"\n".join(H)
|
"\n".join(H)
|
||||||
+ f"""<p>OK, évaluation supprimée.</p>
|
+ f"""<p>OK, évaluation supprimée.</p>
|
||||||
<p><a class="stdlink" href="{
|
<p><a class="stdlink" href="{
|
||||||
url_for("notes.moduleimpl_status", scodoc_dept=g.scodoc_dept,
|
url_for("notes.moduleimpl_status", scodoc_dept=g.scodoc_dept,
|
||||||
moduleimpl_id=E["moduleimpl_id"])
|
moduleimpl_id=evaluation.moduleimpl_id)
|
||||||
}">Continuer</a></p>"""
|
}">Continuer</a></p>"""
|
||||||
+ html_sco_header.sco_footer()
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.6.15"
|
SCOVERSION = "9.6.16"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
@ -6,10 +6,9 @@ import app
|
|||||||
from app import db
|
from app import db
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_but import ResultatsSemestreBUT
|
from app.comp.res_but import ResultatsSemestreBUT
|
||||||
from app.models import FormSemestre, ModuleImpl
|
from app.models import Evaluation, FormSemestre, ModuleImpl
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
sco_bulletins,
|
sco_bulletins,
|
||||||
sco_evaluation_db,
|
|
||||||
sco_formsemestre,
|
sco_formsemestre,
|
||||||
sco_saisie_notes,
|
sco_saisie_notes,
|
||||||
)
|
)
|
||||||
@ -131,7 +130,9 @@ def test_notes_rattrapage(test_client):
|
|||||||
# Note moyenne: reviens à 10/20
|
# Note moyenne: reviens à 10/20
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(10.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(10.0)
|
||||||
# Supprime l'évaluation de rattrapage:
|
# Supprime l'évaluation de rattrapage:
|
||||||
sco_evaluation_db.do_evaluation_delete(e_rat["id"])
|
evaluation = db.session.get(Evaluation, e_rat["id"])
|
||||||
|
assert evaluation
|
||||||
|
evaluation.delete()
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user