diff --git a/app/but/jury_but.py b/app/but/jury_but.py index 9d56cb97b..86a5e4a9a 100644 --- a/app/but/jury_but.py +++ b/app/but/jury_but.py @@ -93,7 +93,7 @@ from app.scodoc import sco_cache from app.scodoc import sco_codes_parcours as sco_codes from app.scodoc.sco_codes_parcours import CODES_UE_VALIDES, RED, UE_STANDARD from app.scodoc import sco_utils as scu -from app.scodoc.sco_exceptions import ScoException, ScoValueError +from app.scodoc.sco_exceptions import ScoNoReferentielCompetences, ScoValueError class NoRCUEError(ScoValueError): @@ -205,6 +205,8 @@ class DecisionsProposeesAnnee(DecisionsProposees): formsemestre: FormSemestre, ): assert formsemestre.formation.is_apc() + if formsemestre.formation.referentiel_competence is None: + raise ScoNoReferentielCompetences(formation=formsemestre.formation) super().__init__(etud=etud) self.formsemestre = formsemestre "le formsemestre utilisé pour construire ce deca" @@ -1148,7 +1150,7 @@ class BUTCursusEtud: # WIP TODO def __init__(self, formsemestre: FormSemestre, etud: Identite): if formsemestre.formation.referentiel_competence is None: - raise ScoException("BUTCursusEtud: pas de référentiel de compétences") + raise ScoNoReferentielCompetences(formation=formsemestre.formation) assert len(etud.formsemestre_inscriptions) > 0 self.formsemestre = formsemestre self.etud = etud diff --git a/app/but/jury_but_recap.py b/app/but/jury_but_recap.py index ecaf1e116..386579575 100644 --- a/app/but/jury_but_recap.py +++ b/app/but/jury_but_recap.py @@ -32,7 +32,7 @@ from app.scodoc.sco_codes_parcours import ( from app.scodoc import sco_formsemestre_status from app.scodoc import sco_pvjury from app.scodoc import sco_utils as scu -from app.scodoc.sco_exceptions import ScoValueError +from app.scodoc.sco_exceptions import ScoNoReferentielCompetences def formsemestre_saisie_jury_but( @@ -63,14 +63,7 @@ def formsemestre_saisie_jury_but( # raise ScoValueError("Cette page ne fonctionne que sur les semestres pairs") if formsemestre2.formation.referentiel_competence is None: - raise ScoValueError( - """ -

Pas de référentiel de compétences associé à la formation !

-

Pour associer un référentiel, passer par le menu Semestre / - Voir la formation... et suivre le lien "associer à un référentiel - de compétences" - """ - ) + raise ScoNoReferentielCompetences(formation=formsemestre2.formation) rows, titles, column_ids, jury_stats = get_jury_but_table( formsemestre2, read_only=read_only, mode=mode diff --git a/app/models/but_refcomp.py b/app/models/but_refcomp.py index c8487ecf5..b1617212b 100644 --- a/app/models/but_refcomp.py +++ b/app/models/but_refcomp.py @@ -14,7 +14,7 @@ import sqlalchemy from app import db from app.scodoc.sco_utils import ModuleType -from app.scodoc.sco_exceptions import ScoValueError +from app.scodoc.sco_exceptions import ScoNoReferentielCompetences # from https://stackoverflow.com/questions/2537471/method-of-iterating-over-sqlalchemy-models-defined-columns @@ -322,9 +322,8 @@ class ApcNiveau(db.Model, XMLModel): if annee not in {1, 2, 3}: raise ValueError("annee invalide pour un parcours BUT") if referentiel_competence is None: - raise ScoValueError( - "Pas de référentiel de compétences associé à la formation !" - ) + raise ScoNoReferentielCompetences() + annee_formation = f"BUT{annee}" if parcour is None: return ApcNiveau.query.filter( diff --git a/app/scodoc/sco_exceptions.py b/app/scodoc/sco_exceptions.py index 226c1c9f7..7f4a67904 100644 --- a/app/scodoc/sco_exceptions.py +++ b/app/scodoc/sco_exceptions.py @@ -40,8 +40,9 @@ class InvalidNoteValue(ScoException): pass -# Exception qui stoque dest_url class ScoValueError(ScoException): + "Exception avec page d'erreur utilisateur, et qui stoque dest_url" + def __init__(self, msg, dest_url=None): super().__init__(msg) self.dest_url = dest_url @@ -74,7 +75,7 @@ class ScoFormatError(ScoValueError): class ScoInvalidParamError(ScoValueError): """Paramètres requete invalides. - A utilisée lorsqu'une route est appelée avec des paramètres invalides + Utilisée lorsqu'une route est appelée avec des paramètres invalides (id strings, ...) """ @@ -157,6 +158,23 @@ class ScoInvalidIdType(ScoValueError): super().__init__(msg) +class ScoNoReferentielCompetences(ScoValueError): + """Formation APC (BUT) non associée à référentiel de compétences""" + + def __init__(self, msg: str = "", formation: "Formation" = None): + formation_title = ( + f"{formation.title} version {formation.version}" if formation else "" + ) + msg = f""" +

