From 2fe9e5ec3945eae808c2fa28ca8e9591ae83e8de Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Fri, 22 Oct 2021 23:09:15 +0200 Subject: [PATCH] =?UTF-8?q?S=C3=A9pare=20les=20UE=20externes=20dans=20la?= =?UTF-8?q?=20pae=20=C3=A9dition=20programme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scodoc/notesdb.py | 16 + app/scodoc/sco_edit_matiere.py | 25 +- app/scodoc/sco_edit_module.py | 24 +- app/scodoc/sco_edit_ue.py | 565 ++++++++++++++-------- app/scodoc/sco_etape_apogee_view.py | 2 +- app/scodoc/sco_etud.py | 9 +- app/scodoc/sco_formations.py | 6 +- app/scodoc/sco_formsemestre_edit.py | 2 +- app/scodoc/sco_formsemestre_exterieurs.py | 27 +- app/scodoc/sco_moduleimpl.py | 13 + app/scodoc/sco_recapcomplet.py | 1 - app/scodoc/sco_xml.py | 18 +- app/static/css/scodoc.css | 13 + app/views/notes.py | 24 +- sco_version.py | 2 +- tests/unit/sco_fake_gen.py | 6 +- tests/unit/test_formations.py | 4 + 17 files changed, 492 insertions(+), 265 deletions(-) diff --git a/app/scodoc/notesdb.py b/app/scodoc/notesdb.py index 6fa29fb98..b03b5427d 100644 --- a/app/scodoc/notesdb.py +++ b/app/scodoc/notesdb.py @@ -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): diff --git a/app/scodoc/sco_edit_matiere.py b/app/scodoc/sco_edit_matiere.py index 1cbd199d3..f07b9b588 100644 --- a/app/scodoc/sco_edit_matiere.py +++ b/app/scodoc/sco_edit_matiere.py @@ -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): "

Suppression de la matière %(titre)s" % M, " dans l'UE (%(acronyme)s))

" % 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: diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py index 301ef585a..54d7fc846 100644 --- a/app/scodoc/sco_edit_module.py +++ b/app/scodoc/sco_edit_module.py @@ -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"), - """

Suppression du module %(titre)s (%(code)s)

""" % Mod, + """

Suppression du module %(titre)s (%(code)s)

""" % 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, diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py index 2e99407de..66d8777d5 100644 --- a/app/scodoc/sco_edit_ue.py +++ b/app/scodoc/sco_edit_ue.py @@ -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): "

Suppression de l'UE %(titre)s (%(acronyme)s))

" % 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( '
montrer les tags
' ) - - 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: """ - % (klass, UE["ue_id"], scu.APO_MISSING_CODE_STR) - + (UE["code_apogee"] or "") - + "" + 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("") - 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('
%s
' % lab) - H.append('") + ) if editable: H.append( '