diff --git a/app/models/assiduites.py b/app/models/assiduites.py index 76ec9ea1..3d6a296c 100644 --- a/app/models/assiduites.py +++ b/app/models/assiduites.py @@ -4,6 +4,7 @@ from datetime import datetime from flask_login import current_user from flask_sqlalchemy.query import Query +from sqlalchemy.exc import DataError from app import db, log, g, set_sco_dept from app.models import ( @@ -249,50 +250,58 @@ class Assiduite(ScoDocModel): sco_abs_notification.abs_notify(etud.id, nouv_assiduite.date_debut) return nouv_assiduite - def set_moduleimpl(self, moduleimpl_id: int | str) -> bool: - """TODO""" - # je ne comprend pas cette fonction WIP - # moduleimpl_id peut être == "autre", ce qui plante - # ci-dessous un fix temporaire en attendant explication de @iziram - if moduleimpl_id is None: - raise ScoValueError("invalid moduleimpl_id") + def set_moduleimpl(self, moduleimpl_id: int | str): + """Mise à jour du moduleimpl_id + Les valeurs du champs "moduleimpl_id" possibles sont : + - (un id classique) + - ("autre" ou "") + - None (pas de moduleimpl_id) + Si la valeur est "autre" il faut: + - mettre à None assiduité.moduleimpl_id + - mettre à jour assiduite.external_data["module"] = "autre" + En fonction de la configuration du semestre la valeur `None` peut-être considérée comme invalide. + - Il faudra donc vérifier que ce n'est pas le cas avant de mettre à jour l'assiduité + """ + moduleimpl: ModuleImpl = None try: - moduleimpl_id_int = int(moduleimpl_id) - except ValueError as exc: - raise ScoValueError("invalid moduleimpl_id") from exc - # /fix - moduleimpl: ModuleImpl = ModuleImpl.query.get(moduleimpl_id_int) - if moduleimpl is not None: - # Vérification de l'inscription de l'étudiant + # ne lève une erreur que si moduleimpl_id est une chaine de caractère non parsable (parseInt) + moduleimpl: ModuleImpl = ModuleImpl.query.get(moduleimpl_id) + # moduleImpl est soit : + # - None si moduleimpl_id==None + # - None si moduleimpl_id== non reconnu + # - ModuleImpl si valide + + # Vérification ModuleImpl not None (raise ScoValueError) + if moduleimpl is None and self._check_force_module(moduleimpl): + # Ici uniquement si on est autorisé à ne pas avoir de module + self.moduleimpl_id = None + return + + # Vérification Inscription ModuleImpl (raise ScoValueError) if moduleimpl.est_inscrit(self.etudiant): self.moduleimpl_id = moduleimpl.id else: raise ScoValueError("L'étudiant n'est pas inscrit au module") - elif isinstance(moduleimpl_id, str): + + except DataError: + # On arrive ici si moduleimpl_id == "autre" ou moduleimpl_id == non parsé + + if moduleimpl_id != "autre": + raise ScoValueError("Module non reconnu") + + # Configuration de external_data pour Module Autre + # Si self.external_data None alors on créé un dictionnaire {"module": "autre"} + # Sinon on met à jour external_data["module"] à "autre" + if self.external_data is None: - self.external_data = {"module": moduleimpl_id} + self.external_data = {"module": "autre"} else: - self.external_data["module"] = moduleimpl_id + self.external_data["module"] = "autre" + + # Dans tous les cas une fois fait, assiduite.moduleimpl_id doit être None self.moduleimpl_id = None - else: - # Vérification si module forcé - formsemestre: FormSemestre = get_formsemestre_from_data( - { - "etudid": self.etudid, - "date_debut": self.date_debut, - "date_fin": self.date_fin, - } - ) - force: bool - if formsemestre: - force = is_assiduites_module_forced(formsemestre_id=formsemestre.id) - else: - force = is_assiduites_module_forced(dept_id=self.etudiant.dept_id) - - if force: - raise ScoValueError("Module non renseigné") - return True + # Ici pas de vérification du force module car on l'a mis dans "external_data" def supprime(self): "Supprime l'assiduité. Log et commit." @@ -351,6 +360,27 @@ class Assiduite(ScoDocModel): return f"saisie le {date} {utilisateur}" + def _check_force_module(self, moduleimpl: ModuleImpl) -> bool: + # Vérification si module forcé + formsemestre: FormSemestre = get_formsemestre_from_data( + { + "etudid": self.etudid, + "date_debut": self.date_debut, + "date_fin": self.date_fin, + } + ) + force: bool + + if formsemestre: + force = is_assiduites_module_forced(formsemestre_id=formsemestre.id) + else: + force = is_assiduites_module_forced(dept_id=self.etudiant.dept_id) + + if force: + raise ScoValueError("Module non renseigné") + + return True + class Justificatif(ScoDocModel): """ diff --git a/app/views/assiduites.py b/app/views/assiduites.py index a6108af2..bc9760b4 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -1570,20 +1570,10 @@ def _action_modifier_assiduite(assi: Assiduite): # Gestion de la description assi.description = form["description"] - module: str = form["moduleimpl_select"] - - if module == "": - module = None - else: - try: - module = int(module) - except ValueError: - pass - # TODO revoir, documenter (voir set_moduleimpl) - # ne pas appeler module ici un paramètre qui s'appelle moduleimpl_id dans la fonction - # module == instance de Module - # moduleimpl_id : id, toujours integer - assi.set_moduleimpl(module) + possible_moduleimpl_id: str = form["moduleimpl_select"] + + # Raise ScoValueError (si None et force module | Etudiant non inscrit | Module non reconnu) + assi.set_moduleimpl(possible_moduleimpl_id) db.session.add(assi) db.session.commit()