forked from ScoDoc/ScoDoc
Corrige et modernise associations formsemestres/programmes
This commit is contained in:
parent
b7a7bf1edc
commit
01308561d3
@ -928,7 +928,7 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
|||||||
H.append(
|
H.append(
|
||||||
f"""
|
f"""
|
||||||
<li><a class="stdlink" href="{
|
<li><a class="stdlink" href="{
|
||||||
url_for('notes.formsemestre_associate_new_version',
|
url_for('notes.formsemestre_associate_new_version',
|
||||||
scodoc_dept=g.scodoc_dept, formation_id=formation_id
|
scodoc_dept=g.scodoc_dept, formation_id=formation_id
|
||||||
)
|
)
|
||||||
}">Créer une nouvelle version de la formation</a> (copie non verrouillée)
|
}">Créer une nouvelle version de la formation</a> (copie non verrouillée)
|
||||||
|
@ -36,21 +36,18 @@ from app.models import (
|
|||||||
ModuleImpl,
|
ModuleImpl,
|
||||||
Evaluation,
|
Evaluation,
|
||||||
EvaluationUEPoids,
|
EvaluationUEPoids,
|
||||||
|
ScolarEvent,
|
||||||
|
ScolarFormSemestreValidation,
|
||||||
UniteEns,
|
UniteEns,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app.models.formations import Formation
|
from app.models.formations import Formation
|
||||||
from app.models.formsemestre import FormSemestre
|
from app.models.formsemestre import FormSemestre
|
||||||
import app.scodoc.notesdb as ndb
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
from app import log
|
from app import log
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc import sco_etud
|
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
from app.scodoc import sco_formsemestre
|
|
||||||
from app.scodoc import sco_moduleimpl
|
|
||||||
from app.scodoc import sco_cursus_dut
|
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_associate_new_version(
|
def formsemestre_associate_new_version(
|
||||||
@ -60,12 +57,11 @@ def formsemestre_associate_new_version(
|
|||||||
):
|
):
|
||||||
"""Formulaire nouvelle version formation et association d'un ou plusieurs formsemestre.
|
"""Formulaire nouvelle version formation et association d'un ou plusieurs formsemestre.
|
||||||
formation_id: la formation à dupliquer
|
formation_id: la formation à dupliquer
|
||||||
formsemestre_id: optionnel, formsemestre de départ, qui sera associé à la noiuvelle version
|
formsemestre_id: optionnel, formsemestre de départ, qui sera associé à la nouvelle version
|
||||||
"""
|
"""
|
||||||
if formsemestre_id is not None:
|
formsemestre_id = int(formsemestre_id) if formsemestre_id else None
|
||||||
formsemestre_id = int(formsemestre_id)
|
|
||||||
formation: Formation = Formation.query.get_or_404(formation_id)
|
formation: Formation = Formation.query.get_or_404(formation_id)
|
||||||
other_formsemestre_ids = {int(x) for x in other_formsemestre_ids or []}
|
other_formsemestre_ids = {int(x) for x in (other_formsemestre_ids or [])}
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
# dresse la liste des semestres non verrouillés de la même formation
|
# dresse la liste des semestres non verrouillés de la même formation
|
||||||
other_formsemestres: list[FormSemestre] = formation.formsemestres.filter_by(
|
other_formsemestres: list[FormSemestre] = formation.formsemestres.filter_by(
|
||||||
@ -90,7 +86,7 @@ def formsemestre_associate_new_version(
|
|||||||
f"""<div><input type="checkbox" name="other_formsemestre_ids:list"
|
f"""<div><input type="checkbox" name="other_formsemestre_ids:list"
|
||||||
value="{other_formsemestre.id}" {checked} {disabled}
|
value="{other_formsemestre.id}" {checked} {disabled}
|
||||||
><a class="stdlink" href="{
|
><a class="stdlink" href="{
|
||||||
url_for("notes.formsemestre_status",
|
url_for("notes.formsemestre_status",
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=other_formsemestre.id)
|
scodoc_dept=g.scodoc_dept, formsemestre_id=other_formsemestre.id)
|
||||||
}">{other_formsemestre.titre_mois()}</a></input></div>"""
|
}">{other_formsemestre.titre_mois()}</a></input></div>"""
|
||||||
)
|
)
|
||||||
@ -132,6 +128,9 @@ def formsemestre_associate_new_version(
|
|||||||
{ "".join(H) }
|
{ "".join(H) }
|
||||||
<p>Les données (étudiants, notes...) de ces semestres seront inchangées.</p>
|
<p>Les données (étudiants, notes...) de ces semestres seront inchangées.</p>
|
||||||
</div>
|
</div>
|
||||||
|
"""
|
||||||
|
+ (
|
||||||
|
f"""
|
||||||
<div class="othersemlist">
|
<div class="othersemlist">
|
||||||
Vous pouvez aussi essayer d'<a class="stdlink" href="{url_for(
|
Vous pouvez aussi essayer d'<a class="stdlink" href="{url_for(
|
||||||
"notes.formsemestre_change_formation",
|
"notes.formsemestre_change_formation",
|
||||||
@ -139,7 +138,10 @@ def formsemestre_associate_new_version(
|
|||||||
)}
|
)}
|
||||||
">associer ce semestre à une autre formation identique</a>.
|
">associer ce semestre à une autre formation identique</a>.
|
||||||
</div>
|
</div>
|
||||||
""",
|
"""
|
||||||
|
if formsemestre_id is not None
|
||||||
|
else ""
|
||||||
|
),
|
||||||
OK="Créer une nouvelle version et y associer ces semestres",
|
OK="Créer une nouvelle version et y associer ces semestres",
|
||||||
dest_url="",
|
dest_url="",
|
||||||
cancel_url=cancel_url,
|
cancel_url=cancel_url,
|
||||||
@ -189,14 +191,13 @@ def do_formsemestres_associate_new_version(
|
|||||||
"""
|
"""
|
||||||
log(f"do_formsemestres_associate_new_version {formation_id} {formsemestre_ids}")
|
log(f"do_formsemestres_associate_new_version {formation_id} {formsemestre_ids}")
|
||||||
|
|
||||||
# Check: tous les semestre de la formation
|
# Check: tous les semestres de la formation
|
||||||
formsemestres = [FormSemestre.query.get_or_404(i) for i in formsemestre_ids]
|
formsemestres = [FormSemestre.query.get_or_404(i) for i in formsemestre_ids]
|
||||||
if not all(
|
if not all(
|
||||||
[formsemestre.formation_id == formation_id for formsemestre in formsemestres]
|
[formsemestre.formation_id == formation_id for formsemestre in formsemestres]
|
||||||
):
|
):
|
||||||
raise ScoValueError("les semestres ne sont pas tous de la même formation !")
|
raise ScoValueError("les semestres ne sont pas tous de la même formation !")
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
|
||||||
# New formation:
|
# New formation:
|
||||||
(
|
(
|
||||||
formation_id,
|
formation_id,
|
||||||
@ -217,49 +218,51 @@ def do_formsemestres_associate_new_version(
|
|||||||
log(f"{mod} -> {new_mod}")
|
log(f"{mod} -> {new_mod}")
|
||||||
# re-associate
|
# re-associate
|
||||||
for formsemestre_id in formsemestre_ids:
|
for formsemestre_id in formsemestre_ids:
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||||
sem["formation_id"] = formation_id
|
formsemestre.formation_id = formation_id
|
||||||
sco_formsemestre.do_formsemestre_edit(sem, cnx=cnx, html_quote=False)
|
db.session.add(formsemestre)
|
||||||
_reassociate_moduleimpls(cnx, formsemestre_id, ues_old2new, modules_old2new)
|
_reassociate_moduleimpls(formsemestre, ues_old2new, modules_old2new)
|
||||||
|
|
||||||
cnx.commit()
|
db.session.commit()
|
||||||
return formation_id
|
return formation_id
|
||||||
|
|
||||||
|
|
||||||
def _reassociate_moduleimpls(cnx, formsemestre_id, ues_old2new, modules_old2new):
|
def _reassociate_moduleimpls(
|
||||||
|
formsemestre: FormSemestre,
|
||||||
|
ues_old2new: dict[int, int],
|
||||||
|
modules_old2new: dict[int, int],
|
||||||
|
):
|
||||||
"""Associe les moduleimpls d'un semestre existant à un autre programme
|
"""Associe les moduleimpls d'un semestre existant à un autre programme
|
||||||
et met à jour les décisions de jury (validations d'UE).
|
et met à jour les décisions de jury (validations d'UE).
|
||||||
"""
|
"""
|
||||||
# re-associate moduleimpls to new modules:
|
# re-associate moduleimpls to new modules:
|
||||||
modimpls = sco_moduleimpl.moduleimpl_list(formsemestre_id=formsemestre_id)
|
for modimpl in formsemestre.modimpls:
|
||||||
for mod in modimpls:
|
modimpl.module_id = modules_old2new[modimpl.module_id]
|
||||||
mod["module_id"] = modules_old2new[mod["module_id"]]
|
db.session.add(modimpl)
|
||||||
sco_moduleimpl.do_moduleimpl_edit(mod, formsemestre_id=formsemestre_id)
|
|
||||||
# Update poids des évaluations
|
# Update poids des évaluations
|
||||||
# les poids associent les évaluations aux UE (qui ont changé d'id)
|
# les poids associent les évaluations aux UE (qui ont changé d'id)
|
||||||
for poids in EvaluationUEPoids.query.filter(
|
for poids in EvaluationUEPoids.query.filter(
|
||||||
EvaluationUEPoids.evaluation_id == Evaluation.id,
|
EvaluationUEPoids.evaluation_id == Evaluation.id,
|
||||||
Evaluation.moduleimpl_id == ModuleImpl.id,
|
Evaluation.moduleimpl_id == ModuleImpl.id,
|
||||||
ModuleImpl.formsemestre_id == formsemestre_id,
|
ModuleImpl.formsemestre_id == formsemestre.id,
|
||||||
):
|
):
|
||||||
poids.ue_id = ues_old2new[poids.ue_id]
|
poids.ue_id = ues_old2new[poids.ue_id]
|
||||||
db.session.add(poids)
|
db.session.add(poids)
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
# update decisions:
|
# update decisions:
|
||||||
events = sco_etud.scolar_events_list(cnx, args={"formsemestre_id": formsemestre_id})
|
for event in ScolarEvent.query.filter_by(formsemestre_id=formsemestre.id):
|
||||||
for e in events:
|
if event.ue_id is not None:
|
||||||
if e["ue_id"]:
|
event.ue_id = ues_old2new[event.ue_id]
|
||||||
e["ue_id"] = ues_old2new[e["ue_id"]]
|
db.session.add(event)
|
||||||
sco_etud.scolar_events_edit(cnx, e)
|
|
||||||
validations = sco_cursus_dut.scolar_formsemestre_validation_list(
|
for validation in ScolarFormSemestreValidation.query.filter_by(
|
||||||
cnx, args={"formsemestre_id": formsemestre_id}
|
formsemestre_id=formsemestre.id
|
||||||
)
|
):
|
||||||
for e in validations:
|
if validation.ue_id is not None:
|
||||||
if e["ue_id"]:
|
validation.ue_id = ues_old2new[validation.ue_id]
|
||||||
e["ue_id"] = ues_old2new[e["ue_id"]]
|
db.session.add(validation)
|
||||||
# log('e=%s' % e )
|
|
||||||
sco_cursus_dut.scolar_formsemestre_validation_edit(cnx, e)
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
def formations_are_equals(
|
def formations_are_equals(
|
||||||
@ -294,7 +297,8 @@ def formsemestre_change_formation(formsemestre: FormSemestre, new_formation: For
|
|||||||
log(
|
log(
|
||||||
f"formsemestre_change_formation: formsemestre {formsemestre} to formation {new_formation}"
|
f"formsemestre_change_formation: formsemestre {formsemestre} to formation {new_formation}"
|
||||||
)
|
)
|
||||||
# Il faut ré-associer tous les modimpls
|
# Il faut ré-associer tous les modimpls et les UEs
|
||||||
|
modules_old2new = {}
|
||||||
for modimpl in formsemestre.modimpls:
|
for modimpl in formsemestre.modimpls:
|
||||||
old_module: Module = modimpl.module
|
old_module: Module = modimpl.module
|
||||||
new_module: Module = (
|
new_module: Module = (
|
||||||
@ -311,7 +315,19 @@ def formsemestre_change_formation(formsemestre: FormSemestre, new_formation: For
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"formsemestre_change_formation: erreur sur module {old_module}"
|
f"formsemestre_change_formation: erreur sur module {old_module}"
|
||||||
)
|
)
|
||||||
modimpl.module = new_module
|
modules_old2new[old_module.id] = new_module.id
|
||||||
db.session.add(modimpl)
|
|
||||||
|
ues_old2new = {}
|
||||||
|
for old_ue in formsemestre.formation.ues:
|
||||||
|
new_ue: UniteEns = UniteEns.query.filter_by(
|
||||||
|
formation_id=new_formation.id, acronyme=old_ue.acronyme, titre=old_ue.titre
|
||||||
|
).first()
|
||||||
|
if new_ue is None:
|
||||||
|
raise ValueError(f"formsemestre_change_formation: erreur sur UE {old_ue}")
|
||||||
|
ues_old2new[old_ue.id] = new_ue.id
|
||||||
|
|
||||||
formsemestre.formation = new_formation
|
formsemestre.formation = new_formation
|
||||||
|
db.session.add(formsemestre)
|
||||||
|
_reassociate_moduleimpls(formsemestre, ues_old2new, modules_old2new)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -24,7 +24,7 @@ et que l'on a oublié d'y rattacher un semestre.
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div>Aucune formation ne peut se substituer à celle de ce semestre.</div>
|
<div class="fontred">Aucune formation ne peut se substituer à celle de ce semestre.</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -29,11 +29,8 @@ Vues "modernes" des formsemestre
|
|||||||
Emmanuel Viennet, 2023
|
Emmanuel Viennet, 2023
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import flask
|
from flask import flash, redirect, render_template, url_for
|
||||||
from flask import abort, flash, redirect, render_template, url_for
|
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
from flask_login import current_user
|
|
||||||
from wtforms.validators import ValidationError
|
|
||||||
|
|
||||||
from app.decorators import (
|
from app.decorators import (
|
||||||
scodoc,
|
scodoc,
|
||||||
|
Loading…
Reference in New Issue
Block a user