Corrige anciennes formations incohérentes (indices de semestres). Plus de logs.

This commit is contained in:
Emmanuel Viennet 2022-09-08 01:20:04 +02:00
parent d2590c1f91
commit 57a62a10f4
6 changed files with 60 additions and 14 deletions

View File

@ -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()

View File

@ -66,7 +66,7 @@ class Module(db.Model):
super(Module, self).__init__(**kwargs)
def __repr__(self):
return f"<Module{ModuleType(self.module_type or ModuleType.STANDARD).name} id={self.id} code={self.code!r}>"
return f"<Module{ModuleType(self.module_type or ModuleType.STANDARD).name} id={self.id} code={self.code!r} semestre_id={self.semestre_id}>"
def to_dict(self, convert_objects=False, with_matiere=False, with_ue=False) -> dict:
"""If convert_objects, convert all attributes to native types

View File

@ -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(

View File

@ -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()

View File

@ -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

View File

@ -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('<tr class="formsemestre_status_green%s">' % fontorange)
H.append(f'<tr class="formsemestre_status_green{fontorange}">')
else:
H.append('<tr class="formsemestre_status%s">' % fontorange)
H.append(f'<tr class="formsemestre_status{fontorange}">')
H.append(
f"""<td class="formsemestre_status_code""><a
@ -1234,14 +1234,14 @@ def formsemestre_tableau_modules(
for coef in coefs:
if coef[1] > 0:
H.append(
f"""<span class="mod_coef_indicator"
f"""<span class="mod_coef_indicator"
title="{coef[0].acronyme}"
style="background: {
coef[0].color if coef[0].color is not None else 'blue'
}"></span>"""
)
else:
H.append(f"""<span class="mod_coef_indicator_zero"></span>""")
H.append("""<span class="mod_coef_indicator_zero"></span>""")
H.append("</a>")
H.append("</td>")
if mod.module_type in (