Pas de référentiel de compétences associé à la formation {formation_title}! +

+

Pour associer un référentiel, passer par le menu Semestre / + Voir la formation... et suivre le lien "associer à un référentiel + de compétences" + """ + super().__init__(msg) + + class ScoGenError(ScoException): "exception avec affichage d'une page explicative ad-hoc" diff --git a/app/scodoc/sco_liste_notes.py b/app/scodoc/sco_liste_notes.py index e2a3890e7..2a63078b4 100644 --- a/app/scodoc/sco_liste_notes.py +++ b/app/scodoc/sco_liste_notes.py @@ -76,7 +76,7 @@ def do_evaluation_listenotes( else: raise ValueError("missing argument: evaluation or module") if not evals: - return "

Aucune évaluation !

", f"ScoDoc" + return "

Aucune évaluation !

", "ScoDoc" E = evals[0] # il y a au moins une evaluation modimpl = ModuleImpl.query.get(E["moduleimpl_id"]) @@ -244,7 +244,6 @@ def _make_table_notes( E = evals[0] moduleimpl_id = E["moduleimpl_id"] modimpl = ModuleImpl.query.get_or_404(moduleimpl_id) - modimpl_o = modimpl.to_dict() # TODO temporaire - à refactorer module: Module = modimpl.module formsemestre: FormSemestre = modimpl.formsemestre is_apc = module.formation.get_parcours().APC_SAE diff --git a/app/scodoc/sco_saisie_notes.py b/app/scodoc/sco_saisie_notes.py index d00a2dcba..3b980df04 100644 --- a/app/scodoc/sco_saisie_notes.py +++ b/app/scodoc/sco_saisie_notes.py @@ -426,16 +426,16 @@ def do_evaluation_set_missing( def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False): "suppress all notes in this eval" - E = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})[0] + evaluation = Evaluation.query.get_or_404(evaluation_id) if sco_permissions_check.can_edit_notes( - current_user, E["moduleimpl_id"], allow_ens=False + current_user, evaluation.moduleimpl_id, allow_ens=False ): # On a le droit de modifier toutes les notes # recupere les etuds ayant une note notes_db = sco_evaluation_db.do_evaluation_get_all_notes(evaluation_id) elif sco_permissions_check.can_edit_notes( - current_user, E["moduleimpl_id"], allow_ens=True + current_user, evaluation.moduleimpl_id, allow_ens=True ): # Enseignant associé au module: ne peut supprimer que les notes qu'il a saisi notes_db = sco_evaluation_db.do_evaluation_get_all_notes( @@ -449,7 +449,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False): status_url = url_for( "notes.moduleimpl_status", scodoc_dept=g.scodoc_dept, - moduleimpl_id=E["moduleimpl_id"], + moduleimpl_id=evaluation.moduleimpl_id, ) if not dialog_confirmed: @@ -495,13 +495,12 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False): """ ] # news - modimpl = ModuleImpl.query.get(E["moduleimpl_id"]) ScolarNews.add( typ=ScolarNews.NEWS_NOTE, - obj=modimpl.id, + obj=evaluation.moduleimpl.id, text=f"""Suppression des notes d'une évaluation dans {modimpl.module.titre or 'module sans titre'} + >{evaluation.moduleimpl.module.titre or 'module sans titre'} """, url=status_url, )