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
|
||||
"""
|
||||
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 app import db
|
||||
from app.auth.models import User
|
||||
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.sco_utils as scu
|
||||
from app.scodoc import sco_cache
|
||||
@ -65,9 +68,9 @@ from app.scodoc import sco_preferences
|
||||
from app.scodoc import sco_users
|
||||
|
||||
|
||||
def _default_sem_title(F):
|
||||
"""Default title for a semestre in formation F"""
|
||||
return F["titre"]
|
||||
def _default_sem_title(formation):
|
||||
"""Default title for a semestre in formation"""
|
||||
return formation.titre
|
||||
|
||||
|
||||
def formsemestre_createwithmodules():
|
||||
@ -140,6 +143,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
||||
if edit:
|
||||
formsemestre_id = int(vals["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 edit:
|
||||
# il faut ScoImplement pour creer un semestre
|
||||
@ -161,26 +165,25 @@ def do_formsemestre_createwithmodules(edit=False):
|
||||
allowed_user_names = list(uid2display.values()) + [""]
|
||||
#
|
||||
formation_id = int(vals["formation_id"])
|
||||
F = sco_formations.formation_list(args={"formation_id": formation_id})
|
||||
if not F:
|
||||
formation = Formation.query.get(formation_id)
|
||||
if formation is None:
|
||||
raise ScoValueError("Formation inexistante !")
|
||||
F = F[0]
|
||||
if not edit:
|
||||
initvalues = {"titre": _default_sem_title(F)}
|
||||
initvalues = {"titre": _default_sem_title(formation)}
|
||||
semestre_id = int(vals["semestre_id"])
|
||||
sem_module_ids = set()
|
||||
module_ids_set = set()
|
||||
else:
|
||||
# setup form init values
|
||||
initvalues = sem
|
||||
semestre_id = initvalues["semestre_id"]
|
||||
# add associated modules to tf-checked:
|
||||
ams = sco_moduleimpl.moduleimpl_list(formsemestre_id=formsemestre_id)
|
||||
sem_module_ids = set([x["module_id"] for x in ams])
|
||||
initvalues["tf-checked"] = ["MI" + str(x["module_id"]) for x in ams]
|
||||
for x in ams:
|
||||
initvalues["MI" + str(x["module_id"])] = uid2display.get(
|
||||
x["responsable_id"],
|
||||
f"inconnu numéro {x['responsable_id']} resp. de {x['moduleimpl_id']} !",
|
||||
module_ids_existing = [modimpl.module.id for modimpl in formsemestre.modimpls]
|
||||
module_ids_set = set(module_ids_existing)
|
||||
initvalues["tf-checked"] = ["MI" + str(x) for x in module_ids_existing]
|
||||
for modimpl in formsemestre.modimpls:
|
||||
initvalues[f"MI{modimpl.module.id}"] = uid2display.get(
|
||||
modimpl.responsable_id,
|
||||
f"inconnu numéro {modimpl.responsable_id} resp. de {modimpl.id} !",
|
||||
)
|
||||
|
||||
initvalues["responsable_id"] = uid2display.get(
|
||||
@ -192,15 +195,20 @@ def do_formsemestre_createwithmodules(edit=False):
|
||||
)
|
||||
|
||||
# Liste des ID de semestres
|
||||
if F["type_parcours"] is not None:
|
||||
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
|
||||
if formation.type_parcours is not None:
|
||||
parcours = sco_codes_parcours.get_parcours_from_code(formation.type_parcours)
|
||||
NB_SEM = parcours.NB_SEM
|
||||
else:
|
||||
NB_SEM = 10 # fallback, max 10 semestres
|
||||
if NB_SEM == 1:
|
||||
semestre_id_list = [-1]
|
||||
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 = []
|
||||
for sid in semestre_id_list:
|
||||
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
|
||||
le titre: ils seront automatiquement ajoutés <input type="button"
|
||||
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",
|
||||
"allowed_values": semestre_id_list,
|
||||
"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:
|
||||
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
|
||||
if edit:
|
||||
select_name = "%s!group_id" % mod["module_id"]
|
||||
@ -560,7 +576,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
||||
else:
|
||||
return ""
|
||||
|
||||
if mod["module_id"] in sem_module_ids:
|
||||
if mod["module_id"] in module_ids_set:
|
||||
disabled = "disabled"
|
||||
else:
|
||||
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>'
|
||||
|
||||
if tf[0] == 0 or msg:
|
||||
return (
|
||||
'<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>'
|
||||
% F
|
||||
+ msg
|
||||
+ str(tf[1])
|
||||
)
|
||||
return f"""<p>Formation <a class="discretelink" href="{
|
||||
url_for("notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formation_id)
|
||||
}"><em>{formation.titre}</em> ({formation.acronyme}), version {formation.version}, code {formation.formation_code}</a>
|
||||
</p>
|
||||
{msg}
|
||||
{tf[1]}
|
||||
"""
|
||||
elif tf[0] == -1:
|
||||
return "<h4>annulation</h4>"
|
||||
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)]
|
||||
)
|
||||
)
|
||||
# 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:
|
||||
# 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])
|
||||
# creation des modules
|
||||
for module_id in tf[2]["tf-checked"]:
|
||||
assert module_id[:2] == "MI"
|
||||
# création des modules
|
||||
for module_id in module_ids_checked:
|
||||
modargs = {
|
||||
"module_id": int(module_id[2:]),
|
||||
"module_id": module_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)
|
||||
flash("Nouveau semestre créé")
|
||||
return flask.redirect(
|
||||
"formsemestre_status?formsemestre_id=%s&head_message=Nouveau%%20semestre%%20créé"
|
||||
% formsemestre_id
|
||||
url_for(
|
||||
"notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre_id,
|
||||
)
|
||||
)
|
||||
else:
|
||||
# modification du semestre:
|
||||
# Modification du semestre:
|
||||
# on doit creer les modules nouvellement selectionnés
|
||||
# modifier ceux a modifier, et DETRUIRE ceux qui ne sont plus selectionnés.
|
||||
# Note: la destruction echouera s'il y a des objets dependants
|
||||
# (eg des evaluations définies)
|
||||
# nouveaux modules
|
||||
# (retire le "MI" du début du nom de champs)
|
||||
checkedmods = [int(x[2:]) for x in tf[2]["tf-checked"]]
|
||||
# modifier ceux à modifier, et DETRUIRE ceux qui ne sont plus selectionnés.
|
||||
# Note: la destruction échouera s'il y a des objets dépendants
|
||||
# (eg des évaluations définies)
|
||||
module_ids_tocreate = [
|
||||
x for x in module_ids_checked if not x in module_ids_existing
|
||||
]
|
||||
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])
|
||||
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 = []
|
||||
for module_id in mods_tocreate:
|
||||
for module_id in module_ids_tocreate:
|
||||
modargs = {
|
||||
"module_id": module_id,
|
||||
"formsemestre_id": formsemestre_id,
|
||||
@ -808,9 +841,11 @@ def do_formsemestre_createwithmodules(edit=False):
|
||||
% (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
|
||||
for module_id in mods_toedit:
|
||||
for module_id in module_ids_toedit:
|
||||
moduleimpl_id = sco_moduleimpl.moduleimpl_list(
|
||||
formsemestre_id=formsemestre_id, module_id=module_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):
|
||||
"""Delete moduleimpls
|
||||
module_ids_to_del: list of module_id (warning: not moduleimpl)
|
||||
|
Loading…
Reference in New Issue
Block a user