forked from ScoDoc/ScoDoc
BUT: modif semestre: modules de même semestre
This commit is contained in:
parent
920aeb066f
commit
d928a6be32
@ -28,13 +28,16 @@
|
|||||||
"""Form choix modules / responsables et creation formsemestre
|
"""Form choix modules / responsables et creation formsemestre
|
||||||
"""
|
"""
|
||||||
import flask
|
import flask
|
||||||
from flask import url_for, g, request
|
from flask import url_for, flash
|
||||||
|
from flask import g, request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
from app.models import APO_CODE_STR_LEN, SHORT_STR_LEN
|
from app.models import APO_CODE_STR_LEN, SHORT_STR_LEN
|
||||||
from app.models import ModuleImpl, Evaluation, EvaluationUEPoids
|
from app.models import Module, ModuleImpl, Evaluation, EvaluationUEPoids
|
||||||
|
from app.models.formations import Formation
|
||||||
|
from app.models.formsemestre import FormSemestre
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
@ -65,9 +68,9 @@ from app.scodoc import sco_preferences
|
|||||||
from app.scodoc import sco_users
|
from app.scodoc import sco_users
|
||||||
|
|
||||||
|
|
||||||
def _default_sem_title(F):
|
def _default_sem_title(formation):
|
||||||
"""Default title for a semestre in formation F"""
|
"""Default title for a semestre in formation"""
|
||||||
return F["titre"]
|
return formation.titre
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_createwithmodules():
|
def formsemestre_createwithmodules():
|
||||||
@ -140,6 +143,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
if edit:
|
if edit:
|
||||||
formsemestre_id = int(vals["formsemestre_id"])
|
formsemestre_id = int(vals["formsemestre_id"])
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||||
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
if not current_user.has_permission(Permission.ScoImplement):
|
if not current_user.has_permission(Permission.ScoImplement):
|
||||||
if not edit:
|
if not edit:
|
||||||
# il faut ScoImplement pour creer un semestre
|
# il faut ScoImplement pour creer un semestre
|
||||||
@ -161,26 +165,25 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
allowed_user_names = list(uid2display.values()) + [""]
|
allowed_user_names = list(uid2display.values()) + [""]
|
||||||
#
|
#
|
||||||
formation_id = int(vals["formation_id"])
|
formation_id = int(vals["formation_id"])
|
||||||
F = sco_formations.formation_list(args={"formation_id": formation_id})
|
formation = Formation.query.get(formation_id)
|
||||||
if not F:
|
if formation is None:
|
||||||
raise ScoValueError("Formation inexistante !")
|
raise ScoValueError("Formation inexistante !")
|
||||||
F = F[0]
|
|
||||||
if not edit:
|
if not edit:
|
||||||
initvalues = {"titre": _default_sem_title(F)}
|
initvalues = {"titre": _default_sem_title(formation)}
|
||||||
semestre_id = int(vals["semestre_id"])
|
semestre_id = int(vals["semestre_id"])
|
||||||
sem_module_ids = set()
|
module_ids_set = set()
|
||||||
else:
|
else:
|
||||||
# setup form init values
|
# setup form init values
|
||||||
initvalues = sem
|
initvalues = sem
|
||||||
semestre_id = initvalues["semestre_id"]
|
semestre_id = initvalues["semestre_id"]
|
||||||
# add associated modules to tf-checked:
|
# add associated modules to tf-checked:
|
||||||
ams = sco_moduleimpl.moduleimpl_list(formsemestre_id=formsemestre_id)
|
module_ids_existing = [modimpl.module.id for modimpl in formsemestre.modimpls]
|
||||||
sem_module_ids = set([x["module_id"] for x in ams])
|
module_ids_set = set(module_ids_existing)
|
||||||
initvalues["tf-checked"] = ["MI" + str(x["module_id"]) for x in ams]
|
initvalues["tf-checked"] = ["MI" + str(x) for x in module_ids_existing]
|
||||||
for x in ams:
|
for modimpl in formsemestre.modimpls:
|
||||||
initvalues["MI" + str(x["module_id"])] = uid2display.get(
|
initvalues[f"MI{modimpl.module.id}"] = uid2display.get(
|
||||||
x["responsable_id"],
|
modimpl.responsable_id,
|
||||||
f"inconnu numéro {x['responsable_id']} resp. de {x['moduleimpl_id']} !",
|
f"inconnu numéro {modimpl.responsable_id} resp. de {modimpl.id} !",
|
||||||
)
|
)
|
||||||
|
|
||||||
initvalues["responsable_id"] = uid2display.get(
|
initvalues["responsable_id"] = uid2display.get(
|
||||||
@ -192,15 +195,20 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Liste des ID de semestres
|
# Liste des ID de semestres
|
||||||
if F["type_parcours"] is not None:
|
if formation.type_parcours is not None:
|
||||||
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
|
parcours = sco_codes_parcours.get_parcours_from_code(formation.type_parcours)
|
||||||
NB_SEM = parcours.NB_SEM
|
NB_SEM = parcours.NB_SEM
|
||||||
else:
|
else:
|
||||||
NB_SEM = 10 # fallback, max 10 semestres
|
NB_SEM = 10 # fallback, max 10 semestres
|
||||||
if NB_SEM == 1:
|
if NB_SEM == 1:
|
||||||
semestre_id_list = [-1]
|
semestre_id_list = [-1]
|
||||||
else:
|
else:
|
||||||
semestre_id_list = [-1] + list(range(1, NB_SEM + 1))
|
if edit and formation.is_apc():
|
||||||
|
# en APC, ne permet pas de changer de semestre
|
||||||
|
semestre_id_list = [formsemestre.semestre_id]
|
||||||
|
else:
|
||||||
|
semestre_id_list = [-1] + list(range(1, NB_SEM + 1))
|
||||||
|
|
||||||
semestre_id_labels = []
|
semestre_id_labels = []
|
||||||
for sid in semestre_id_list:
|
for sid in semestre_id_list:
|
||||||
if sid == -1:
|
if sid == -1:
|
||||||
@ -319,7 +327,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
"explanation": """n'indiquez pas les dates, ni le semestre, ni la modalité dans
|
"explanation": """n'indiquez pas les dates, ni le semestre, ni la modalité dans
|
||||||
le titre: ils seront automatiquement ajoutés <input type="button"
|
le titre: ils seront automatiquement ajoutés <input type="button"
|
||||||
value="remettre titre par défaut" onClick="document.tf.titre.value='%s';"/>"""
|
value="remettre titre par défaut" onClick="document.tf.titre.value='%s';"/>"""
|
||||||
% _default_sem_title(F),
|
% _default_sem_title(formation),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -340,6 +348,9 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
"title": "Semestre dans la formation",
|
"title": "Semestre dans la formation",
|
||||||
"allowed_values": semestre_id_list,
|
"allowed_values": semestre_id_list,
|
||||||
"labels": semestre_id_labels,
|
"labels": semestre_id_labels,
|
||||||
|
"explanation": "en BUT, on ne peut pas modifier le semestre après création"
|
||||||
|
if formation.is_apc()
|
||||||
|
else "",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -549,7 +560,12 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
for mod in mods:
|
for mod in mods:
|
||||||
if mod["semestre_id"] == semestre_id:
|
if mod["semestre_id"] == semestre_id and (
|
||||||
|
(not edit) # creation => tous modules
|
||||||
|
or (not formation.is_apc()) # pas BUT, on peux mixer les semestres
|
||||||
|
or (semestre_id == formsemestre.semestre_id) # module du semestre
|
||||||
|
or (mod["module_id"] in module_ids_set) # module déjà présent
|
||||||
|
):
|
||||||
nbmod += 1
|
nbmod += 1
|
||||||
if edit:
|
if edit:
|
||||||
select_name = "%s!group_id" % mod["module_id"]
|
select_name = "%s!group_id" % mod["module_id"]
|
||||||
@ -560,7 +576,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
if mod["module_id"] in sem_module_ids:
|
if mod["module_id"] in module_ids_set:
|
||||||
disabled = "disabled"
|
disabled = "disabled"
|
||||||
else:
|
else:
|
||||||
disabled = ""
|
disabled = ""
|
||||||
@ -684,12 +700,13 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
msg = '<ul class="tf-msg"><li class="tf-msg">Code étape Apogée manquant</li></ul>'
|
msg = '<ul class="tf-msg"><li class="tf-msg">Code étape Apogée manquant</li></ul>'
|
||||||
|
|
||||||
if tf[0] == 0 or msg:
|
if tf[0] == 0 or msg:
|
||||||
return (
|
return f"""<p>Formation <a class="discretelink" href="{
|
||||||
'<p>Formation <a class="discretelink" href="ue_table?formation_id=%(formation_id)s"><em>%(titre)s</em> (%(acronyme)s), version %(version)s, code %(formation_code)s</a></p>'
|
url_for("notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formation_id)
|
||||||
% F
|
}"><em>{formation.titre}</em> ({formation.acronyme}), version {formation.version}, code {formation.formation_code}</a>
|
||||||
+ msg
|
</p>
|
||||||
+ str(tf[1])
|
{msg}
|
||||||
)
|
{tf[1]}
|
||||||
|
"""
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return "<h4>annulation</h4>"
|
return "<h4>annulation</h4>"
|
||||||
else:
|
else:
|
||||||
@ -735,42 +752,58 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
etape=tf[2]["etape_apo" + str(n)], vdi=tf[2]["vdi_apo" + str(n)]
|
etape=tf[2]["etape_apo" + str(n)], vdi=tf[2]["vdi_apo" + str(n)]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
# Modules sélectionnés:
|
||||||
|
# (retire le "MI" du début du nom de champs)
|
||||||
|
module_ids_checked = [int(x[2:]) for x in tf[2]["tf-checked"]]
|
||||||
if not edit:
|
if not edit:
|
||||||
# creation du semestre
|
if formation.is_apc():
|
||||||
|
_formsemestre_check_module_list(
|
||||||
|
module_ids_checked, tf[2]["semestre_id"]
|
||||||
|
)
|
||||||
|
# création du semestre
|
||||||
formsemestre_id = sco_formsemestre.do_formsemestre_create(tf[2])
|
formsemestre_id = sco_formsemestre.do_formsemestre_create(tf[2])
|
||||||
# creation des modules
|
# création des modules
|
||||||
for module_id in tf[2]["tf-checked"]:
|
for module_id in module_ids_checked:
|
||||||
assert module_id[:2] == "MI"
|
|
||||||
modargs = {
|
modargs = {
|
||||||
"module_id": int(module_id[2:]),
|
"module_id": module_id,
|
||||||
"formsemestre_id": formsemestre_id,
|
"formsemestre_id": formsemestre_id,
|
||||||
"responsable_id": tf[2][module_id],
|
"responsable_id": tf[2][f"MI{module_id}"],
|
||||||
}
|
}
|
||||||
_ = sco_moduleimpl.do_moduleimpl_create(modargs)
|
_ = sco_moduleimpl.do_moduleimpl_create(modargs)
|
||||||
|
flash("Nouveau semestre créé")
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
"formsemestre_status?formsemestre_id=%s&head_message=Nouveau%%20semestre%%20créé"
|
url_for(
|
||||||
% formsemestre_id
|
"notes.formsemestre_status",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# modification du semestre:
|
# Modification du semestre:
|
||||||
# on doit creer les modules nouvellement selectionnés
|
# on doit creer les modules nouvellement selectionnés
|
||||||
# modifier ceux a modifier, et DETRUIRE ceux qui ne sont plus selectionnés.
|
# modifier ceux à modifier, et DETRUIRE ceux qui ne sont plus selectionnés.
|
||||||
# Note: la destruction echouera s'il y a des objets dependants
|
# Note: la destruction échouera s'il y a des objets dépendants
|
||||||
# (eg des evaluations définies)
|
# (eg des évaluations définies)
|
||||||
# nouveaux modules
|
module_ids_tocreate = [
|
||||||
# (retire le "MI" du début du nom de champs)
|
x for x in module_ids_checked if not x in module_ids_existing
|
||||||
checkedmods = [int(x[2:]) for x in tf[2]["tf-checked"]]
|
]
|
||||||
|
if formation.is_apc():
|
||||||
|
_formsemestre_check_module_list(
|
||||||
|
module_ids_tocreate, tf[2]["semestre_id"]
|
||||||
|
)
|
||||||
|
# modules existants à modifier
|
||||||
|
module_ids_toedit = [
|
||||||
|
x for x in module_ids_checked if x in module_ids_existing
|
||||||
|
]
|
||||||
|
# modules à détruire
|
||||||
|
module_ids_todelete = [
|
||||||
|
x for x in module_ids_existing if not x in module_ids_checked
|
||||||
|
]
|
||||||
|
#
|
||||||
sco_formsemestre.do_formsemestre_edit(tf[2])
|
sco_formsemestre.do_formsemestre_edit(tf[2])
|
||||||
ams = sco_moduleimpl.moduleimpl_list(formsemestre_id=formsemestre_id)
|
|
||||||
existingmods = [x["module_id"] for x in ams]
|
|
||||||
mods_tocreate = [x for x in checkedmods if not x in existingmods]
|
|
||||||
# modules a existants a modifier
|
|
||||||
mods_toedit = [x for x in checkedmods if x in existingmods]
|
|
||||||
# modules a detruire
|
|
||||||
mods_todelete = [x for x in existingmods if not x in checkedmods]
|
|
||||||
#
|
#
|
||||||
msg = []
|
msg = []
|
||||||
for module_id in mods_tocreate:
|
for module_id in module_ids_tocreate:
|
||||||
modargs = {
|
modargs = {
|
||||||
"module_id": module_id,
|
"module_id": module_id,
|
||||||
"formsemestre_id": formsemestre_id,
|
"formsemestre_id": formsemestre_id,
|
||||||
@ -808,9 +841,11 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
% (module_id, moduleimpl_id)
|
% (module_id, moduleimpl_id)
|
||||||
)
|
)
|
||||||
#
|
#
|
||||||
ok, diag = formsemestre_delete_moduleimpls(formsemestre_id, mods_todelete)
|
ok, diag = formsemestre_delete_moduleimpls(
|
||||||
|
formsemestre_id, module_ids_todelete
|
||||||
|
)
|
||||||
msg += diag
|
msg += diag
|
||||||
for module_id in mods_toedit:
|
for module_id in module_ids_toedit:
|
||||||
moduleimpl_id = sco_moduleimpl.moduleimpl_list(
|
moduleimpl_id = sco_moduleimpl.moduleimpl_list(
|
||||||
formsemestre_id=formsemestre_id, module_id=module_id
|
formsemestre_id=formsemestre_id, module_id=module_id
|
||||||
)[0]["moduleimpl_id"]
|
)[0]["moduleimpl_id"]
|
||||||
@ -847,6 +882,22 @@ def do_formsemestre_createwithmodules(edit=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _formsemestre_check_module_list(module_ids, semestre_idx):
|
||||||
|
"""En APC: Vérifie que tous les modules de la liste
|
||||||
|
sont dans le semestre indiqué.
|
||||||
|
Sinon, raise ScoValueError.
|
||||||
|
"""
|
||||||
|
# vérification de la cohérence / modules / semestre
|
||||||
|
mod_sems_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}:
|
||||||
|
raise ScoValueError(
|
||||||
|
"Les modules sélectionnés ne sont pas tous dans le semestre choisi !",
|
||||||
|
dest_url="javascript:history.back();",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_delete_moduleimpls(formsemestre_id, module_ids_to_del):
|
def formsemestre_delete_moduleimpls(formsemestre_id, module_ids_to_del):
|
||||||
"""Delete moduleimpls
|
"""Delete moduleimpls
|
||||||
module_ids_to_del: list of module_id (warning: not moduleimpl)
|
module_ids_to_del: list of module_id (warning: not moduleimpl)
|
||||||
|
Loading…
Reference in New Issue
Block a user