From 57a62a10f4b3d4ee0f6bfeba5a37365bed107caa Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 8 Sep 2022 01:20:04 +0200 Subject: [PATCH] =?UTF-8?q?Corrige=20anciennes=20formations=20incoh=C3=A9r?= =?UTF-8?q?entes=20(indices=20de=20semestres).=20Plus=20de=20logs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/formations.py | 21 ++++++++++++++++++-- app/models/modules.py | 2 +- app/scodoc/sco_edit_module.py | 12 +++++++++--- app/scodoc/sco_edit_ue.py | 1 + app/scodoc/sco_formsemestre_edit.py | 28 ++++++++++++++++++++++++--- app/scodoc/sco_formsemestre_status.py | 10 +++++----- 6 files changed, 60 insertions(+), 14 deletions(-) diff --git a/app/models/formations.py b/app/models/formations.py index 167fef04..12627298 100644 --- a/app/models/formations.py +++ b/app/models/formations.py @@ -133,12 +133,15 @@ class Formation(db.Model): def sanitize_old_formation(self) -> None: """ Corrige si nécessaire certains champs issus d'anciennes versions de ScoDoc: + Pour les formations APC (BUT) seulement: - affecte à chaque module de cette formation le semestre de son UE de rattachement, si elle en a une. - si le module_type n'est pas renseigné, le met à STANDARD. + - on n'utilise pas de matières: réaffecte tous les modules + à la première matière de leur UE. - Devrait être appelé lorsqu'on change le type de formation vers le BUT, et aussi - lorsqu'on change le semestre d'une UE BUT. + Devrait être appelé lorsqu'on change le type de formation vers le BUT, + et aussi lorsqu'on change le semestre d'une UE BUT. Utile pour la migration des anciennes formations vers le BUT. En cas de changement, invalide les caches coefs/poids. @@ -164,6 +167,7 @@ class Formation(db.Model): # --- Numéros de modules if Module.query.filter_by(formation_id=self.id, numero=None).count() > 0: scu.objects_renumber(db, self.modules.all()) + # --- Types d'UE (avant de rendre le type non nullable) ues_sans_type = UniteEns.query.filter_by(formation_id=self.id, type=None) if ues_sans_type.count() > 0: @@ -171,6 +175,19 @@ class Formation(db.Model): ue.type = 0 db.session.add(ue) + # --- Réaffectation des matières: + for ue in self.ues: + mat = ue.matieres.first() + if mat is None: + mat = Matiere() + ue.matieres.append(mat) + db.session.add(mat) + for module in ue.modules: + if module.matiere_id != mat.id: + module.matiere = mat + db.session.add(module) + change = True + db.session.commit() if change: app.clear_scodoc_cache() diff --git a/app/models/modules.py b/app/models/modules.py index ad693069..904b8b63 100644 --- a/app/models/modules.py +++ b/app/models/modules.py @@ -66,7 +66,7 @@ class Module(db.Model): super(Module, self).__init__(**kwargs) def __repr__(self): - return f"" + return f"" def to_dict(self, convert_objects=False, with_matiere=False, with_ue=False) -> dict: """If convert_objects, convert all attributes to native types diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py index ef4cc3aa..e88e8c8a 100644 --- a/app/scodoc/sco_edit_module.py +++ b/app/scodoc/sco_edit_module.py @@ -98,12 +98,18 @@ def module_list(*args, **kw): def do_module_create(args) -> int: "Create a module. Returns id of new object." + formation = Formation.query.get(args["formation_id"]) + # refuse de créer un module APC avec semestres incohérents: + if formation.is_apc(): + ue = UniteEns.query.get(args["ue_id"]) + if int(args.get("semestre_id", 0)) != ue.semestre_idx: + raise ValueError("Formation incompatible: contacter le support ScoDoc") # create cnx = ndb.GetDBConnexion() - r = _moduleEditor.create(cnx, args) + module_id = _moduleEditor.create(cnx, args) + log(f"do_module_create: created {module_id} with {args}") # news - formation = Formation.query.get(args["formation_id"]) ScolarNews.add( typ=ScolarNews.NEWS_FORM, obj=formation.id, @@ -111,7 +117,7 @@ def do_module_create(args) -> int: max_frequency=10 * 60, ) formation.invalidate_cached_sems() - return r + return module_id def module_create( diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py index fe5326af..71236df0 100644 --- a/app/scodoc/sco_edit_ue.py +++ b/app/scodoc/sco_edit_ue.py @@ -129,6 +129,7 @@ def do_ue_create(args): args["ue_code"] = code # create ue_id = _ueEditor.create(cnx, args) + log(f"do_ue_create: created {ue_id} with {args}") formation: Formation = Formation.query.get(args["formation_id"]) formation.invalidate_module_coefs() diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py index 2677a6e2..794e7bca 100644 --- a/app/scodoc/sco_formsemestre_edit.py +++ b/app/scodoc/sco_formsemestre_edit.py @@ -951,8 +951,18 @@ def _formsemestre_check_module_list(module_ids, semestre_idx): Module.query.get_or_404(module_id).ue.semestre_idx for module_id in module_ids } if mod_sems_idx and mod_sems_idx != {semestre_idx}: + modules = [Module.query.get_or_404(module_id) for module_id in module_ids] + log( + f"""_formsemestre_check_module_list: + {chr(10).join( str(module) + " " + str(module.ue) for module in modules )} + """ + ) + for module in modules: + log( + f"{module.code}\tsemestre_id={module.semestre_id}\tue.semestre_idx={module.ue.semestre_idx}" + ) raise ScoValueError( - "Les modules sélectionnés ne sont pas tous dans le semestre choisi !", + f"Les modules sélectionnés ne sont pas tous dans le semestre choisi (S{semestre_idx}) !", dest_url="javascript:history.back();", ) @@ -1316,7 +1326,7 @@ def do_formsemestres_associate_new_version(formsemestre_ids): si elles existent (codes d'UE validées). Les semestre doivent tous appartenir à la meme version de la formation """ - log("do_formsemestres_associate_new_version %s" % formsemestre_ids) + log(f"do_formsemestres_associate_new_version {formsemestre_ids}") if not formsemestre_ids: return # Check: tous de la même formation @@ -1336,7 +1346,19 @@ def do_formsemestres_associate_new_version(formsemestre_ids): modules_old2new, ues_old2new, ) = sco_formations.formation_create_new_version(formation_id, redirect=False) - + # Log new ues: + for ue_id in ues_old2new: + ue = UniteEns.query.get(ue_id) + new_ue = UniteEns.query.get(ues_old2new[ue_id]) + assert ue.semestre_idx == new_ue.semestre_idx + log(f"{ue} -> {new_ue}") + # Log new modules + for module_id in modules_old2new: + mod = Module.query.get(module_id) + new_mod = Module.query.get(modules_old2new[module_id]) + assert mod.semestre_id == new_mod.semestre_id + log(f"{mod} -> {new_mod}") + # re-associate for formsemestre_id in formsemestre_ids: sem = sco_formsemestre.get_formsemestre(formsemestre_id) sem["formation_id"] = formation_id diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index f7e06134..a9cea70a 100644 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -1143,7 +1143,7 @@ def formsemestre_tableau_modules( H = [] prev_ue_id = None for modimpl in modimpls: - mod = Module.query.get(modimpl["module_id"]) + mod: Module = Module.query.get(modimpl["module_id"]) mod_descr = "Module " + (mod.titre or "") if mod.is_apc(): coef_descr = ", ".join( @@ -1204,9 +1204,9 @@ def formsemestre_tableau_modules( and etat["nb_evals_en_cours"] == 0 and etat["nb_evals_vides"] == 0 ): - H.append('' % fontorange) + H.append(f'') else: - H.append('' % fontorange) + H.append(f'') H.append( f""" 0: H.append( - f"""""" ) else: - H.append(f"""""") + H.append("""""") H.append("") H.append("") if mod.module_type in (