Assiduites : bug moduleimpl / autre fixes #827

This commit is contained in:
Iziram 2024-01-12 10:00:53 +01:00
parent bcb01089ca
commit 0fa35708f9
2 changed files with 69 additions and 49 deletions

View File

@ -4,6 +4,7 @@
from datetime import datetime from datetime import datetime
from flask_login import current_user from flask_login import current_user
from flask_sqlalchemy.query import Query from flask_sqlalchemy.query import Query
from sqlalchemy.exc import DataError
from app import db, log, g, set_sco_dept from app import db, log, g, set_sco_dept
from app.models import ( from app.models import (
@ -249,50 +250,58 @@ class Assiduite(ScoDocModel):
sco_abs_notification.abs_notify(etud.id, nouv_assiduite.date_debut) sco_abs_notification.abs_notify(etud.id, nouv_assiduite.date_debut)
return nouv_assiduite return nouv_assiduite
def set_moduleimpl(self, moduleimpl_id: int | str) -> bool: def set_moduleimpl(self, moduleimpl_id: int | str):
"""TODO""" """Mise à jour du moduleimpl_id
# je ne comprend pas cette fonction WIP Les valeurs du champs "moduleimpl_id" possibles sont :
# moduleimpl_id peut être == "autre", ce qui plante - <int> (un id classique)
# ci-dessous un fix temporaire en attendant explication de @iziram - <str> ("autre" ou "<id>")
if moduleimpl_id is None: - None (pas de moduleimpl_id)
raise ScoValueError("invalid 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: try:
moduleimpl_id_int = int(moduleimpl_id) # ne lève une erreur que si moduleimpl_id est une chaine de caractère non parsable (parseInt)
except ValueError as exc: moduleimpl: ModuleImpl = ModuleImpl.query.get(moduleimpl_id)
raise ScoValueError("invalid moduleimpl_id") from exc # moduleImpl est soit :
# /fix # - None si moduleimpl_id==None
moduleimpl: ModuleImpl = ModuleImpl.query.get(moduleimpl_id_int) # - None si moduleimpl_id==<int> non reconnu
if moduleimpl is not None: # - ModuleImpl si <int|str> valide
# Vérification de l'inscription de l'étudiant
# 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): if moduleimpl.est_inscrit(self.etudiant):
self.moduleimpl_id = moduleimpl.id self.moduleimpl_id = moduleimpl.id
else: else:
raise ScoValueError("L'étudiant n'est pas inscrit au module") 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 == <str> 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: if self.external_data is None:
self.external_data = {"module": moduleimpl_id} self.external_data = {"module": "autre"}
else: 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 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: # Ici pas de vérification du force module car on l'a mis dans "external_data"
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
def supprime(self): def supprime(self):
"Supprime l'assiduité. Log et commit." "Supprime l'assiduité. Log et commit."
@ -351,6 +360,27 @@ class Assiduite(ScoDocModel):
return f"saisie le {date} {utilisateur}" 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): class Justificatif(ScoDocModel):
""" """

View File

@ -1570,20 +1570,10 @@ def _action_modifier_assiduite(assi: Assiduite):
# Gestion de la description # Gestion de la description
assi.description = form["description"] assi.description = form["description"]
module: str = form["moduleimpl_select"] possible_moduleimpl_id: str = form["moduleimpl_select"]
if module == "": # Raise ScoValueError (si None et force module | Etudiant non inscrit | Module non reconnu)
module = None assi.set_moduleimpl(possible_moduleimpl_id)
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)
db.session.add(assi) db.session.add(assi)
db.session.commit() db.session.commit()