diff --git a/app/api/evaluations.py b/app/api/evaluations.py index 6643ea844..b1ffee788 100644 --- a/app/api/evaluations.py +++ b/app/api/evaluations.py @@ -273,5 +273,5 @@ def evaluation_delete(evaluation_id: int): sco_saisie_notes.evaluation_suppress_alln( evaluation_id=evaluation_id, dialog_confirmed=True ) - sco_evaluation_db.do_evaluation_delete(evaluation_id) + evaluation.delete() return "ok" diff --git a/app/models/evaluations.py b/app/models/evaluations.py index 235b7f74d..73659aa3d 100644 --- a/app/models/evaluations.py +++ b/app/models/evaluations.py @@ -141,6 +141,44 @@ class Evaluation(db.Model): n = 0 # the only one 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 {modimpl.module.titre}""", + url=url, + ) + def to_dict(self) -> dict: "Représentation dict (riche, compat ScoDoc 7)" e_dict = dict(self.__dict__) diff --git a/app/scodoc/sco_evaluation_db.py b/app/scodoc/sco_evaluation_db.py index 041daf342..38110c6c8 100644 --- a/app/scodoc/sco_evaluation_db.py +++ b/app/scodoc/sco_evaluation_db.py @@ -28,19 +28,17 @@ """Gestion évaluations (ScoDoc7, code en voie de modernisation) """ -import pprint - import flask from flask import url_for, g from flask_login import current_user 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 import app.scodoc.sco_utils as scu 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_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 {modimpl.module.titre}""", - url=url, - ) - - # ancien _notes_getall def do_evaluation_get_all_notes( evaluation_id, table="notes_notes", filter_suppressed=True, by_uid=None diff --git a/app/views/notes.py b/app/views/notes.py index 0ef193687..492f3493c 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -1654,30 +1654,37 @@ sco_publish( @scodoc7func def evaluation_delete(evaluation_id): """Form delete evaluation""" - El = sco_evaluation_db.get_evaluation_dict(args={"evaluation_id": evaluation_id}) - if not El: - raise ScoValueError("Evaluation inexistante ! (%s)" % evaluation_id) - E = El[0] - M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0] - Mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0] - tit = "Suppression de l'évaluation %(description)s (%(jour)s)" % E - etat = sco_evaluations.do_evaluation_etat(evaluation_id) + evaluation: Evaluation = ( + Evaluation.query.filter_by(id=evaluation_id) + .join(ModuleImpl) + .join(FormSemestre) + .filter_by(dept_id=g.scodoc_dept_id) + .first_or_404() + ) + + tit = f"""Suppression de l'évaluation {evaluation.description or ""} ({evaluation.descr_date()})""" + etat = sco_evaluations.do_evaluation_etat(evaluation.id) H = [ - html_sco_header.html_sem_header(tit, with_h2=False), - """

Module %(code)s %(titre)s

""" % Mod, - """

%s

""" % tit, - """

Opération irréversible. Si vous supprimez l'évaluation, vous ne pourrez pas retrouver les notes associées.

""", + f""" + {html_sco_header.html_sem_header(tit, with_h2=False)} +

Module {evaluation.moduleimpl.module.code} + {evaluation.moduleimpl.module.titre_str()}

+

{tit}

+

Opération irréversible. + Si vous supprimez l'évaluation, vous ne pourrez pas retrouver les notes associées. +

+ """, ] warning = False if etat["nb_notes_total"]: warning = True nb_desinscrits = etat["nb_notes_total"] - etat["nb_notes"] H.append( - """
Il y a %s notes""" % etat["nb_notes_total"] + f"""
Il y a {etat["nb_notes_total"]} notes""" ) if nb_desinscrits: 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""") if etat["nb_notes"] == 0: @@ -1687,8 +1694,13 @@ def evaluation_delete(evaluation_id): if etat["nb_notes"]: H.append( - """

Suppression impossible (effacer les notes d'abord)

retour au tableau de bord du module

""" - % E["moduleimpl_id"] + f"""

Suppression impossible (effacer les notes d'abord)

+

retour au tableau de bord du module +

+
""" ) return "\n".join(H) + html_sco_header.sco_footer() if warning: @@ -1698,7 +1710,7 @@ def evaluation_delete(evaluation_id): request.base_url, scu.get_request_args(), (("evaluation_id", {"input_type": "hidden"}),), - initvalues=E, + initvalues={"evaluation_id": evaluation.id}, submitlabel="Confirmer la suppression", cancelbutton="Annuler", ) @@ -1709,17 +1721,17 @@ def evaluation_delete(evaluation_id): url_for( "notes.moduleimpl_status", scodoc_dept=g.scodoc_dept, - moduleimpl_id=E["moduleimpl_id"], + moduleimpl_id=evaluation.moduleimpl_id, ) ) else: - sco_evaluation_db.do_evaluation_delete(E["evaluation_id"]) + evaluation.delete() return ( "\n".join(H) + f"""

OK, évaluation supprimée.

Continuer

""" + html_sco_header.sco_footer() ) diff --git a/tests/unit/test_notes_rattrapage.py b/tests/unit/test_notes_rattrapage.py index 45433886f..918a357c5 100644 --- a/tests/unit/test_notes_rattrapage.py +++ b/tests/unit/test_notes_rattrapage.py @@ -6,10 +6,9 @@ import app from app import db from app.comp import res_sem from app.comp.res_but import ResultatsSemestreBUT -from app.models import FormSemestre, ModuleImpl +from app.models import Evaluation, FormSemestre, ModuleImpl from app.scodoc import ( sco_bulletins, - sco_evaluation_db, sco_formsemestre, sco_saisie_notes, ) @@ -131,7 +130,9 @@ def test_notes_rattrapage(test_client): # Note moyenne: reviens à 10/20 assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(10.0) # 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( sem["formsemestre_id"], etud["etudid"] )