forked from ScoDoc/ScoDoc
Sépare les UE externes dans la pae édition programme
This commit is contained in:
parent
c49aecaa2f
commit
2fe9e5ec39
@ -597,6 +597,22 @@ def float_null_is_null(x):
|
||||
return float(x)
|
||||
|
||||
|
||||
BOOL_STR = {
|
||||
"": False,
|
||||
"false": False,
|
||||
"0": False,
|
||||
"1": True,
|
||||
"true": "true",
|
||||
}
|
||||
|
||||
|
||||
def bool_or_str(x):
|
||||
"""a boolean, may also be encoded as a string "0", "False", "1", "True" """
|
||||
if isinstance(x, str):
|
||||
return BOOL_STR[x.lower()]
|
||||
return x
|
||||
|
||||
|
||||
# post filtering
|
||||
#
|
||||
def UniqListofDicts(L, key):
|
||||
|
@ -190,7 +190,7 @@ def do_matiere_delete(oid):
|
||||
|
||||
|
||||
def matiere_delete(matiere_id=None):
|
||||
"""Delete an UE"""
|
||||
"""Delete matière"""
|
||||
from app.scodoc import sco_edit_ue
|
||||
|
||||
M = matiere_list(args={"matiere_id": matiere_id})[0]
|
||||
@ -200,7 +200,11 @@ def matiere_delete(matiere_id=None):
|
||||
"<h2>Suppression de la matière %(titre)s" % M,
|
||||
" dans l'UE (%(acronyme)s))</h2>" % UE,
|
||||
]
|
||||
dest_url = scu.NotesURL() + "/ue_list?formation_id=" + str(UE["formation_id"])
|
||||
dest_url = url_for(
|
||||
"notes.ue_table",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=str(UE["formation_id"]),
|
||||
)
|
||||
tf = TrivialFormulator(
|
||||
request.base_url,
|
||||
scu.get_request_args(),
|
||||
@ -227,13 +231,13 @@ def matiere_edit(matiere_id=None):
|
||||
if not F:
|
||||
raise ScoValueError("Matière inexistante !")
|
||||
F = F[0]
|
||||
U = sco_edit_ue.ue_list(args={"ue_id": F["ue_id"]})
|
||||
if not F:
|
||||
ues = sco_edit_ue.ue_list(args={"ue_id": F["ue_id"]})
|
||||
if not ues:
|
||||
raise ScoValueError("UE inexistante !")
|
||||
U = U[0]
|
||||
Fo = sco_formations.formation_list(args={"formation_id": U["formation_id"]})[0]
|
||||
ue = ues[0]
|
||||
Fo = sco_formations.formation_list(args={"formation_id": ue["formation_id"]})[0]
|
||||
|
||||
ues = sco_edit_ue.ue_list(args={"formation_id": U["formation_id"]})
|
||||
ues = sco_edit_ue.ue_list(args={"formation_id": ue["formation_id"]})
|
||||
ue_names = ["%(acronyme)s (%(titre)s)" % u for u in ues]
|
||||
ue_ids = [u["ue_id"] for u in ues]
|
||||
H = [
|
||||
@ -278,8 +282,11 @@ associé.
|
||||
submitlabel="Modifier les valeurs",
|
||||
)
|
||||
|
||||
dest_url = scu.NotesURL() + "/ue_list?formation_id=" + str(U["formation_id"])
|
||||
|
||||
dest_url = url_for(
|
||||
"notes.ue_table",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=str(ue["formation_id"]),
|
||||
)
|
||||
if tf[0] == 0:
|
||||
return "\n".join(H) + tf[1] + help + html_sco_header.sco_footer()
|
||||
elif tf[0] == -1:
|
||||
|
@ -285,21 +285,25 @@ def module_delete(module_id=None):
|
||||
"""Delete a module"""
|
||||
if not module_id:
|
||||
raise ScoValueError("invalid module !")
|
||||
Mods = module_list(args={"module_id": module_id})
|
||||
if not Mods:
|
||||
modules = module_list(args={"module_id": module_id})
|
||||
if not modules:
|
||||
raise ScoValueError("Module inexistant !")
|
||||
Mod = Mods[0]
|
||||
mod = modules[0]
|
||||
H = [
|
||||
html_sco_header.sco_header(page_title="Suppression d'un module"),
|
||||
"""<h2>Suppression du module %(titre)s (%(code)s)</h2>""" % Mod,
|
||||
"""<h2>Suppression du module %(titre)s (%(code)s)</h2>""" % mod,
|
||||
]
|
||||
|
||||
dest_url = scu.NotesURL() + "/ue_list?formation_id=" + str(Mod["formation_id"])
|
||||
dest_url = url_for(
|
||||
"notes.ue_table",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=str(mod["formation_id"]),
|
||||
)
|
||||
tf = TrivialFormulator(
|
||||
request.base_url,
|
||||
scu.get_request_args(),
|
||||
(("module_id", {"input_type": "hidden"}),),
|
||||
initvalues=Mod,
|
||||
initvalues=mod,
|
||||
submitlabel="Confirmer la suppression",
|
||||
cancelbutton="Annuler",
|
||||
)
|
||||
@ -367,9 +371,11 @@ def module_edit(module_id=None):
|
||||
Mod["ue_matiere_id"] = "%s!%s" % (Mod["ue_id"], Mod["matiere_id"])
|
||||
|
||||
semestres_indices = list(range(1, parcours.NB_SEM + 1))
|
||||
|
||||
dest_url = scu.NotesURL() + "/ue_list?formation_id=" + str(Mod["formation_id"])
|
||||
|
||||
dest_url = url_for(
|
||||
"notes.ue_table",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=str(Mod["formation_id"]),
|
||||
)
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title="Modification du module %(titre)s" % Mod,
|
||||
|
@ -75,7 +75,7 @@ _ueEditor = ndb.EditableTable(
|
||||
sortkey="numero",
|
||||
input_formators={
|
||||
"type": ndb.int_null_is_zero,
|
||||
"is_external": bool,
|
||||
"is_external": ndb.bool_or_str,
|
||||
},
|
||||
output_formators={
|
||||
"numero": ndb.int_null_is_zero,
|
||||
@ -139,7 +139,11 @@ def do_ue_delete(ue_id, delete_validations=False, force=False):
|
||||
% (len(validations), ue["acronyme"], ue["titre"]),
|
||||
dest_url="",
|
||||
target_variable="delete_validations",
|
||||
cancel_url="ue_list?formation_id=%s" % ue["formation_id"],
|
||||
cancel_url=url_for(
|
||||
"notes.ue_table",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=str(ue["formation_id"]),
|
||||
),
|
||||
parameters={"ue_id": ue_id, "dialog_confirmed": 1},
|
||||
)
|
||||
if delete_validations:
|
||||
@ -294,6 +298,14 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
||||
"explanation": "(optionnel) code élément pédagogique Apogée ou liste de codes ELP séparés par des virgules",
|
||||
},
|
||||
),
|
||||
(
|
||||
"is_external",
|
||||
{
|
||||
"input_type": "boolcheckbox",
|
||||
"title": "UE externe",
|
||||
"explanation": "réservé pour les capitalisations d'UE effectuées à l'extérieur de l'établissement",
|
||||
},
|
||||
),
|
||||
]
|
||||
if parcours.UE_IS_MODULE:
|
||||
# demande le semestre pour creer le module immediatement:
|
||||
@ -418,7 +430,11 @@ def ue_delete(ue_id=None, delete_validations=False, dialog_confirmed=False):
|
||||
"<h2>Suppression de l'UE %(titre)s (%(acronyme)s))</h2>" % ue,
|
||||
dest_url="",
|
||||
parameters={"ue_id": ue_id},
|
||||
cancel_url="ue_list?formation_id=%s" % ue["formation_id"],
|
||||
cancel_url=url_for(
|
||||
"notes.ue_table",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=str(ue["formation_id"]),
|
||||
),
|
||||
)
|
||||
|
||||
return do_ue_delete(ue_id, delete_validations=delete_validations)
|
||||
@ -438,21 +454,24 @@ def ue_table(formation_id=None, msg=""): # was ue_list
|
||||
parcours = sco_codes_parcours.get_parcours_from_code(F["type_parcours"])
|
||||
locked = sco_formations.formation_has_locked_sems(formation_id)
|
||||
|
||||
ues = ue_list(args={"formation_id": formation_id})
|
||||
ues = ue_list(args={"formation_id": formation_id, "is_external": False})
|
||||
ues_externes = ue_list(args={"formation_id": formation_id, "is_external": True})
|
||||
# tri par semestre et numero:
|
||||
_add_ue_semestre_id(ues)
|
||||
_add_ue_semestre_id(ues_externes)
|
||||
ues.sort(key=lambda u: (u["semestre_id"], u["numero"]))
|
||||
ues_externes.sort(key=lambda u: (u["semestre_id"], u["numero"]))
|
||||
has_duplicate_ue_codes = len(set([ue["ue_code"] for ue in ues])) != len(ues)
|
||||
|
||||
perm_change = current_user.has_permission(Permission.ScoChangeFormation)
|
||||
# editable = (not locked) and perm_change
|
||||
has_perm_change = current_user.has_permission(Permission.ScoChangeFormation)
|
||||
# editable = (not locked) and has_perm_change
|
||||
# On autorise maintanant la modification des formations qui ont des semestres verrouillés,
|
||||
# sauf si cela affect les notes passées (verrouillées):
|
||||
# - pas de modif des modules utilisés dans des semestres verrouillés
|
||||
# - pas de changement des codes d'UE utilisés dans des semestres verrouillés
|
||||
editable = perm_change
|
||||
editable = has_perm_change
|
||||
tag_editable = (
|
||||
current_user.has_permission(Permission.ScoEditFormationTags) or perm_change
|
||||
current_user.has_permission(Permission.ScoEditFormationTags) or has_perm_change
|
||||
)
|
||||
if locked:
|
||||
lockicon = scu.icontag("lock32_img", title="verrouillé")
|
||||
@ -556,213 +575,20 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
||||
H.append(
|
||||
'<form><input type="checkbox" class="sco_tag_checkbox">montrer les tags</input></form>'
|
||||
)
|
||||
|
||||
cur_ue_semestre_id = None
|
||||
iue = 0
|
||||
for UE in ues:
|
||||
if UE["ects"]:
|
||||
UE["ects_str"] = ", %g ECTS" % UE["ects"]
|
||||
else:
|
||||
UE["ects_str"] = ""
|
||||
if editable:
|
||||
klass = "span_apo_edit"
|
||||
else:
|
||||
klass = ""
|
||||
UE["code_apogee_str"] = (
|
||||
""", Apo: <span class="%s" data-url="edit_ue_set_code_apogee" id="%s" data-placeholder="%s">"""
|
||||
% (klass, UE["ue_id"], scu.APO_MISSING_CODE_STR)
|
||||
+ (UE["code_apogee"] or "")
|
||||
+ "</span>"
|
||||
H.append(
|
||||
_ue_table_ues(
|
||||
parcours,
|
||||
ues,
|
||||
editable,
|
||||
tag_editable,
|
||||
has_perm_change,
|
||||
arrow_up,
|
||||
arrow_down,
|
||||
arrow_none,
|
||||
delete_icon,
|
||||
delete_disabled_icon,
|
||||
)
|
||||
|
||||
if cur_ue_semestre_id != UE["semestre_id"]:
|
||||
cur_ue_semestre_id = UE["semestre_id"]
|
||||
if iue > 0:
|
||||
H.append("</ul>")
|
||||
if UE["semestre_id"] == sco_codes_parcours.UE_SEM_DEFAULT:
|
||||
lab = "Pas d'indication de semestre:"
|
||||
else:
|
||||
lab = "Semestre %s:" % UE["semestre_id"]
|
||||
H.append('<div class="ue_list_tit_sem">%s</div>' % lab)
|
||||
H.append('<ul class="notes_ue_list">')
|
||||
H.append('<li class="notes_ue_list">')
|
||||
if iue != 0 and editable:
|
||||
H.append(
|
||||
'<a href="ue_move?ue_id=%s&after=0" class="aud">%s</a>'
|
||||
% (UE["ue_id"], arrow_up)
|
||||
)
|
||||
else:
|
||||
H.append(arrow_none)
|
||||
if iue < len(ues) - 1 and editable:
|
||||
H.append(
|
||||
'<a href="ue_move?ue_id=%s&after=1" class="aud">%s</a>'
|
||||
% (UE["ue_id"], arrow_down)
|
||||
)
|
||||
else:
|
||||
H.append(arrow_none)
|
||||
iue += 1
|
||||
UE["acro_titre"] = str(UE["acronyme"])
|
||||
if UE["titre"] != UE["acronyme"]:
|
||||
UE["acro_titre"] += " " + str(UE["titre"])
|
||||
H.append(
|
||||
"""%(acro_titre)s <span class="ue_code">(code %(ue_code)s%(ects_str)s, coef. %(coefficient)3.2f%(code_apogee_str)s)</span>
|
||||
<span class="ue_coef"></span>
|
||||
"""
|
||||
% UE
|
||||
)
|
||||
|
||||
if UE["type"] != sco_codes_parcours.UE_STANDARD:
|
||||
H.append(
|
||||
'<span class="ue_type">%s</span>'
|
||||
% sco_codes_parcours.UE_TYPE_NAME[UE["type"]]
|
||||
)
|
||||
ue_editable = editable and not ue_is_locked(UE["ue_id"])
|
||||
if ue_editable:
|
||||
H.append(
|
||||
'<a class="stdlink" href="ue_edit?ue_id=%(ue_id)s">modifier</a>' % UE
|
||||
)
|
||||
else:
|
||||
H.append('<span class="locked">[verrouillé]</span>')
|
||||
if not parcours.UE_IS_MODULE:
|
||||
H.append('<ul class="notes_matiere_list">')
|
||||
Matlist = sco_edit_matiere.matiere_list(args={"ue_id": UE["ue_id"]})
|
||||
for Mat in Matlist:
|
||||
if not parcours.UE_IS_MODULE:
|
||||
H.append('<li class="notes_matiere_list">')
|
||||
if editable and not sco_edit_matiere.matiere_is_locked(
|
||||
Mat["matiere_id"]
|
||||
):
|
||||
H.append(
|
||||
f"""<a class="stdlink" href="{
|
||||
url_for("notes.matiere_edit",
|
||||
scodoc_dept=g.scodoc_dept, matiere_id=Mat["matiere_id"])
|
||||
}">
|
||||
"""
|
||||
)
|
||||
H.append("%(titre)s" % Mat)
|
||||
if editable and not sco_edit_matiere.matiere_is_locked(
|
||||
Mat["matiere_id"]
|
||||
):
|
||||
H.append("</a>")
|
||||
|
||||
H.append('<ul class="notes_module_list">')
|
||||
Modlist = sco_edit_module.module_list(
|
||||
args={"matiere_id": Mat["matiere_id"]}
|
||||
)
|
||||
im = 0
|
||||
for Mod in Modlist:
|
||||
Mod["nb_moduleimpls"] = sco_edit_module.module_count_moduleimpls(
|
||||
Mod["module_id"]
|
||||
)
|
||||
klass = "notes_module_list"
|
||||
if Mod["module_type"] == scu.MODULE_MALUS:
|
||||
klass += " module_malus"
|
||||
H.append('<li class="%s">' % klass)
|
||||
|
||||
H.append('<span class="notes_module_list_buts">')
|
||||
if im != 0 and editable:
|
||||
H.append(
|
||||
'<a href="module_move?module_id=%s&after=0" class="aud">%s</a>'
|
||||
% (Mod["module_id"], arrow_up)
|
||||
)
|
||||
else:
|
||||
H.append(arrow_none)
|
||||
if im < len(Modlist) - 1 and editable:
|
||||
H.append(
|
||||
'<a href="module_move?module_id=%s&after=1" class="aud">%s</a>'
|
||||
% (Mod["module_id"], arrow_down)
|
||||
)
|
||||
else:
|
||||
H.append(arrow_none)
|
||||
im += 1
|
||||
if Mod["nb_moduleimpls"] == 0 and editable:
|
||||
H.append(
|
||||
'<a class="smallbutton" href="module_delete?module_id=%s">%s</a>'
|
||||
% (Mod["module_id"], delete_icon)
|
||||
)
|
||||
else:
|
||||
H.append(delete_disabled_icon)
|
||||
H.append("</span>")
|
||||
|
||||
mod_editable = editable # and not sco_edit_module.module_is_locked( Mod['module_id'])
|
||||
if mod_editable:
|
||||
H.append(
|
||||
'<a class="discretelink" title="Modifier le module numéro %(numero)s, utilisé par %(nb_moduleimpls)d sessions" href="module_edit?module_id=%(module_id)s">'
|
||||
% Mod
|
||||
)
|
||||
H.append(
|
||||
'<span class="formation_module_tit">%s</span>'
|
||||
% scu.join_words(Mod["code"], Mod["titre"])
|
||||
)
|
||||
if mod_editable:
|
||||
H.append("</a>")
|
||||
heurescoef = (
|
||||
"%(heures_cours)s/%(heures_td)s/%(heures_tp)s, coef. %(coefficient)s"
|
||||
% Mod
|
||||
)
|
||||
if mod_editable:
|
||||
klass = "span_apo_edit"
|
||||
else:
|
||||
klass = ""
|
||||
heurescoef += (
|
||||
', Apo: <span class="%s" data-url="edit_module_set_code_apogee" id="%s" data-placeholder="%s">'
|
||||
% (klass, Mod["module_id"], scu.APO_MISSING_CODE_STR)
|
||||
+ (Mod["code_apogee"] or "")
|
||||
+ "</span>"
|
||||
)
|
||||
if tag_editable:
|
||||
tag_cls = "module_tag_editor"
|
||||
else:
|
||||
tag_cls = "module_tag_editor_ro"
|
||||
tag_mk = """<span class="sco_tag_edit"><form><textarea data-module_id="{}" class="{}">{}</textarea></form></span>"""
|
||||
tag_edit = tag_mk.format(
|
||||
Mod["module_id"],
|
||||
tag_cls,
|
||||
",".join(sco_tag_module.module_tag_list(Mod["module_id"])),
|
||||
)
|
||||
H.append(
|
||||
" %s %s" % (parcours.SESSION_NAME, Mod["semestre_id"])
|
||||
+ " (%s)" % heurescoef
|
||||
+ tag_edit
|
||||
)
|
||||
H.append("</li>")
|
||||
if not Modlist:
|
||||
H.append("<li>Aucun module dans cette matière !")
|
||||
if editable:
|
||||
H.append(
|
||||
f"""<a class="stdlink" href="{
|
||||
url_for("notes.matiere_delete",
|
||||
scodoc_dept=g.scodoc_dept, matiere_id=Mat["matiere_id"])}"
|
||||
>supprimer cette matière</a>
|
||||
"""
|
||||
)
|
||||
H.append("</li>")
|
||||
if editable: # and ((not parcours.UE_IS_MODULE) or len(Modlist) == 0):
|
||||
H.append(
|
||||
f"""<li> <a class="stdlink" href="{
|
||||
url_for("notes.module_create",
|
||||
scodoc_dept=g.scodoc_dept, matiere_id=Mat["matiere_id"])}"
|
||||
>créer un module</a></li>
|
||||
"""
|
||||
)
|
||||
H.append("</ul>")
|
||||
H.append("</li>")
|
||||
if not Matlist:
|
||||
H.append("<li>Aucune matière dans cette UE ! ")
|
||||
if editable:
|
||||
H.append(
|
||||
"""<a class="stdlink" href="ue_delete?ue_id=%(ue_id)s">supprimer l'UE</a>"""
|
||||
% UE
|
||||
)
|
||||
H.append("</li>")
|
||||
if editable and not parcours.UE_IS_MODULE:
|
||||
H.append(
|
||||
'<li><a class="stdlink" href="matiere_create?ue_id=%(ue_id)s">créer une matière</a> </li>'
|
||||
% UE
|
||||
)
|
||||
if not parcours.UE_IS_MODULE:
|
||||
H.append("</ul>")
|
||||
H.append("</ul>")
|
||||
)
|
||||
if editable:
|
||||
H.append(
|
||||
'<ul><li><a class="stdlink" href="ue_create?formation_id=%s">Ajouter une UE</a></li>'
|
||||
@ -774,6 +600,27 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
||||
)
|
||||
H.append("</div>") # formation_ue_list
|
||||
|
||||
if ues_externes:
|
||||
H.append('<div class="formation_ue_list formation_ue_list_externes">')
|
||||
H.append(
|
||||
'<div class="ue_list_tit">UE externes déclarées (pour information):</div>'
|
||||
)
|
||||
H.append(
|
||||
_ue_table_ues(
|
||||
parcours,
|
||||
ues_externes,
|
||||
editable,
|
||||
tag_editable,
|
||||
has_perm_change,
|
||||
arrow_up,
|
||||
arrow_down,
|
||||
arrow_none,
|
||||
delete_icon,
|
||||
delete_disabled_icon,
|
||||
)
|
||||
)
|
||||
H.append("</div>") # formation_ue_list
|
||||
|
||||
H.append("<p><ul>")
|
||||
if editable:
|
||||
H.append(
|
||||
@ -795,7 +642,7 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
||||
</p>"""
|
||||
% F
|
||||
)
|
||||
if perm_change:
|
||||
if has_perm_change:
|
||||
H.append(
|
||||
"""
|
||||
<h3> <a name="sems">Semestres ou sessions de cette formation</a></h3>
|
||||
@ -836,6 +683,294 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
||||
return "".join(H)
|
||||
|
||||
|
||||
def _ue_table_ues(
|
||||
parcours,
|
||||
ues,
|
||||
editable,
|
||||
tag_editable,
|
||||
has_perm_change,
|
||||
arrow_up,
|
||||
arrow_down,
|
||||
arrow_none,
|
||||
delete_icon,
|
||||
delete_disabled_icon,
|
||||
):
|
||||
"""Édition de programme: liste des UEs (avec leurs matières et modules)."""
|
||||
H = []
|
||||
cur_ue_semestre_id = None
|
||||
iue = 0
|
||||
for ue in ues:
|
||||
if ue["ects"]:
|
||||
ue["ects_str"] = ", %g ECTS" % ue["ects"]
|
||||
else:
|
||||
ue["ects_str"] = ""
|
||||
if editable:
|
||||
klass = "span_apo_edit"
|
||||
else:
|
||||
klass = ""
|
||||
ue["code_apogee_str"] = (
|
||||
""", Apo: <span class="%s" data-url="edit_ue_set_code_apogee" id="%s" data-placeholder="%s">"""
|
||||
% (klass, ue["ue_id"], scu.APO_MISSING_CODE_STR)
|
||||
+ (ue["code_apogee"] or "")
|
||||
+ "</span>"
|
||||
)
|
||||
|
||||
if cur_ue_semestre_id != ue["semestre_id"]:
|
||||
cur_ue_semestre_id = ue["semestre_id"]
|
||||
if iue > 0:
|
||||
H.append("</ul>")
|
||||
if ue["semestre_id"] == sco_codes_parcours.UE_SEM_DEFAULT:
|
||||
lab = "Pas d'indication de semestre:"
|
||||
else:
|
||||
lab = "Semestre %s:" % ue["semestre_id"]
|
||||
H.append('<div class="ue_list_tit_sem">%s</div>' % lab)
|
||||
H.append('<ul class="notes_ue_list">')
|
||||
H.append('<li class="notes_ue_list">')
|
||||
if iue != 0 and editable:
|
||||
H.append(
|
||||
'<a href="ue_move?ue_id=%s&after=0" class="aud">%s</a>'
|
||||
% (ue["ue_id"], arrow_up)
|
||||
)
|
||||
else:
|
||||
H.append(arrow_none)
|
||||
if iue < len(ues) - 1 and editable:
|
||||
H.append(
|
||||
'<a href="ue_move?ue_id=%s&after=1" class="aud">%s</a>'
|
||||
% (ue["ue_id"], arrow_down)
|
||||
)
|
||||
else:
|
||||
H.append(arrow_none)
|
||||
iue += 1
|
||||
ue["acro_titre"] = str(ue["acronyme"])
|
||||
if ue["titre"] != ue["acronyme"]:
|
||||
ue["acro_titre"] += " " + str(ue["titre"])
|
||||
H.append(
|
||||
"""%(acro_titre)s <span class="ue_code">(code %(ue_code)s%(ects_str)s, coef. %(coefficient)3.2f%(code_apogee_str)s)</span>
|
||||
<span class="ue_coef"></span>
|
||||
"""
|
||||
% ue
|
||||
)
|
||||
if ue["type"] != sco_codes_parcours.UE_STANDARD:
|
||||
H.append(
|
||||
'<span class="ue_type">%s</span>'
|
||||
% sco_codes_parcours.UE_TYPE_NAME[ue["type"]]
|
||||
)
|
||||
if ue["is_external"]:
|
||||
# Cas spécial: si l'UE externe a plus d'un module, c'est peut être une UE
|
||||
# qui a été déclarée externe par erreur (ou suite à un bug d'import/export xml)
|
||||
# Dans ce cas, propose de changer le type (même si verrouillée)
|
||||
if len(sco_moduleimpl.moduleimpls_in_external_ue(ue["ue_id"])) > 1:
|
||||
H.append('<span class="ue_is_external">')
|
||||
if has_perm_change:
|
||||
H.append(
|
||||
f"""<a class="stdlink" href="{
|
||||
url_for("notes.ue_set_internal", scodoc_dept=g.scodoc_dept, ue_id=ue["ue_id"])
|
||||
}">transformer en UE ordinaire</a> """
|
||||
)
|
||||
H.append("</span>")
|
||||
ue_editable = editable and not ue_is_locked(ue["ue_id"])
|
||||
if ue_editable:
|
||||
H.append(
|
||||
'<a class="stdlink" href="ue_edit?ue_id=%(ue_id)s">modifier</a>' % ue
|
||||
)
|
||||
else:
|
||||
H.append('<span class="locked">[verrouillé]</span>')
|
||||
H.append(
|
||||
_ue_table_matieres(
|
||||
parcours,
|
||||
ue,
|
||||
editable,
|
||||
tag_editable,
|
||||
arrow_up,
|
||||
arrow_down,
|
||||
arrow_none,
|
||||
delete_icon,
|
||||
delete_disabled_icon,
|
||||
)
|
||||
)
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def _ue_table_matieres(
|
||||
parcours,
|
||||
ue,
|
||||
editable,
|
||||
tag_editable,
|
||||
arrow_up,
|
||||
arrow_down,
|
||||
arrow_none,
|
||||
delete_icon,
|
||||
delete_disabled_icon,
|
||||
):
|
||||
"""Édition de programme: liste des matières (et leurs modules) d'une UE."""
|
||||
H = []
|
||||
if not parcours.UE_IS_MODULE:
|
||||
H.append('<ul class="notes_matiere_list">')
|
||||
matieres = sco_edit_matiere.matiere_list(args={"ue_id": ue["ue_id"]})
|
||||
for mat in matieres:
|
||||
if not parcours.UE_IS_MODULE:
|
||||
H.append('<li class="notes_matiere_list">')
|
||||
if editable and not sco_edit_matiere.matiere_is_locked(mat["matiere_id"]):
|
||||
H.append(
|
||||
f"""<a class="stdlink" href="{
|
||||
url_for("notes.matiere_edit",
|
||||
scodoc_dept=g.scodoc_dept, matiere_id=mat["matiere_id"])
|
||||
}">
|
||||
"""
|
||||
)
|
||||
H.append("%(titre)s" % mat)
|
||||
if editable and not sco_edit_matiere.matiere_is_locked(mat["matiere_id"]):
|
||||
H.append("</a>")
|
||||
|
||||
modules = sco_edit_module.module_list(args={"matiere_id": mat["matiere_id"]})
|
||||
H.append(
|
||||
_ue_table_modules(
|
||||
parcours,
|
||||
mat,
|
||||
modules,
|
||||
editable,
|
||||
tag_editable,
|
||||
arrow_up,
|
||||
arrow_down,
|
||||
arrow_none,
|
||||
delete_icon,
|
||||
delete_disabled_icon,
|
||||
)
|
||||
)
|
||||
if not matieres:
|
||||
H.append("<li>Aucune matière dans cette UE ! ")
|
||||
if editable:
|
||||
H.append(
|
||||
"""<a class="stdlink" href="ue_delete?ue_id=%(ue_id)s">supprimer l'UE</a>"""
|
||||
% ue
|
||||
)
|
||||
H.append("</li>")
|
||||
if editable and not parcours.UE_IS_MODULE:
|
||||
H.append(
|
||||
'<li><a class="stdlink" href="matiere_create?ue_id=%(ue_id)s">créer une matière</a> </li>'
|
||||
% ue
|
||||
)
|
||||
if not parcours.UE_IS_MODULE:
|
||||
H.append("</ul>")
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def _ue_table_modules(
|
||||
parcours,
|
||||
mat,
|
||||
modules,
|
||||
editable,
|
||||
tag_editable,
|
||||
arrow_up,
|
||||
arrow_down,
|
||||
arrow_none,
|
||||
delete_icon,
|
||||
delete_disabled_icon,
|
||||
):
|
||||
"""Édition de programme: liste des modules d'une matière d'une UE"""
|
||||
H = ['<ul class="notes_module_list">']
|
||||
im = 0
|
||||
for mod in modules:
|
||||
mod["nb_moduleimpls"] = sco_edit_module.module_count_moduleimpls(
|
||||
mod["module_id"]
|
||||
)
|
||||
klass = "notes_module_list"
|
||||
if mod["module_type"] == scu.MODULE_MALUS:
|
||||
klass += " module_malus"
|
||||
H.append('<li class="%s">' % klass)
|
||||
|
||||
H.append('<span class="notes_module_list_buts">')
|
||||
if im != 0 and editable:
|
||||
H.append(
|
||||
'<a href="module_move?module_id=%s&after=0" class="aud">%s</a>'
|
||||
% (mod["module_id"], arrow_up)
|
||||
)
|
||||
else:
|
||||
H.append(arrow_none)
|
||||
if im < len(modules) - 1 and editable:
|
||||
H.append(
|
||||
'<a href="module_move?module_id=%s&after=1" class="aud">%s</a>'
|
||||
% (mod["module_id"], arrow_down)
|
||||
)
|
||||
else:
|
||||
H.append(arrow_none)
|
||||
im += 1
|
||||
if mod["nb_moduleimpls"] == 0 and editable:
|
||||
H.append(
|
||||
'<a class="smallbutton" href="module_delete?module_id=%s">%s</a>'
|
||||
% (mod["module_id"], delete_icon)
|
||||
)
|
||||
else:
|
||||
H.append(delete_disabled_icon)
|
||||
H.append("</span>")
|
||||
|
||||
mod_editable = (
|
||||
editable # and not sco_edit_module.module_is_locked( Mod['module_id'])
|
||||
)
|
||||
if mod_editable:
|
||||
H.append(
|
||||
'<a class="discretelink" title="Modifier le module numéro %(numero)s, utilisé par %(nb_moduleimpls)d sessions" href="module_edit?module_id=%(module_id)s">'
|
||||
% mod
|
||||
)
|
||||
H.append(
|
||||
'<span class="formation_module_tit">%s</span>'
|
||||
% scu.join_words(mod["code"], mod["titre"])
|
||||
)
|
||||
if mod_editable:
|
||||
H.append("</a>")
|
||||
heurescoef = (
|
||||
"%(heures_cours)s/%(heures_td)s/%(heures_tp)s, coef. %(coefficient)s" % mod
|
||||
)
|
||||
if mod_editable:
|
||||
klass = "span_apo_edit"
|
||||
else:
|
||||
klass = ""
|
||||
heurescoef += (
|
||||
', Apo: <span class="%s" data-url="edit_module_set_code_apogee" id="%s" data-placeholder="%s">'
|
||||
% (klass, mod["module_id"], scu.APO_MISSING_CODE_STR)
|
||||
+ (mod["code_apogee"] or "")
|
||||
+ "</span>"
|
||||
)
|
||||
if tag_editable:
|
||||
tag_cls = "module_tag_editor"
|
||||
else:
|
||||
tag_cls = "module_tag_editor_ro"
|
||||
tag_mk = """<span class="sco_tag_edit"><form><textarea data-module_id="{}" class="{}">{}</textarea></form></span>"""
|
||||
tag_edit = tag_mk.format(
|
||||
mod["module_id"],
|
||||
tag_cls,
|
||||
",".join(sco_tag_module.module_tag_list(mod["module_id"])),
|
||||
)
|
||||
H.append(
|
||||
" %s %s" % (parcours.SESSION_NAME, mod["semestre_id"])
|
||||
+ " (%s)" % heurescoef
|
||||
+ tag_edit
|
||||
)
|
||||
H.append("</li>")
|
||||
if not modules:
|
||||
H.append("<li>Aucun module dans cette matière ! ")
|
||||
if editable:
|
||||
H.append(
|
||||
f"""<a class="stdlink" href="{
|
||||
url_for("notes.matiere_delete",
|
||||
scodoc_dept=g.scodoc_dept, matiere_id=mat["matiere_id"])}"
|
||||
>la supprimer</a>
|
||||
"""
|
||||
)
|
||||
H.append("</li>")
|
||||
if editable: # and ((not parcours.UE_IS_MODULE) or len(Modlist) == 0):
|
||||
H.append(
|
||||
f"""<li> <a class="stdlink" href="{
|
||||
url_for("notes.module_create",
|
||||
scodoc_dept=g.scodoc_dept, matiere_id=mat["matiere_id"])}"
|
||||
>créer un module</a></li>
|
||||
"""
|
||||
)
|
||||
H.append("</ul>")
|
||||
H.append("</li>")
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def ue_sharing_code(ue_code=None, ue_id=None, hide_ue_id=None):
|
||||
"""HTML list of UE sharing this code
|
||||
Either ue_code or ue_id may be specified.
|
||||
|
@ -356,7 +356,7 @@ def apo_semset_maq_status(
|
||||
H.append(
|
||||
", ".join(
|
||||
[
|
||||
'<a class="stdlink" href="ue_list?formation_id=%(formation_id)s">%(acronyme)s v%(version)s</a>'
|
||||
'<a class="stdlink" href="ue_table?formation_id=%(formation_id)s">%(acronyme)s v%(version)s</a>'
|
||||
% f
|
||||
for f in formations
|
||||
]
|
||||
|
@ -152,7 +152,7 @@ def format_nom(s, uppercase=True):
|
||||
def input_civilite(s):
|
||||
"""Converts external representation of civilite to internal:
|
||||
'M', 'F', or 'X' (and nothing else).
|
||||
Raises valueError if conversion fails.
|
||||
Raises ScoValueError if conversion fails.
|
||||
"""
|
||||
s = s.upper().strip()
|
||||
if s in ("M", "M.", "MR", "H"):
|
||||
@ -161,12 +161,13 @@ def input_civilite(s):
|
||||
return "F"
|
||||
elif s == "X" or not s:
|
||||
return "X"
|
||||
raise ValueError("valeur invalide pour la civilité: %s" % s)
|
||||
raise ScoValueError("valeur invalide pour la civilité: %s" % s)
|
||||
|
||||
|
||||
def format_civilite(civilite):
|
||||
"""returns 'M.' ou 'Mme' ou '' (pour le genre neutre,
|
||||
personne ne souhaitant pas d'affichage)
|
||||
personne ne souhaitant pas d'affichage).
|
||||
Raises ScoValueError if conversion fails.
|
||||
"""
|
||||
try:
|
||||
return {
|
||||
@ -175,7 +176,7 @@ def format_civilite(civilite):
|
||||
"X": "",
|
||||
}[civilite]
|
||||
except KeyError:
|
||||
raise ValueError("valeur invalide pour la civilité: %s" % civilite)
|
||||
raise ScoValueError("valeur invalide pour la civilité: %s" % civilite)
|
||||
|
||||
|
||||
def format_lycee(nomlycee):
|
||||
|
@ -254,7 +254,11 @@ def formation_list_table(formation_id=None, args={}):
|
||||
).NAME
|
||||
except:
|
||||
f["parcours_name"] = ""
|
||||
f["_titre_target"] = "ue_list?formation_id=%(formation_id)s" % f
|
||||
f["_titre_target"] = url_for(
|
||||
"notes.ue_table",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=str(f["formation_id"]),
|
||||
)
|
||||
f["_titre_link_class"] = "stdlink"
|
||||
f["_titre_id"] = "titre-%s" % f["acronyme"].lower().replace(" ", "-")
|
||||
# Ajoute les semestres associés à chaque formation:
|
||||
|
@ -675,7 +675,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
||||
|
||||
if tf[0] == 0 or msg:
|
||||
return (
|
||||
'<p>Formation <a class="discretelink" href="ue_list?formation_id=%(formation_id)s"><em>%(titre)s</em> (%(acronyme)s), version %(version)s, code %(formation_code)s</a></p>'
|
||||
'<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])
|
||||
|
@ -221,12 +221,11 @@ def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid):
|
||||
"""
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
ue_list = _list_ue_with_coef_and_validations(sem, etudid)
|
||||
descr = _ue_form_description(ue_list, scu.get_request_args())
|
||||
ues = _list_ue_with_coef_and_validations(sem, etudid)
|
||||
descr = _ue_form_description(ues, scu.get_request_args())
|
||||
if request.method == "GET":
|
||||
initvalues = {
|
||||
"note_" + str(ue["ue_id"]): ue["validation"].get("moy_ue", "")
|
||||
for ue in ue_list
|
||||
"note_" + str(ue["ue_id"]): ue["validation"].get("moy_ue", "") for ue in ues
|
||||
}
|
||||
else:
|
||||
initvalues = {}
|
||||
@ -247,15 +246,13 @@ def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid):
|
||||
return "\n".join(H)
|
||||
else: # soumission
|
||||
# simule erreur
|
||||
ok, message = _check_values(ue_list, tf[2])
|
||||
ok, message = _check_values(ues, tf[2])
|
||||
if not ok:
|
||||
H = _make_page(etud, sem, tf, message=message)
|
||||
return "\n".join(H)
|
||||
else:
|
||||
# Submit
|
||||
_record_ue_validations_and_coefs(
|
||||
formsemestre_id, etudid, ue_list, tf[2]
|
||||
)
|
||||
_record_ue_validations_and_coefs(formsemestre_id, etudid, ues, tf[2])
|
||||
return flask.redirect(
|
||||
"formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s"
|
||||
% (formsemestre_id, etudid)
|
||||
@ -303,7 +300,7 @@ _UE_VALID_CODES = {
|
||||
}
|
||||
|
||||
|
||||
def _ue_form_description(ue_list, values):
|
||||
def _ue_form_description(ues, values):
|
||||
"""Description du formulaire de saisie des UE / validations
|
||||
Pour chaque UE, on peut saisir: son code jury, sa note, son coefficient.
|
||||
"""
|
||||
@ -320,7 +317,7 @@ def _ue_form_description(ue_list, values):
|
||||
("formsemestre_id", {"input_type": "hidden"}),
|
||||
("etudid", {"input_type": "hidden"}),
|
||||
]
|
||||
for ue in ue_list:
|
||||
for ue in ues:
|
||||
# Menu pour code validation UE:
|
||||
# Ne propose que ADM, CMP et "Non inscrit"
|
||||
select_name = "valid_" + str(ue["ue_id"])
|
||||
@ -439,8 +436,8 @@ def _list_ue_with_coef_and_validations(sem, etudid):
|
||||
"""
|
||||
cnx = ndb.GetDBConnexion()
|
||||
formsemestre_id = sem["formsemestre_id"]
|
||||
ue_list = sco_edit_ue.ue_list({"formation_id": sem["formation_id"]})
|
||||
for ue in ue_list:
|
||||
ues = sco_edit_ue.ue_list({"formation_id": sem["formation_id"]})
|
||||
for ue in ues:
|
||||
# add coefficient
|
||||
uecoef = sco_formsemestre.formsemestre_uecoef_list(
|
||||
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue["ue_id"]}
|
||||
@ -462,11 +459,11 @@ def _list_ue_with_coef_and_validations(sem, etudid):
|
||||
ue["validation"] = validation[0]
|
||||
else:
|
||||
ue["validation"] = {}
|
||||
return ue_list
|
||||
return ues
|
||||
|
||||
|
||||
def _record_ue_validations_and_coefs(formsemestre_id, etudid, ue_list, values):
|
||||
for ue in ue_list:
|
||||
def _record_ue_validations_and_coefs(formsemestre_id, etudid, ues, values):
|
||||
for ue in ues:
|
||||
code = values.get("valid_" + str(ue["ue_id"]), False)
|
||||
if code == "None":
|
||||
code = None
|
||||
|
@ -178,6 +178,19 @@ def moduleimpl_withmodule_list(
|
||||
return modimpls
|
||||
|
||||
|
||||
def moduleimpls_in_external_ue(ue_id):
|
||||
"""List of modimpls in this ue"""
|
||||
cursor = ndb.SimpleQuery(
|
||||
"""SELECT DISTINCT mi.*
|
||||
FROM notes_ue u, notes_moduleimpl mi, notes_modules m
|
||||
WHERE u.is_external is true
|
||||
AND mi.module_id = m.id AND m.ue_id = %(ue_id)s
|
||||
""",
|
||||
{"ue_id": ue_id},
|
||||
)
|
||||
return cursor.dictfetchall()
|
||||
|
||||
|
||||
def do_moduleimpl_inscription_list(moduleimpl_id=None, etudid=None):
|
||||
"list moduleimpl_inscriptions"
|
||||
args = locals()
|
||||
|
@ -348,7 +348,6 @@ def make_formsemestre_recapcomplet(
|
||||
if not hidemodules:
|
||||
h.append("")
|
||||
pass
|
||||
|
||||
if not hidemodules and not ue["is_external"]:
|
||||
for modimpl in modimpls:
|
||||
if modimpl["module"]["ue_id"] == ue["ue_id"]:
|
||||
|
@ -82,25 +82,35 @@ def simple_dictlist2xml(dictlist, tagname=None, quote=False, pretty=True):
|
||||
return ans
|
||||
|
||||
|
||||
def _repr_as_xml(v):
|
||||
if isinstance(v, bool):
|
||||
return str(int(v)) # booleans as "0" / "1"
|
||||
return str(v)
|
||||
|
||||
|
||||
def _dictlist2xml(dictlist, root=None, tagname=None, quote=False):
|
||||
scalar_types = (bytes, str, int, float)
|
||||
scalar_types = (bytes, str, int, float, bool)
|
||||
for d in dictlist:
|
||||
elem = ElementTree.Element(tagname)
|
||||
root.append(elem)
|
||||
if isinstance(d, scalar_types) or isinstance(d, ApoEtapeVDI):
|
||||
elem.set("code", str(d))
|
||||
elem.set("code", _repr_as_xml(d))
|
||||
else:
|
||||
if quote:
|
||||
d_scalar = dict(
|
||||
[
|
||||
(k, quote_xml_attr(v))
|
||||
(k, quote_xml_attr(_repr_as_xml(v)))
|
||||
for (k, v) in d.items()
|
||||
if isinstance(v, scalar_types)
|
||||
]
|
||||
)
|
||||
else:
|
||||
d_scalar = dict(
|
||||
[(k, str(v)) for (k, v) in d.items() if isinstance(v, scalar_types)]
|
||||
[
|
||||
(k, _repr_as_xml(v))
|
||||
for (k, v) in d.items()
|
||||
if isinstance(v, scalar_types)
|
||||
]
|
||||
)
|
||||
for k in d_scalar:
|
||||
elem.set(k, d_scalar[k])
|
||||
|
@ -1511,6 +1511,19 @@ span.ue_type {
|
||||
margin-right: 1.5em;
|
||||
}
|
||||
|
||||
div.formation_ue_list_externes {
|
||||
background-color: #98cc98;
|
||||
}
|
||||
div.formation_ue_list_externes ul.notes_ue_list, div.formation_ue_list_externes li.notes_ue_list {
|
||||
background-color: #98cc98;
|
||||
}
|
||||
span.ue_is_external span {
|
||||
color: orange;
|
||||
}
|
||||
span.ue_is_external a {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
li.notes_matiere_list {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
@ -41,9 +41,12 @@ import flask
|
||||
from flask import url_for
|
||||
from flask import current_app, g, request
|
||||
from flask_login import current_user
|
||||
from werkzeug.utils import redirect
|
||||
|
||||
from config import Config
|
||||
|
||||
from app import db
|
||||
from app import models
|
||||
from app.auth.models import User
|
||||
|
||||
from app.decorators import (
|
||||
@ -336,8 +339,8 @@ sco_publish(
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/ue_table")
|
||||
@bp.route("/ue_list") # backward compat
|
||||
@bp.route("/ue_table")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func
|
||||
@ -345,6 +348,25 @@ def ue_table(formation_id=None, msg=""):
|
||||
return sco_edit_ue.ue_table(formation_id=formation_id, msg=msg)
|
||||
|
||||
|
||||
@bp.route("/ue_set_internal", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoChangeFormation)
|
||||
@scodoc7func
|
||||
def ue_set_internal(ue_id):
|
||||
""""""
|
||||
ue = models.formations.NotesUE.query.get(ue_id)
|
||||
if not ue:
|
||||
raise ScoValueError("invalid ue_id")
|
||||
ue.is_external = False
|
||||
db.session.add(ue)
|
||||
db.session.commit()
|
||||
return redirect(
|
||||
url_for(
|
||||
"notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=ue.formation_id
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
sco_publish("/ue_sharing_code", sco_edit_ue.ue_sharing_code, Permission.ScoView)
|
||||
sco_publish(
|
||||
"/edit_ue_set_code_apogee",
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.0.54"
|
||||
SCOVERSION = "9.0.55"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
@ -324,7 +324,7 @@ class ScoFake(object):
|
||||
formation (dict), liste d'ue (dicts), liste de modules.
|
||||
"""
|
||||
f = self.create_formation(acronyme=acronyme, titre=titre)
|
||||
ue_list = []
|
||||
ues = []
|
||||
mod_list = []
|
||||
for semestre_id in range(1, nb_semestre + 1):
|
||||
for n in range(1, nb_ue_per_semestre + 1):
|
||||
@ -333,7 +333,7 @@ class ScoFake(object):
|
||||
acronyme="TSU%s%s" % (semestre_id, n),
|
||||
titre="ue test %s%s" % (semestre_id, n),
|
||||
)
|
||||
ue_list.append(ue)
|
||||
ues.append(ue)
|
||||
mat = self.create_matiere(ue_id=ue["ue_id"], titre="matière test")
|
||||
for _ in range(nb_module_per_ue):
|
||||
mod = self.create_module(
|
||||
@ -346,7 +346,7 @@ class ScoFake(object):
|
||||
formation_id=f["formation_id"], # faiblesse de l'API
|
||||
)
|
||||
mod_list.append(mod)
|
||||
return f, ue_list, mod_list
|
||||
return f, ues, mod_list
|
||||
|
||||
def setup_formsemestre(
|
||||
self,
|
||||
|
@ -339,6 +339,10 @@ def test_import_formation(test_client):
|
||||
f = sco_formations.formation_import_xml(doc)
|
||||
assert len(f) == 3 # 3-uple
|
||||
formation_id = f[0]
|
||||
# --- Vérification des UE
|
||||
ues = sco_edit_ue.ue_list({"formation_id": formation_id})
|
||||
assert len(ues) == 10
|
||||
assert all(not ue["is_external"] for ue in ues) # aucune UE externe dans le XML
|
||||
# --- Mise en place de 4 semestres
|
||||
sems = [
|
||||
G.create_formsemestre(
|
||||
|
Loading…
Reference in New Issue
Block a user