diff --git a/app/formations/edit_module.py b/app/formations/edit_module.py index 71fd3ade7..b8b389d9a 100644 --- a/app/formations/edit_module.py +++ b/app/formations/edit_module.py @@ -33,168 +33,28 @@ from flask import flash, url_for, render_template from flask import g, request from flask_login import current_user -from app import db, log +from app import db from app import models -from app.formations import edit_matiere from app.models import APO_CODE_STR_LEN from app.models import Formation, Matiere, Module, UniteEns from app.models import FormSemestre, ModuleImpl -from app.models import ScolarNews from app.models.but_refcomp import ApcAppCritique, ApcParcours -import app.scodoc.notesdb as ndb import app.scodoc.sco_utils as scu from app.scodoc.TrivialFormulator import TrivialFormulator from app.scodoc.sco_permissions import Permission from app.scodoc.sco_exceptions import ( ScoValueError, - ScoLockedFormError, - ScoGenError, ScoNonEmptyFormationObject, ) from app.scodoc import codes_cursus -from app.scodoc import sco_moduleimpl - -_moduleEditor = ndb.EditableTable( - "notes_modules", - "module_id", - ( - "module_id", - "titre", - "code", - "abbrev", - "heures_cours", - "heures_td", - "heures_tp", - "coefficient", - "ue_id", - "matiere_id", - "formation_id", - "semestre_id", - "numero", - "code_apogee", - "module_type", - "edt_id", - #'ects' - ), - sortkey="numero, code, titre", - output_formators={ - "heures_cours": ndb.float_null_is_zero, - "heures_td": ndb.float_null_is_zero, - "heures_tp": ndb.float_null_is_zero, - "numero": ndb.int_null_is_zero, - "coefficient": ndb.float_null_is_zero, - "module_type": ndb.int_null_is_zero, - #'ects' : ndb.float_null_is_null - }, -) - - -def module_list(*args, **kw): - "list modules" - cnx = ndb.GetDBConnexion() - return _moduleEditor.list(cnx, *args, **kw) - - -def do_module_create(args) -> int: - "Create a module. Returns id of new object." - formation = db.session.get(Formation, args["formation_id"]) - # refuse de créer un module APC avec semestres incohérents: - if formation.is_apc(): - ue = db.session.get(UniteEns, args["ue_id"]) - if int(args.get("semestre_id", 0)) != ue.semestre_idx: - raise ScoValueError("Formation incompatible: contacter le support ScoDoc") - # create - module = Module.create_from_dict(args) - db.session.commit() - log(f"do_module_create: created {module.id} with {args}") - - # news - ScolarNews.add( - typ=ScolarNews.NEWS_FORM, - obj=formation.id, - text=f"Modification de la formation {formation.acronyme}", - ) - formation.invalidate_cached_sems() - return module.id - - -def module_create( - matiere_id=None, module_type=None, semestre_id=None, formation_id=None -): - """Formulaire de création d'un module - Si matiere_id est spécifié, le module sera créé dans cette matière (cas normal). - Sinon, donne le choix de l'UE de rattachement et utilise la première - matière de cette UE (si elle n'existe pas, la crée). - """ - return module_edit( - create=True, - matiere_id=matiere_id, - module_type=module_type, - semestre_id=semestre_id, - formation_id=formation_id, - ) - - -def can_delete_module(module): - "True si le module n'est pas utilisée dans des formsemestre" - return len(module.modimpls.all()) == 0 - - -def do_module_delete(oid): - "delete module" - module = Module.query.get_or_404(oid) - mod = module_list({"module_id": oid})[0] # sco7 - if module_is_locked(module.id): - raise ScoLockedFormError() - if not can_delete_module(module): - raise ScoNonEmptyFormationObject( - "Module", - msg=module.titre, - dest_url=url_for( - "notes.ue_table", - scodoc_dept=g.scodoc_dept, - formation_id=module.formation_id, - semestre_idx=module.ue.semestre_idx, - ), - ) - - # S'il y a des moduleimpls, on ne peut pas detruire le module ! - mods = sco_moduleimpl.moduleimpl_list(module_id=oid) - if mods: - err_page = f""" -
Il faut d'abord supprimer le semestre (ou en retirer - ce module). - Mais il est peut être préférable de laisser ce programme intact et - d'en créer une nouvelle version pour la modifier sans affecter - les semestres déjà en place. -
- reprendre - """ - raise ScoGenError(err_page) - # delete - cnx = ndb.GetDBConnexion() - _moduleEditor.delete(cnx, oid) - - # news - formation = module.formation - ScolarNews.add( - typ=ScolarNews.NEWS_FORM, - obj=mod["formation_id"], - text=f"Modification de la formation {formation.acronyme}", - ) - formation.invalidate_cached_sems() def module_delete(module_id=None): - """Delete a module""" + """Formulaire suppression d'un module""" module = Module.query.get_or_404(module_id) - mod = module_list(args={"module_id": module_id})[0] # sco7 - if not can_delete_module(module): + if not module.can_be_deleted(): raise ScoNonEmptyFormationObject( "Module", msg=module.titre, @@ -221,7 +81,7 @@ def module_delete(module_id=None): request.base_url, scu.get_request_args(), (("module_id", {"input_type": "hidden"}),), - initvalues=mod, + initvalues=module.to_dict(), submitlabel="Confirmer la suppression", cancelbutton="Annuler", ) @@ -231,37 +91,38 @@ def module_delete(module_id=None): title="Suppression d'un module", content="\n".join(H) + tf[1], ) - elif tf[0] == -1: - return flask.redirect(dest_url) - else: - do_module_delete(module_id) + if tf[0] == -1: # cancel return flask.redirect(dest_url) + module.delete() + return flask.redirect(dest_url) + def do_module_edit(vals: dict) -> None: "edit a module" # check - mod = module_list({"module_id": vals["module_id"]})[0] - if module_is_locked(mod["module_id"]): - # formation verrouillée: empeche de modifier certains champs: - vals = vals.copy() - protected_fields = ("coefficient", "ue_id", "matiere_id", "semestre_id") - for f in protected_fields: - if f in vals: - del vals[f] + module = Module.get_instance(vals["module_id"]) # edit - cnx = ndb.GetDBConnexion() - _moduleEditor.edit(cnx, vals) - db.session.get(Formation, mod["formation_id"]).invalidate_cached_sems() + modif = module.from_dict(vals) + if modif: + module.formation.invalidate_cached_sems() -def check_module_code_unicity(code, field, formation_id, module_id=None): - "true si code module unique dans la formation" - modules = module_list(args={"code": code, "formation_id": formation_id}) - if module_id: # edition: supprime le module en cours - modules = [m for m in modules if m["module_id"] != module_id] - - return len(modules) == 0 +def module_create( + matiere_id=None, module_type=None, semestre_id=None, formation_id=None +): + """Formulaire de création d'un module + Si matiere_id est spécifié, le module sera créé dans cette matière (cas normal). + Sinon, donne le choix de l'UE de rattachement et utilise la première + matière de cette UE (si elle n'existe pas, la crée). + """ + return module_edit( + create=True, + matiere_id=matiere_id, + module_type=module_type, + semestre_id=semestre_id, + formation_id=formation_id, + ) def module_edit( @@ -278,14 +139,12 @@ def module_edit( Sinon, donne le choix de l'UE de rattachement et utilise la première matière de cette UE (si elle n'existe pas, la crée). """ - from app.scodoc import sco_tag_module - # --- Détermination de la formation orig_semestre_idx = semestre_id ue = None if create: if matiere_id: - matiere = Matiere.query.get_or_404(matiere_id) + matiere = Matiere.get_instance(matiere_id) ue = matiere.ue formation = ue.formation orig_semestre_idx = ue.semestre_idx if semestre_id is None else semestre_id @@ -300,7 +159,7 @@ def module_edit( ue = module.ue module_dict = module.to_dict() formation = module.formation - unlocked = not module_is_locked(module_id) + unlocked = not module.is_locked() parcours = codes_cursus.get_cursus_from_code(formation.type_parcours) is_apc = parcours.APC_SAE # BUT @@ -326,17 +185,14 @@ def module_edit( if (module and module.matiere and (module.matiere.id == mat.id)) or (mat.id == mat.ue.matieres.first().id) ] - mat_names = [ - "S%s / %s" % (mat.ue.semestre_idx, mat.ue.acronyme) for mat in matieres - ] + mat_names = [f"S{mat.ue.semestre_idx} / {mat.ue.acronyme}" for mat in matieres] else: - mat_names = ["%s / %s" % (mat.ue.acronyme, mat.titre or "") for mat in matieres] + mat_names = ["{mat.ue.acronyme} / {mat.titre or ''}" for mat in matieres] if module: # edition - ue_mat_ids = ["%s!%s" % (mat.ue.id, mat.id) for mat in matieres] - module_dict["ue_matiere_id"] = "%s!%s" % ( - module_dict["ue_id"], - module_dict["matiere_id"], + ue_mat_ids = [f"{mat.ue.id}!{mat.id}" for mat in matieres] + module_dict["ue_matiere_id"] = ( + f"{module_dict['ue_id']}!{module_dict['matiere_id']}" ) semestres_indices = list(range(1, parcours.NB_SEM + 1)) @@ -433,8 +289,8 @@ def module_edit( "explanation": """code du module (issu du programme, exemple M1203, R2.01, ou SAÉ 3.4. Doit être unique dans la formation)""", "allow_null": False, - "validator": lambda val, field, formation_id=formation.id: check_module_code_unicity( - val, field, formation_id, module_id=module.id if module else None + "validator": lambda val, _, formation_id=formation.id: Module.check_module_code_unicity( + val, formation_id, module_id=module.id if module else None ), }, ), @@ -602,7 +458,8 @@ def module_edit( "title": "UE de rattachement", "explanation": "utilisée notamment pour les malus", "labels": [ - f"S{u.semestre_idx if u.semestre_idx is not None else '.'} / {u.acronyme} {u.titre}" + f"""S{u.semestre_idx if u.semestre_idx is not None else '.' + } / {u.acronyme} {u.titre}""" for u in ues ], "allowed_values": [u.id for u in ues], @@ -631,7 +488,8 @@ def module_edit( "input_type": "menu", "type": "int", "title": parcours.SESSION_NAME.capitalize(), - "explanation": f"{parcours.SESSION_NAME} de début du module dans la formation standard", + "explanation": f"""{parcours.SESSION_NAME + } de début du module dans la formation standard""", "labels": [str(x) for x in semestres_indices], "allowed_values": semestres_indices, "enabled": unlocked, @@ -846,8 +704,7 @@ def module_edit( tf[2]["matiere_id"] = matiere.id tf[2]["semestre_id"] = ue.semestre_idx - module_id = do_module_create(tf[2]) - module = db.session.get(Module, module_id) + module = Module.create_from_dict(tf[2], news=True) else: # EDITION MODULE # l'UE de rattachement peut changer tf[2]["ue_id"], tf[2]["matiere_id"] = tf[2]["ue_matiere_id"].split("!") @@ -892,6 +749,7 @@ def module_edit( ] db.session.add(module) db.session.commit() + module.formation.invalidate_cached_sems() return flask.redirect( url_for( "notes.ue_table", @@ -904,28 +762,36 @@ def module_edit( def module_table(formation_id): """Liste des modules de la formation - (XXX inutile ou a revoir) + (affichage debug) """ - if not formation_id: - raise ScoValueError("invalid formation !") - formation: Formation = Formation.query.get_or_404(formation_id) + formation = Formation.get_formation(formation_id) + editable = current_user.has_permission(Permission.EditFormation) + H = [ - f"""{str_module}' + ) if editable: H.append( - 'modifier' - % module_dict - ) - H.append( - 'supprimer' - % module_dict + f""" + modifier + supprimer + """ ) H.append("
formation_id=%s" % sem["formation_id"], + f"""
formation_id={sem["formation_id"]}""", ] if bad_ue: H += [ diff --git a/app/views/scolar.py b/app/views/scolar.py index 59cdba472..5ddaf4c93 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -86,7 +86,6 @@ from app.scodoc import ( sco_archives_etud, sco_bug_report, sco_cache, - sco_debouche, sco_dept, sco_dump_db, sco_etud, diff --git a/sco_version.py b/sco_version.py index e9ebfa7cd..92963199f 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,6 +1,8 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- +"Infos sur version ScoDoc" + SCOVERSION = "9.7.28" SCONAME = "ScoDoc" diff --git a/tests/api/setup_test_api.py b/tests/api/setup_test_api.py index 097877e04..9b0e38c86 100644 --- a/tests/api/setup_test_api.py +++ b/tests/api/setup_test_api.py @@ -117,7 +117,7 @@ def GET( print("reply", reply.text) raise APIError( errmsg or f"""erreur get {url} !""", - reply.json(), + reply if reply.status_code == 404 else reply.json(), status_code=reply.status_code, ) if raw: @@ -220,7 +220,8 @@ def check_failure_get(path: str, headers: dict, err: str = None): # ^ Renvoi un 404 except APIError as api_err: if err is not None: - assert api_err.payload["message"] == err + if "message" in api_err.payload: + assert api_err.payload["message"] == err else: raise APIError("Le GET n'aurait pas du fonctionner") diff --git a/tests/api/test_api_formations.py b/tests/api/test_api_formations.py index ae7b1e49d..8192961bc 100644 --- a/tests/api/test_api_formations.py +++ b/tests/api/test_api_formations.py @@ -177,7 +177,7 @@ def test_formation_export(api_headers): assert isinstance(module["heures_td"], float) assert isinstance(module["heures_tp"], float) assert isinstance(module["coefficient"], float) - assert isinstance(module["ects"], str) + assert isinstance(module["ects"], str) if "ects" in module else True assert isinstance(module["semestre_id"], int) assert isinstance(module["numero"], int) assert isinstance(module["code_apogee"], str) diff --git a/tests/api/tools_test_api.py b/tests/api/tools_test_api.py index 66c3cfc0f..2d0486e5a 100644 --- a/tests/api/tools_test_api.py +++ b/tests/api/tools_test_api.py @@ -1,5 +1,6 @@ """Utilitaires pour les tests de l'API """ + import json @@ -37,11 +38,11 @@ def verify_occurences_ids_etuds(json_response) -> bool: DEPARTEMENT_FIELDS = [ - "id", "acronym", - "description", - "visible", "date_creation", + "description", + "id", + "visible", ] # Champs "données personnelles" @@ -67,17 +68,17 @@ ETUD_FIELDS = { FORMATION_FIELDS = { - "dept_id", "acronyme", - "titre_officiel", - "formation_code", "code_specialite", - "id", - "titre", - "version", - "type_parcours", - "referentiel_competence_id", + "dept_id", + "formation_code", "formation_id", + "id", + "referentiel_competence_id", + "titre_officiel", + "titre", + "type_parcours", + "version", } FORMATION_EXPORT_FIELDS = { @@ -95,39 +96,42 @@ FORMATION_EXPORT_FIELDS = { FORMATION_EXPORT_UE_FIELDS = { "acronyme", + "code_apogee", + "coefficient", + "color", + "ects", + "is_external", + "matiere", "numero", + "reference", + "semestre_idx", "titre", "type", "ue_code", - "ects", - "is_external", - "code_apogee", - "coefficient", - "semestre_idx", - "color", - "reference", - "matiere", } FORMATION_EXPORT_UE_MATIERE_FIELDS = { - "titre", - "numero", "module", + "numero", + "titre", } FORMATION_EXPORT_UE_MATIERE_MODULE_FIELDS = { - "titre", "abbrev", + "app_critiques", + "code_apogee", "code", + "coefficient", + "coefficients", + "edt_id", "heures_cours", "heures_td", - "coefficient", - "ects", - "semestre_id", - "numero", - "code_apogee", + "heures_tp", "module_type", - "coefficients", + "numero", + "parcours", + "semestre_id", + "titre", } FORMATION_EXPORT_UE_MATIERE_MODULE_COEF_FIELDS = { @@ -136,42 +140,42 @@ FORMATION_EXPORT_UE_MATIERE_MODULE_COEF_FIELDS = { } FORMSEMESTRE_FIELDS = [ - "titre", - "gestion_semestrielle", - "scodoc7_id", - "date_debut", + "block_moyenne_generale", + "block_moyennes", "bul_bgcolor", + "bul_hide_xml", + "date_debut_iso", + "date_debut", + "date_fin_iso", "date_fin", - "resp_can_edit", + "departement", "dept_id", + "elt_annee_apo", + "elt_sem_apo", + "ens_can_edit_eval", + "etape_apo", "etat", - "resp_can_change_ens", + "formation_id", + "formation", + "formsemestre_id", + "gestion_compensation", + "gestion_semestrielle", "id", "modalite", - "ens_can_edit_eval", - "formation_id", - "gestion_compensation", - "elt_sem_apo", - "semestre_id", - "bul_hide_xml", - "elt_annee_apo", - "block_moyenne_generale", - "formsemestre_id", - "titre_num", - "titre_formation", - "date_debut_iso", - "date_fin_iso", - "responsables", "parcours", - "departement", - "formation", - "etape_apo", - "block_moyennes", + "resp_can_change_ens", + "resp_can_edit", + "responsables", + "scodoc7_id", + "semestre_id", + "titre_formation", + "titre_num", + "titre", ] FSEM_FIELDS = { - "block_moyennes", "block_moyenne_generale", + "block_moyennes", "bul_bgcolor", "bul_hide_xml", "date_debut_iso", @@ -198,123 +202,123 @@ FSEM_FIELDS = { } MODIMPL_FIELDS = { - "id", - "formsemestre_id", "computation_expr", - "module_id", - "responsable_id", - "moduleimpl_id", "ens", + "formsemestre_id", + "id", + "module_id", "module", + "moduleimpl_id", + "responsable_id", } MODULE_FIELDS = { - "heures_tp", - "code_apogee", - "titre", - "coefficient", - "module_type", - "id", - "ects", "abbrev", - "ue_id", + "code_apogee", "code", + "coefficient", + "ects", "formation_id", "heures_cours", - "matiere_id", "heures_td", - "semestre_id", - "numero", + "heures_tp", + "id", + "matiere_id", "module_id", + "module_type", + "numero", + "semestre_id", + "titre", + "ue_id", } UE_FIELDS = { - "semestre_idx", - "type", - "formation_id", - "ue_code", - "id", - "ects", "acronyme", - "is_external", - "numero", "code_apogee", - "titre", "coefficient", "color", + "ects", + "formation_id", + "id", + "is_external", + "numero", + "semestre_idx", + "titre", + "type", + "ue_code", "ue_id", } BULLETIN_FIELDS = { - "version", - "type", "date", - "publie", + "etat_inscription", "etudiant", "formation", "formsemestre_id", - "etat_inscription", "options", + "publie", "ressources", "saes", - "ues", "semestre", + "type", + "ues", + "version", } BULLETIN_ETUDIANT_FIELDS = { + "boursier", "civilite", "code_ine", "code_nip", + "codepostaldomicile", "date_naissance", - "dept_id", "dept_acronym", + "dept_id", + "dept_naissance", + "description", + "domicile", "email", "emailperso", "etudid", - "nom", - "prenom", - "nomprenom", - "lieu_naissance", - "dept_naissance", - "nationalite", - "boursier", - "fiche_url", - "photo_url", - "id", - "domicile", - "villedomicile", - "telephone", "fax", - "description", - "codepostaldomicile", + "fiche_url", + "id", + "lieu_naissance", + "nationalite", + "nom", + "nomprenom", "paysdomicile", + "photo_url", + "prenom", + "telephone", "telephonemobile", "typeadresse", + "villedomicile", } BULLETIN_FORMATION_FIELDS = {"id", "acronyme", "titre_officiel", "titre"} BULLETIN_OPTIONS_FIELDS = { - "show_abs", "show_abs_modules", - "show_ects", + "show_abs", "show_codemodules", + "show_coef", + "show_date_inscr", + "show_ects", "show_matieres", - "show_rangs", - "show_ue_rangs", + "show_minmax_eval", + "show_minmax_mod", + "show_minmax", "show_mod_rangs", "show_moypromo", - "show_minmax", - "show_minmax_mod", - "show_minmax_eval", - "show_coef", - "show_ue_cap_details", - "show_ue_cap_current", + "show_rangs", "show_temporary", - "temporary_txt", + "show_ue_cap_current", + "show_ue_cap_details", + "show_ue_rangs", "show_uevalid", - "show_date_inscr", + "temporary_txt", } BULLETIN_RESSOURCES_FIELDS = { @@ -346,23 +350,23 @@ BULLETIN_SAES_FIELDS = { ########### RESSOURCES ET SAES ########### BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_FIELDS = { - "id", - "titre", "code_apogee", - "url", - "moyenne", "evaluations", + "id", + "moyenne", + "titre", + "url", } BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_FIELDS = { - "id", - "description", + "coef", "date", + "description", "heure_debut", "heure_fin", - "coef", - "poids", + "id", "note", + "poids", "url", } @@ -373,10 +377,10 @@ BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_POIDS_FIELDS = { } BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_NOTE_FIELDS = { - "value", - "min", "max", + "min", "moy", + "value", } @@ -384,19 +388,19 @@ BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_NOTE_FIELDS = { BULLETIN_UES_FIELDS = {"RT1.1", "RT2.1", "RT3.1"} BULLETIN_UES_UE_FIELDS = { - "id", - "titre", - "numero", - "type", + "bonus", + "capitalise", "color", "competence", - "moyenne", - "bonus", + "ECTS", + "id", "malus", - "capitalise", + "moyenne", + "numero", "ressources", "saes", - "ECTS", + "titre", + "type", } BULLETIN_UES_UE_MOYENNE_FIELDS = {"value", "min", "max", "moy", "rang", "total"} @@ -461,16 +465,16 @@ BULLETIN_UES_UE_ECTS_FIELDS = {"acquis", "total"} ########### SEMESTRE ########### BULLETIN_SEMESTRE_FIELDS = { - "etapes", + "absences", + "annee_universitaire", "date_debut", "date_fin", - "annee_universitaire", - "numero", - "inscription", - "groupes", - "absences", "ECTS", + "etapes", + "groupes", + "inscription", "notes", + "numero", "rang", } @@ -484,78 +488,78 @@ BULLETIN_SEMESTRE_RANG_FIELDS = {"value", "total"} EVAL_FIELDS = { - "id", - "description", + "coefficient", "date_debut", "date_fin", - "coefficient", + "description", + "etat", "evaluation_type", + "id", "moduleimpl_id", + "nb_inscrits", + "nb_notes_abs", + "nb_notes_att", + "nb_notes_exc", + "nb_notes_manquantes", "note_max", "numero", "poids", "publish_incomplete", - "visibulletin", - "etat", - "nb_inscrits", - "nb_notes_manquantes", - "nb_notes_abs", - "nb_notes_att", - "nb_notes_exc", "saisie_notes", + "visibulletin", } SAISIE_NOTES_FIELDS = {"datetime_debut", "datetime_fin", "datetime_mediane"} REF_COMP_FIELDS = { - "dept_id", "annexe", - "specialite", - "specialite_long", - "type_structure", - "type_departement", - "type_titre", - "version_orebut", + "competences", + "dept_id", + "parcours", "scodoc_date_loaded", "scodoc_orig_filename", - "competences", - "parcours", + "specialite_long", + "specialite", + "type_departement", + "type_structure", + "type_titre", + "version_orebut", } ABSENCES_FIELDS = { - "jour", - "matin", + "begin", + "description", + "end", "estabs", "estjust", - "description", - "begin", - "end", + "jour", + "matin", } ABSENCES_GROUP_ETAT_FIELDS = {"etudid", "list_abs"} FORMSEMESTRE_ETUD_FIELDS = { - "id", - "code_nip", - "code_ine", - "nom", - "nom_usuel", - "prenom", "civilite", + "code_ine", + "code_nip", "groups", + "id", + "nom_usuel", + "nom", + "prenom", } FORMSEMESTRE_ETUS_GROUPS_FIELDS = { - "partition_id", - "id", - "formsemestre_id", - "partition_name", - "numero", "bul_show_rank", - "show_in_lists", + "formsemestre_id", "group_id", "group_name", + "id", + "numero", + "partition_id", + "partition_name", + "show_in_lists", } EVALUATIONS_FIELDS = { @@ -573,107 +577,107 @@ EVALUATIONS_FIELDS = { } NOTES_FIELDS = { - "etudid", - "evaluation_id", - "value", "comment", "date", + "etudid", + "evaluation_id", "uid", + "value", } PARTITIONS_FIELDS = { - "id", - "formsemestre_id", - "partition_name", - "numero", "bul_show_rank", + "formsemestre_id", + "id", + "numero", + "partition_name", "show_in_lists", } PARTITION_GROUPS_ETUD_FIELDS = { - "id", + "civilite", + "code_ine", + "code_nip", "dept_id", + "id", + "nom_usuel", "nom", "prenom", - "nom_usuel", - "civilite", - "code_nip", - "code_ine", } FORMSEMESTRE_BULLETINS_FIELDS = { - "version", - "type", "date", - "publie", + "etat_inscription", "etudiant", "formation", "formsemestre_id", - "etat_inscription", "options", + "publie", "ressources", "saes", - "ues", "semestre", + "type", + "ues", + "version", } FORMSEMESTRE_BULLETINS_ETU_FIELDS = { + "boursier", "civilite", "code_ine", "code_nip", + "codepostaldomicile", "date_naissance", - "dept_id", "dept_acronym", + "dept_id", + "dept_naissance", + "description", + "domicile", "email", "emailperso", "etudid", - "nom", - "prenom", - "nomprenom", - "lieu_naissance", - "dept_naissance", - "nationalite", - "boursier", + "fax", "fiche_url", - "photo_url", "id", - "codepostaldomicile", + "lieu_naissance", + "nationalite", + "nom", + "nomprenom", "paysdomicile", + "photo_url", + "prenom", + "telephone", "telephonemobile", "typeadresse", - "domicile", "villedomicile", - "telephone", - "fax", - "description", } FORMSEMESTRE_BULLETINS_FORMATION_FIELDS = { - "id", "acronyme", + "id", "titre_officiel", "titre", } FORMSEMESTRE_BULLETINS_OPT_FIELDS = { - "show_abs", "show_abs_modules", - "show_ects", + "show_abs", "show_codemodules", + "show_coef", + "show_date_inscr", + "show_ects", "show_matieres", - "show_rangs", - "show_ue_rangs", + "show_minmax_eval", + "show_minmax_mod", + "show_minmax", "show_mod_rangs", "show_moypromo", - "show_minmax", - "show_minmax_mod", - "show_minmax_eval", - "show_coef", - "show_ue_cap_details", - "show_ue_cap_current", + "show_rangs", "show_temporary", - "temporary_txt", + "show_ue_cap_current", + "show_ue_cap_details", + "show_ue_rangs", "show_uevalid", - "show_date_inscr", + "temporary_txt", } diff --git a/tests/scenarios/test_scenario1_formation.py b/tests/scenarios/test_scenario1_formation.py index eb93f3d6b..e1903da87 100644 --- a/tests/scenarios/test_scenario1_formation.py +++ b/tests/scenarios/test_scenario1_formation.py @@ -12,7 +12,8 @@ Usage: pytest tests/scenarios/test_scenario1_formation.py # code écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en août 2021 from tests.unit import sco_fake_gen -from app.formations import edit_module, formation_io +from app.formations import formation_io +from app.models import Formation @pytest.mark.skip # test obsolete @@ -52,11 +53,11 @@ def run_scenario1(): ] # --- Implémentation des modules - modules = edit_module.module_list({"formation_id": formation_id}) + formation = Formation.get_formation(formation_id) mods_imp = [] - for mod in modules: + for mod in formation.modules: mi = G.create_moduleimpl( - module_id=mod["module_id"], - formsemestre_id=sems[mod["semestre_id"] - 1]["formsemestre_id"], + module_id=mod.id, + formsemestre_id=sems[mod.semestre_id - 1]["formsemestre_id"], ) mods_imp.append(mi) diff --git a/tests/unit/sco_fake_gen.py b/tests/unit/sco_fake_gen.py index ef3976826..d9545c961 100644 --- a/tests/unit/sco_fake_gen.py +++ b/tests/unit/sco_fake_gen.py @@ -16,7 +16,7 @@ import typing from app import db, log from app.auth.models import User -from app.formations import edit_matiere, edit_module, edit_ue +from app.formations import edit_ue from app.models import ( Departement, Evaluation, @@ -24,13 +24,13 @@ from app.models import ( FormationModalite, Identite, Matiere, + Module, ModuleImpl, ) from app.scodoc import codes_cursus from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_validation -from app.scodoc import sco_moduleimpl from app.scodoc import sco_saisie_notes from app.scodoc import sco_synchro_etuds from app.scodoc import sco_utils as scu @@ -228,11 +228,8 @@ class ScoFake(object): matiere = db.session.get(Matiere, matiere_id) ue_id = matiere.ue.id formation_id = matiere.ue.formation.id - oid = edit_module.do_module_create(locals()) - oids = edit_module.module_list(args={"module_id": oid}) - if not oids: - raise ScoValueError(f"module not created ! (oid={oid})") - return oid + module = Module.create_from_dict(locals(), news=True, inval_cache=True) + return module.id @logging_meth def create_formsemestre( @@ -276,11 +273,8 @@ class ScoFake(object): ) -> int: if not responsable_id: responsable_id = self.default_user.id - oid = sco_moduleimpl.do_moduleimpl_create(locals()) - oids = sco_moduleimpl.moduleimpl_list(moduleimpl_id=oid) # API inconsistency - if not oids: - raise ScoValueError("moduleimpl not created !") - return oid + modimpl = ModuleImpl.create_from_dict(locals()) + return modimpl.id @logging_meth def inscrit_etudiant(self, formsemestre_id: int, etud: dict): diff --git a/tests/unit/test_formations.py b/tests/unit/test_formations.py index e234e1ff5..a68114891 100644 --- a/tests/unit/test_formations.py +++ b/tests/unit/test_formations.py @@ -34,8 +34,7 @@ # - moduleimpl_list # - do_module_impl_with_module_list # - do_formsemestre_delete -# - module_list -# - do_module_delete +# - Module.delete # - ue_list # - do_ue_delete # - do_formation_delete @@ -52,7 +51,7 @@ from app.formations import ( edit_ue, formation_io, ) -from app.models import Formation, Matiere, ModuleImpl +from app.models import Formation, Matiere, Module, ModuleImpl from app.scodoc import sco_formsemestre from app.scodoc import sco_exceptions from app.scodoc import sco_formsemestre_edit @@ -259,7 +258,7 @@ def test_formations(test_client): formsemestre_id=sem2["formsemestre_id"] ) - li_module = edit_module.module_list() + li_module = Module.query.all() assert len(li_module) == 4 # Suppression impossible car utilisé dans le semestre formsemestre_idt: module3 = db.session.get(ModuleImpl, mi3).module @@ -268,13 +267,14 @@ def test_formations(test_client): sco_formsemestre_edit.do_formsemestre_delete(formsemestre_idt) - li_module2_before = edit_module.module_list() + li_module2_before = Module.query.all() - edit_module.do_module_delete(module3.id) - edit_module.do_module_delete(module_id_t) + module3.delete() + module_t = db.session.get(Module, module_id_t) + module_t.delete() # deuxieme methode de supression d'un module - li_module2_after = edit_module.module_list() + li_module2_after = Module.query.all() assert ( len(li_module2_after) == len(li_module2_before) - 2 @@ -340,14 +340,14 @@ def test_import_formation(test_client, filename="formation-exemple-1.xml"): ) ] # et les modules - modules = edit_module.module_list({"formation_id": formation_id}) - for mod in modules: + formation = Formation.get_formation(formation_id) + for mod in formation.modules: moduleimpl_id = G.create_moduleimpl( - module_id=mod["module_id"], - formsemestre_id=formsemestre_ids[mod["semestre_id"] - 1], + module_id=mod.id, + formsemestre_id=formsemestre_ids[mod.semestre_id - 1], ) mi = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] - assert mi["module_id"] == mod["module_id"] + assert mi["module_id"] == mod.id # --- Export formation en XML doc1 = formation_io.formation_export(formation_id, fmt="xml").get_data(as_text=True)