forked from ScoDoc/ScoDoc
merge du master + ajout de abs_group_etat + ajout de test pour departements et etudiants
This commit is contained in:
parent
864d90e22c
commit
61830180a5
@ -5,7 +5,7 @@ from flask import jsonify
|
||||
from app.api import bp
|
||||
from app.api.errors import error_response
|
||||
from app.api.auth import token_auth, token_permission_required
|
||||
from app.api.tools import get_etu_from_etudid_or_nip_or_ine
|
||||
from app.api.tools import get_etud_from_etudid_or_nip_or_ine
|
||||
from app.scodoc import notesdb as ndb
|
||||
|
||||
from app.scodoc import sco_abs
|
||||
@ -50,12 +50,11 @@ def absences(etudid: int = None, nip: int = None, ine: int = None):
|
||||
"""
|
||||
if etudid is None:
|
||||
# Récupération de l'étudiant
|
||||
etud = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
etud = get_etud_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
if etud is None:
|
||||
return error_response(
|
||||
409,
|
||||
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||
"Veuillez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||
404,
|
||||
message="id de l'étudiant (etudid, nip, ine) inconnu",
|
||||
)
|
||||
etudid = etud.etudid
|
||||
|
||||
@ -103,16 +102,13 @@ def absences_just(etudid: int = None, nip: int = None, ine: int = None):
|
||||
]
|
||||
"""
|
||||
if etudid is None:
|
||||
# Récupération de l'étudiant
|
||||
try:
|
||||
etu = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
etudid = etu.etudid
|
||||
except AttributeError:
|
||||
etud = get_etud_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
if etud is None:
|
||||
return error_response(
|
||||
409,
|
||||
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||
"Veuillez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||
404,
|
||||
message="id de l'étudiant (etudid, nip, ine) inconnu",
|
||||
)
|
||||
etudid = etud.etudid
|
||||
|
||||
# Récupération des absences justifiées de l'étudiant
|
||||
abs_just = [
|
||||
|
@ -1,57 +1,66 @@
|
||||
############################################### Departements ##########################################################
|
||||
|
||||
import json
|
||||
from flask import jsonify
|
||||
|
||||
import app
|
||||
from app import models
|
||||
from app.api import bp
|
||||
from app.api.auth import token_auth, token_permission_required
|
||||
from app.api.errors import error_response
|
||||
from app.models import Departement, FormSemestre
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
|
||||
@bp.route("/departements", methods=["GET"])
|
||||
def get_departement(dept_ident: str) -> Departement:
|
||||
"Le departement, par id ou acronyme. Erreur 404 si pas trouvé."
|
||||
try:
|
||||
dept_id = int(dept_ident)
|
||||
except ValueError:
|
||||
dept_id = None
|
||||
if dept_id is None:
|
||||
return Departement.query.filter_by(acronym=dept_ident).first_or_404()
|
||||
return Departement.query.get_or_404(dept_id)
|
||||
|
||||
|
||||
@bp.route("/departements_ids", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def departements():
|
||||
def departements_ids():
|
||||
"""Liste des ids de départements"""
|
||||
return jsonify([dept.id for dept in Departement.query])
|
||||
|
||||
|
||||
@bp.route("/departement/<string:dept_ident>", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def departement(dept_ident: str):
|
||||
"""
|
||||
Retourne la liste des départements visibles
|
||||
Info sur un département. Accès par id ou acronyme.
|
||||
|
||||
Exemple de résultat :
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"acronym": "TAPI",
|
||||
"description": null,
|
||||
"visible": true,
|
||||
"date_creation": "Fri, 15 Apr 2022 12:19:28 GMT"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"acronym": "MMI",
|
||||
"description": null,
|
||||
"visible": false,
|
||||
"date_creation": "Fri, 18 Apr 2022 11:20:8 GMT"
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
"""
|
||||
# Récupération de tous les départements
|
||||
depts = models.Departement.query.all()
|
||||
|
||||
# Mise en place de la liste avec tous les départements
|
||||
data = [d.to_dict() for d in depts]
|
||||
|
||||
return jsonify(data)
|
||||
dept = get_departement(dept_ident)
|
||||
return jsonify(dept.to_dict())
|
||||
|
||||
|
||||
@bp.route("/departements/<string:dept>/etudiants/list", methods=["GET"])
|
||||
@bp.route(
|
||||
"/departements/<string:dept>/etudiants/list/<int:formsemestre_id>", methods=["GET"]
|
||||
)
|
||||
@bp.route("/departements", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def list_etudiants(dept: str, formsemestre_id=None):
|
||||
def departements():
|
||||
"""Liste les départements"""
|
||||
return jsonify([dept.to_dict() for dept in Departement.query])
|
||||
|
||||
|
||||
@bp.route("/departement/<string:dept_ident>/etudiants", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def list_etudiants(dept_ident: str):
|
||||
"""
|
||||
Retourne la liste des étudiants d'un département
|
||||
|
||||
@ -61,54 +70,39 @@ def list_etudiants(dept: str, formsemestre_id=None):
|
||||
Exemple de résultat :
|
||||
[
|
||||
{
|
||||
"civilite": "X",
|
||||
"code_ine": null,
|
||||
"code_nip": null,
|
||||
"civilite": "M",
|
||||
"ine": "7899X61616",
|
||||
"nip": "F6777H88",
|
||||
"date_naissance": null,
|
||||
"email": null,
|
||||
"email": "toto@toto.fr",
|
||||
"emailperso": null,
|
||||
"etudid": 18,
|
||||
"nom": "MOREL",
|
||||
"prenom": "JACQUES"
|
||||
},
|
||||
{
|
||||
"civilite": "X",
|
||||
"code_ine": null,
|
||||
"code_nip": null,
|
||||
"date_naissance": null,
|
||||
"email": null,
|
||||
"emailperso": null,
|
||||
"etudid": 19,
|
||||
"nom": "FOURNIER",
|
||||
"prenom": "ANNE"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
# Si le formsemestre_id a été renseigné
|
||||
if formsemestre_id is not None:
|
||||
# Récupération du formsemestre
|
||||
formsemestre = models.FormSemestre.query.filter_by(
|
||||
id=formsemestre_id
|
||||
).first_or_404()
|
||||
# Récupération du département
|
||||
departement = formsemestre.departement
|
||||
# Le département, spécifié par un id ou un acronyme
|
||||
dept = get_departement(dept_ident)
|
||||
|
||||
# Si le formsemestre_id n'a pas été renseigné
|
||||
else:
|
||||
# Récupération du formsemestre
|
||||
departement = models.Departement.query.filter_by(acronym=dept).first_or_404()
|
||||
|
||||
# Mise en forme des données
|
||||
list_etu = [etu.to_dict_bul(include_urls=False) for etu in departement.etudiants]
|
||||
|
||||
return jsonify(list_etu)
|
||||
return jsonify([etud.to_dict_short() for etud in dept.etudiants])
|
||||
|
||||
|
||||
@bp.route("/departements/<string:dept>/semestres_courants", methods=["GET"])
|
||||
@bp.route("/departement/<string:dept_ident>/formsemestres_ids", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def liste_semestres_courant(dept: str):
|
||||
def formsemestres_ids(dept_ident: str):
|
||||
"""liste des ids formsemestre du département"""
|
||||
# Le département, spécifié par un id ou un acronyme
|
||||
dept = get_departement(dept_ident)
|
||||
return jsonify([formsemestre.id for formsemestre in dept.formsemestres])
|
||||
|
||||
|
||||
@bp.route("/departement/<string:dept_ident>/formsemestres_courants", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def liste_semestres_courant(dept_ident: str):
|
||||
"""
|
||||
Liste des semestres actifs d'un départements donné
|
||||
|
||||
@ -117,11 +111,16 @@ def liste_semestres_courant(dept: str):
|
||||
Exemple de résultat :
|
||||
[
|
||||
{
|
||||
"date_fin": "31/08/2022",
|
||||
"titre": "master machine info",
|
||||
"gestion_semestrielle": false,
|
||||
"scodoc7_id": null,
|
||||
"date_debut": "01/09/2021",
|
||||
"bul_bgcolor": null,
|
||||
"date_fin": "15/12/2022",
|
||||
"resp_can_edit": false,
|
||||
"dept_id": 1,
|
||||
"etat": true,
|
||||
"resp_can_change_ens": true,
|
||||
"resp_can_change_ens": false,
|
||||
"id": 1,
|
||||
"modalite": "FI",
|
||||
"ens_can_edit_eval": false,
|
||||
@ -131,32 +130,27 @@ def liste_semestres_courant(dept: str):
|
||||
"semestre_id": 1,
|
||||
"bul_hide_xml": false,
|
||||
"elt_annee_apo": null,
|
||||
"titre": "Semestre test",
|
||||
"block_moyennes": false,
|
||||
"scodoc7_id": null,
|
||||
"date_debut": "01/09/2021",
|
||||
"gestion_semestrielle": false,
|
||||
"bul_bgcolor": "white",
|
||||
"formsemestre_id": 1,
|
||||
"titre_num": "Semestre test semestre 1",
|
||||
"titre_num": "master machine info semestre 1",
|
||||
"date_debut_iso": "2021-09-01",
|
||||
"date_fin_iso": "2022-08-31",
|
||||
"date_fin_iso": "2022-12-15",
|
||||
"responsables": [
|
||||
12,
|
||||
42
|
||||
],
|
||||
"titre_court": "BUT MMI"
|
||||
3,
|
||||
2
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
# Récupération des départements comportant l'acronym mit en paramètre
|
||||
dept = models.Departement.query.filter_by(acronym=dept).first_or_404()
|
||||
# Le département, spécifié par un id ou un acronyme
|
||||
dept = get_departement(dept_ident)
|
||||
|
||||
# Récupération des semestres suivant id_dept
|
||||
semestres = models.FormSemestre.query.filter_by(dept_id=dept.id, etat=True)
|
||||
# Les semestres en cours de ce département
|
||||
formsemestres = models.FormSemestre.query.filter(
|
||||
FormSemestre.dept_id == dept.id,
|
||||
FormSemestre.date_debut <= app.db.func.now(),
|
||||
FormSemestre.date_fin >= app.db.func.now(),
|
||||
)
|
||||
|
||||
# Mise en forme des données
|
||||
data = [d.to_dict_api() for d in semestres]
|
||||
|
||||
return jsonify(data)
|
||||
return jsonify([d.to_dict() for d in formsemestres])
|
||||
|
@ -7,12 +7,10 @@ from app import models
|
||||
from app.api import bp
|
||||
from app.api.errors import error_response
|
||||
from app.api.auth import token_auth, token_permission_required
|
||||
from app.api.tools import get_etu_from_etudid_or_nip_or_ine
|
||||
from app.api.tools import get_etud_from_etudid_or_nip_or_ine
|
||||
from app.models import FormSemestreInscription, FormSemestre, Identite
|
||||
from app.scodoc import sco_bulletins
|
||||
from app.scodoc import sco_groups
|
||||
from app.scodoc.sco_bulletins import do_formsemestre_bulletinetud
|
||||
from app.scodoc.sco_bulletins_pdf import get_etud_bulletins_pdf
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
|
||||
@ -22,7 +20,7 @@ from app.scodoc.sco_permissions import Permission
|
||||
@token_permission_required(Permission.APIView)
|
||||
def etudiants_courant(long=False):
|
||||
"""
|
||||
Retourne la liste des étudiants courant
|
||||
Liste des étudiants inscrits dans un formsemestre actuellement en cours.
|
||||
|
||||
Exemple de résultat :
|
||||
[
|
||||
@ -43,7 +41,6 @@ def etudiants_courant(long=False):
|
||||
...
|
||||
]
|
||||
"""
|
||||
# Récupération de tous les étudiants
|
||||
etuds = Identite.query.filter(
|
||||
Identite.id == FormSemestreInscription.etudid,
|
||||
FormSemestreInscription.formsemestre_id == FormSemestre.id,
|
||||
@ -99,8 +96,12 @@ def etudiant(etudid: int = None, nip: int = None, ine: int = None):
|
||||
}
|
||||
"""
|
||||
# Récupération de l'étudiant
|
||||
etud = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
|
||||
etud = get_etud_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
if etud is None:
|
||||
return error_response(
|
||||
404,
|
||||
message="id de l'étudiant (etudid, nip, ine) inconnu",
|
||||
)
|
||||
# Mise en forme des données
|
||||
data = etud.to_dict_bul(include_urls=False)
|
||||
|
||||
@ -147,85 +148,56 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None)
|
||||
"titre_num": "Semestre test semestre 1",
|
||||
"date_debut_iso": "2021-09-01",
|
||||
"date_fin_iso": "2022-08-31",
|
||||
"responsables": [
|
||||
12,
|
||||
42
|
||||
],
|
||||
"titre_court": "BUT MMI"
|
||||
"responsables": []
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
# Récupération de l'étudiant
|
||||
etud = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
etud = get_etud_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
if etud is None:
|
||||
return error_response(
|
||||
404,
|
||||
message="id de l'étudiant (etudid, nip, ine) inconnu",
|
||||
)
|
||||
|
||||
formsemestres = models.FormSemestre.query.filter(
|
||||
models.FormSemestreInscription.etudid == etud.id,
|
||||
models.FormSemestreInscription.formsemestre_id == models.FormSemestre.id,
|
||||
).order_by(models.FormSemestre.date_debut)
|
||||
|
||||
return jsonify([formsemestre.to_dict_api() for formsemestre in formsemestres])
|
||||
return jsonify([formsemestre.to_dict() for formsemestre in formsemestres])
|
||||
|
||||
|
||||
@bp.route(
|
||||
"/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||
methods=["GET"],
|
||||
defaults={"version": "long", "format": "json"},
|
||||
defaults={"version": "long"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||
methods=["GET"],
|
||||
defaults={"version": "long", "format": "json"},
|
||||
defaults={"version": "long"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||
methods=["GET"],
|
||||
defaults={"version": "long", "format": "json"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "long", "format": "pdf"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "long", "format": "pdf"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "long", "format": "pdf"},
|
||||
defaults={"version": "long"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin/short",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "format": "json"},
|
||||
defaults={"version": "short"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin/short",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "format": "json"},
|
||||
defaults={"version": "short"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin/short",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "format": "json"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "format": "pdf"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "format": "pdf"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "format": "pdf"},
|
||||
defaults={"version": "short"},
|
||||
)
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
@ -235,7 +207,6 @@ def etudiant_bulletin_semestre(
|
||||
nip: int = None,
|
||||
ine: int = None,
|
||||
version="long",
|
||||
format="json",
|
||||
):
|
||||
"""
|
||||
Retourne le bulletin d'un étudiant en fonction de son id et d'un semestre donné
|
||||
@ -421,23 +392,15 @@ def etudiant_bulletin_semestre(
|
||||
|
||||
app.set_sco_dept(dept.acronym)
|
||||
|
||||
# Récupération de l'étudiant
|
||||
try:
|
||||
etu = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
except AttributeError:
|
||||
etud = get_etud_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
if etud is None:
|
||||
return error_response(
|
||||
409,
|
||||
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||
"Veuillez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||
404,
|
||||
message="id de l'étudiant (etudid, nip, ine) inconnu",
|
||||
)
|
||||
if format == "json":
|
||||
return sco_bulletins.get_formsemestre_bulletin_etud_json(
|
||||
formsemestre, etu, version
|
||||
formsemestre, etud, version
|
||||
)
|
||||
else:
|
||||
etudid = etu.id
|
||||
print(etudid)
|
||||
return do_formsemestre_bulletinetud(formsemestre, etudid, version, format)
|
||||
|
||||
|
||||
@bp.route(
|
||||
@ -490,12 +453,11 @@ def etudiant_groups(
|
||||
]
|
||||
"""
|
||||
if etudid is None:
|
||||
etud = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
etud = get_etud_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
if etud is None:
|
||||
return error_response(
|
||||
409,
|
||||
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||
"Veuillez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||
404,
|
||||
message="id de l'étudiant (etudid, nip, ine) inconnu",
|
||||
)
|
||||
etudid = etud.etudid
|
||||
|
||||
|
@ -99,7 +99,7 @@ def evaluation_notes(evaluation_id: int):
|
||||
data = do_evaluation_get_all_notes(evaluation_id)
|
||||
except AttributeError: # ???
|
||||
return error_response(
|
||||
409,
|
||||
404,
|
||||
message="La requête ne peut être traitée en l’état actuel.",
|
||||
)
|
||||
|
||||
|
@ -29,10 +29,10 @@ def formations_ids():
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@bp.route("/formations/<int:formation_id>", methods=["GET"])
|
||||
@bp.route("/formation/<int:formation_id>", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def formations_by_id(formation_id: int):
|
||||
def formation_by_id(formation_id: int):
|
||||
"""
|
||||
Retourne une formation en fonction d'un id donné
|
||||
|
||||
@ -63,12 +63,12 @@ def formations_by_id(formation_id: int):
|
||||
|
||||
|
||||
@bp.route(
|
||||
"/formations/formation_export/<int:formation_id>",
|
||||
"/formation/formation_export/<int:formation_id>",
|
||||
methods=["GET"],
|
||||
defaults={"export_ids": False},
|
||||
)
|
||||
@bp.route(
|
||||
"/formations/formation_export/<int:formation_id>/with_ids",
|
||||
"/formation/formation_export/<int:formation_id>/with_ids",
|
||||
methods=["GET"],
|
||||
defaults={"export_ids": True},
|
||||
)
|
||||
@ -177,16 +177,12 @@ def formation_export_by_formation_id(formation_id: int, export_ids=False):
|
||||
# Utilisation de la fonction formation_export
|
||||
data = sco_formations.formation_export(formation_id, export_ids)
|
||||
except ValueError:
|
||||
return error_response(
|
||||
409,
|
||||
message="La requête ne peut être traitée en l’état actuel. \n"
|
||||
"Veillez vérifier la conformité du 'formation_id'",
|
||||
)
|
||||
return error_response(500, message="Erreur inconnue")
|
||||
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@bp.route("/formations/moduleimpl/<int:moduleimpl_id>", methods=["GET"])
|
||||
@bp.route("/formation/moduleimpl/<int:moduleimpl_id>", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def moduleimpl(moduleimpl_id: int):
|
||||
@ -199,7 +195,6 @@ def moduleimpl(moduleimpl_id: int):
|
||||
{
|
||||
"id": 1,
|
||||
"formsemestre_id": 1,
|
||||
"computation_expr": null,
|
||||
"module_id": 1,
|
||||
"responsable_id": 2,
|
||||
"moduleimpl_id": 1,
|
||||
@ -231,63 +226,7 @@ def moduleimpl(moduleimpl_id: int):
|
||||
|
||||
|
||||
@bp.route(
|
||||
"/formations/moduleimpl/formsemestre/<int:formsemestre_id>/list",
|
||||
methods=["GET"],
|
||||
)
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def moduleimpls_sem(formsemestre_id: int):
|
||||
"""
|
||||
Retourne la liste des moduleimpl d'un semestre
|
||||
|
||||
formsemestre_id : l'id d'un formsemestre
|
||||
|
||||
Exemple d'utilisation :
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"formsemestre_id": 1,
|
||||
"computation_expr": null,
|
||||
"module_id": 1,
|
||||
"responsable_id": 2,
|
||||
"module": {
|
||||
"heures_tp": 0.0,
|
||||
"code_apogee": "",
|
||||
"titre": "Initiation aux r\u00e9seaux informatiques",
|
||||
"coefficient": 1.0,
|
||||
"module_type": 2,
|
||||
"id": 1,
|
||||
"ects": null,
|
||||
"abbrev": "Init aux r\u00e9seaux informatiques",
|
||||
"ue_id": 1,
|
||||
"code": "R101",
|
||||
"formation_id": 1,
|
||||
"heures_cours": 0.0,
|
||||
"matiere_id": 1,
|
||||
"heures_td": 0.0,
|
||||
"semestre_id": 1,
|
||||
"numero": 10,
|
||||
"module_id": 1
|
||||
},
|
||||
"moduleimpl_id": 1,
|
||||
"ens": []
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
formsemestre = models.FormSemestre.query.filter_by(
|
||||
id=formsemestre_id
|
||||
).first_or_404()
|
||||
|
||||
moduleimpls = formsemestre.modimpls_sorted
|
||||
|
||||
data = [moduleimpl.to_dict() for moduleimpl in moduleimpls]
|
||||
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@bp.route(
|
||||
"/formations/<int:formation_id>/referentiel_competences",
|
||||
"/formation/<int:formation_id>/referentiel_competences",
|
||||
methods=["GET"],
|
||||
)
|
||||
@token_auth.login_required
|
||||
|
@ -4,14 +4,11 @@ from flask import jsonify
|
||||
import app
|
||||
from app import models
|
||||
from app.api import bp
|
||||
from app.api.errors import error_response
|
||||
from app.api.auth import token_auth, token_permission_required
|
||||
from app.api.tools import get_etu_from_etudid_or_nip_or_ine
|
||||
from app.models import FormSemestre, FormSemestreEtape
|
||||
from app.models import Departement, FormSemestre, FormSemestreEtape
|
||||
from app.scodoc.sco_bulletins import get_formsemestre_bulletin_etud_json
|
||||
from app.scodoc.sco_bulletins_json import make_json_formsemestre_bulletinetud
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc.sco_pvjury import formsemestre_pvjury
|
||||
from app.scodoc.sco_utils import ModuleType
|
||||
|
||||
|
||||
@bp.route("/formsemestre/<int:formsemestre_id>", methods=["GET"])
|
||||
@ -19,47 +16,50 @@ from app.scodoc.sco_pvjury import formsemestre_pvjury
|
||||
@token_permission_required(Permission.APIView)
|
||||
def formsemestre(formsemestre_id: int):
|
||||
"""
|
||||
Retourne l'information sur le formsemestre correspondant au formsemestre_id
|
||||
Information sur le formsemestre indiqué.
|
||||
|
||||
formsemestre_id : l'id d'un formsemestre
|
||||
formsemestre_id : l'id du formsemestre
|
||||
|
||||
Exemple de résultat :
|
||||
{
|
||||
"block_moyennes": false,
|
||||
"bul_bgcolor": "white",
|
||||
"bul_hide_xml": false,
|
||||
"date_debut_iso": "2021-09-01",
|
||||
"date_debut": "01/09/2021",
|
||||
"date_fin_iso": "2022-08-31",
|
||||
"date_fin": "31/08/2022",
|
||||
"resp_can_edit": false,
|
||||
"dept_id": 1,
|
||||
"elt_annee_apo": null,
|
||||
"elt_sem_apo": null,
|
||||
"ens_can_edit_eval": false,
|
||||
"etat": true,
|
||||
"resp_can_change_ens": true,
|
||||
"formation_id": 1,
|
||||
"formsemestre_id": 1,
|
||||
"gestion_compensation": false,
|
||||
"gestion_semestrielle": false,
|
||||
"id": 1,
|
||||
"modalite": "FI",
|
||||
"ens_can_edit_eval": false,
|
||||
"formation_id": 1,
|
||||
"gestion_compensation": false,
|
||||
"elt_sem_apo": null,
|
||||
"semestre_id": 1,
|
||||
"bul_hide_xml": false,
|
||||
"elt_annee_apo": null,
|
||||
"titre": "Semestre test",
|
||||
"block_moyennes": false,
|
||||
"resp_can_change_ens": true,
|
||||
"resp_can_edit": false,
|
||||
"responsables": [1, 99], // uids
|
||||
"scodoc7_id": null,
|
||||
"date_debut": "01/09/2021",
|
||||
"gestion_semestrielle": false,
|
||||
"bul_bgcolor": "white",
|
||||
"formsemestre_id": 1,
|
||||
"titre_num": "Semestre test semestre 1",
|
||||
"date_debut_iso": "2021-09-01",
|
||||
"date_fin_iso": "2022-08-31",
|
||||
"responsables": [
|
||||
12,
|
||||
42
|
||||
],
|
||||
"titre_court": "BUT MMI"
|
||||
"semestre_id": 1,
|
||||
"titre_formation" : "BUT GEA",
|
||||
"titre_num": "BUT GEA semestre 1",
|
||||
"titre": "BUT GEA",
|
||||
}
|
||||
|
||||
"""
|
||||
formsemestre = models.FormSemestre.query.filter_by(
|
||||
formsemestre: FormSemestre = models.FormSemestre.query.filter_by(
|
||||
id=formsemestre_id
|
||||
).first_or_404()
|
||||
data = formsemestre.to_dict_api()
|
||||
data = formsemestre.to_dict()
|
||||
# Pour le moment on a besoin de fixer le departement
|
||||
# pour accéder aux préferences
|
||||
dept = Departement.query.get(formsemestre.dept_id)
|
||||
app.set_sco_dept(dept.acronym)
|
||||
data["session_id"] = formsemestre.session_id()
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@ -74,38 +74,8 @@ def formsemestre_apo(etape_apo: str):
|
||||
|
||||
Exemple de résultat :
|
||||
[
|
||||
{
|
||||
"date_fin": "31/08/2022",
|
||||
"resp_can_edit": false,
|
||||
"dept_id": 1,
|
||||
"etat": true,
|
||||
"resp_can_change_ens": true,
|
||||
"id": 1,
|
||||
"modalite": "FI",
|
||||
"ens_can_edit_eval": false,
|
||||
"formation_id": 1,
|
||||
"gestion_compensation": false,
|
||||
"elt_sem_apo": null,
|
||||
"semestre_id": 1,
|
||||
"bul_hide_xml": false,
|
||||
"elt_annee_apo": null,
|
||||
"titre": "Semestre test",
|
||||
"block_moyennes": false,
|
||||
"scodoc7_id": null,
|
||||
"date_debut": "01/09/2021",
|
||||
"gestion_semestrielle": false,
|
||||
"bul_bgcolor": "white",
|
||||
"formsemestre_id": 1,
|
||||
"titre_num": "Semestre test semestre 1",
|
||||
"date_debut_iso": "2021-09-01",
|
||||
"date_fin_iso": "2022-08-31",
|
||||
"responsables": [
|
||||
12,
|
||||
42
|
||||
],
|
||||
"titre_court": "BUT MMI"
|
||||
},
|
||||
...
|
||||
{ ...formsemestre...
|
||||
}, ...
|
||||
]
|
||||
"""
|
||||
formsemestres = FormSemestre.query.filter(
|
||||
@ -113,7 +83,7 @@ def formsemestre_apo(etape_apo: str):
|
||||
FormSemestreEtape.formsemestre_id == FormSemestre.id,
|
||||
)
|
||||
|
||||
return jsonify([formsemestre.to_dict_api() for formsemestre in formsemestres])
|
||||
return jsonify([formsemestre.to_dict() for formsemestre in formsemestres])
|
||||
|
||||
|
||||
@bp.route("/formsemestre/<int:formsemestre_id>/bulletins", methods=["GET"])
|
||||
@ -349,114 +319,96 @@ def bulletins(formsemestre_id: int):
|
||||
# return jsonify(data)
|
||||
|
||||
|
||||
# XXX A spécifier et compléter TODO
|
||||
# @bp.route(
|
||||
# "/formsemestre/<int:formsemestre_id>/programme",
|
||||
# methods=["GET"],
|
||||
# )
|
||||
# @token_auth.login_required
|
||||
# @token_permission_required(Permission.APIView)
|
||||
# def programme(formsemestre_id: int):
|
||||
# """
|
||||
# Retourne la liste des Ues, ressources et SAE d'un semestre
|
||||
#
|
||||
# formsemestre_id : l'id d'un formsemestre
|
||||
#
|
||||
# Exemple de résultat :
|
||||
# {
|
||||
# "ues": [
|
||||
# {
|
||||
# "type": 0,
|
||||
# "formation_id": 1,
|
||||
# "ue_code": "UCOD11",
|
||||
# "id": 1,
|
||||
# "ects": 12.0,
|
||||
# "acronyme": "RT1.1",
|
||||
# "is_external": false,
|
||||
# "numero": 1,
|
||||
# "code_apogee": "",
|
||||
# "titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||
# "coefficient": 0.0,
|
||||
# "semestre_idx": 1,
|
||||
# "color": "#B80004",
|
||||
# "ue_id": 1
|
||||
# },
|
||||
# ...
|
||||
# ],
|
||||
# "ressources": [
|
||||
# {
|
||||
# "titre": "Fondamentaux de la programmation",
|
||||
# "coefficient": 1.0,
|
||||
# "module_type": 2,
|
||||
# "id": 17,
|
||||
# "ects": null,
|
||||
# "abbrev": null,
|
||||
# "ue_id": 3,
|
||||
# "code": "R107",
|
||||
# "formation_id": 1,
|
||||
# "heures_cours": 0.0,
|
||||
# "matiere_id": 3,
|
||||
# "heures_td": 0.0,
|
||||
# "semestre_id": 1,
|
||||
# "heures_tp": 0.0,
|
||||
# "numero": 70,
|
||||
# "code_apogee": "",
|
||||
# "module_id": 17
|
||||
# },
|
||||
# ...
|
||||
# ],
|
||||
# "saes": [
|
||||
# {
|
||||
# "titre": "Se pr\u00e9senter sur Internet",
|
||||
# "coefficient": 1.0,
|
||||
# "module_type": 3,
|
||||
# "id": 14,
|
||||
# "ects": null,
|
||||
# "abbrev": null,
|
||||
# "ue_id": 3,
|
||||
# "code": "SAE14",
|
||||
# "formation_id": 1,
|
||||
# "heures_cours": 0.0,
|
||||
# "matiere_id": 3,
|
||||
# "heures_td": 0.0,
|
||||
# "semestre_id": 1,
|
||||
# "heures_tp": 0.0,
|
||||
# "numero": 40,
|
||||
# "code_apogee": "",
|
||||
# "module_id": 14
|
||||
# },
|
||||
# ...
|
||||
# ]
|
||||
# }
|
||||
# """
|
||||
#
|
||||
# formsemestre: FormSemestre = models.FormSemestre.query.filter_by(
|
||||
# id=formsemestre_id
|
||||
# ).first_or_404()
|
||||
#
|
||||
# ues = formsemestre.query_ues()
|
||||
#
|
||||
# ues_dict = []
|
||||
# ressources = []
|
||||
# saes = []
|
||||
#
|
||||
# for ue in ues:
|
||||
# ues_dict.append(ue.to_dict())
|
||||
# ressources = ue.get_ressources()
|
||||
# saes = ue.get_saes()
|
||||
#
|
||||
# data_ressources = []
|
||||
# for ressource in ressources:
|
||||
# data_ressources.append(ressource.to_dict())
|
||||
#
|
||||
# data_saes = []
|
||||
# for sae in saes:
|
||||
# data_saes.append(sae.to_dict())
|
||||
#
|
||||
# data = {
|
||||
# "ues": ues_dict,
|
||||
# "ressources": data_ressources,
|
||||
# "saes": data_saes,
|
||||
# }
|
||||
#
|
||||
# return data
|
||||
@bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/programme",
|
||||
methods=["GET"],
|
||||
)
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def formsemestre_programme(formsemestre_id: int):
|
||||
"""
|
||||
Retourne la liste des Ues, ressources et SAE d'un semestre
|
||||
|
||||
formsemestre_id : l'id d'un formsemestre
|
||||
|
||||
Exemple de résultat :
|
||||
{
|
||||
"ues": [
|
||||
{
|
||||
"type": 0,
|
||||
"formation_id": 1,
|
||||
"ue_code": "UCOD11",
|
||||
"id": 1,
|
||||
"ects": 12.0,
|
||||
"acronyme": "RT1.1",
|
||||
"is_external": false,
|
||||
"numero": 1,
|
||||
"code_apogee": "",
|
||||
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||
"coefficient": 0.0,
|
||||
"semestre_idx": 1,
|
||||
"color": "#B80004",
|
||||
"ue_id": 1
|
||||
},
|
||||
...
|
||||
],
|
||||
"ressources": [
|
||||
{
|
||||
"ens": [ 10, 18 ],
|
||||
"formsemestre_id": 1,
|
||||
"id": 15,
|
||||
"module": {
|
||||
"abbrev": "Programmer",
|
||||
"code": "SAE15",
|
||||
"code_apogee": "V7GOP",
|
||||
"coefficient": 1.0,
|
||||
"formation_id": 1,
|
||||
"heures_cours": 0.0,
|
||||
"heures_td": 0.0,
|
||||
"heures_tp": 0.0,
|
||||
"id": 15,
|
||||
"matiere_id": 3,
|
||||
"module_id": 15,
|
||||
"module_type": 3,
|
||||
"numero": 50,
|
||||
"semestre_id": 1,
|
||||
"titre": "Programmer en Python",
|
||||
"ue_id": 3
|
||||
},
|
||||
"module_id": 15,
|
||||
"moduleimpl_id": 15,
|
||||
"responsable_id": 2
|
||||
},
|
||||
...
|
||||
],
|
||||
"saes": [
|
||||
{
|
||||
...
|
||||
},
|
||||
...
|
||||
],
|
||||
"modules" : [ ... les modules qui ne sont ni des SAEs ni des ressources ... ]
|
||||
}
|
||||
"""
|
||||
formsemestre: FormSemestre = models.FormSemestre.query.filter_by(
|
||||
id=formsemestre_id
|
||||
).first_or_404()
|
||||
|
||||
ues = formsemestre.query_ues()
|
||||
m_list = {
|
||||
ModuleType.RESSOURCE: [],
|
||||
ModuleType.SAE: [],
|
||||
ModuleType.STANDARD: [],
|
||||
}
|
||||
for modimpl in formsemestre.modimpls_sorted:
|
||||
d = modimpl.to_dict()
|
||||
m_list[modimpl.module.module_type].append(d)
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
"ues": [ue.to_dict() for ue in ues],
|
||||
"ressources": m_list[ModuleType.RESSOURCE],
|
||||
"saes": m_list[ModuleType.SAE],
|
||||
"modules": m_list[ModuleType.STANDARD],
|
||||
}
|
||||
)
|
||||
|
@ -113,11 +113,7 @@ def etud_in_group(group_id: int, etat=None):
|
||||
data = get_group_members(group_id, etat)
|
||||
|
||||
if len(data) == 0:
|
||||
return error_response(
|
||||
409,
|
||||
message="La requête ne peut être traitée en l’état actuel. \n"
|
||||
"Aucun groupe ne correspond au 'group_id' renseigné",
|
||||
)
|
||||
return error_response(404, message="group_id inconnu")
|
||||
|
||||
return jsonify(data)
|
||||
|
||||
@ -146,8 +142,4 @@ def set_groups(
|
||||
setGroups(partition_id, groups_lists, groups_to_create, groups_to_delete)
|
||||
return error_response(200, message="Groups set")
|
||||
except ValueError:
|
||||
return error_response(
|
||||
409,
|
||||
message="La requête ne peut être traitée en l’état actuel. \n"
|
||||
"Veillez vérifier la conformité des éléments passé en paramètres",
|
||||
)
|
||||
return error_response(404, message="Erreur")
|
||||
|
@ -1,15 +1,17 @@
|
||||
from app import models
|
||||
|
||||
|
||||
def get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine):
|
||||
def get_etud_from_etudid_or_nip_or_ine(
|
||||
etudid=None, nip=None, ine=None
|
||||
) -> models.Identite:
|
||||
"""
|
||||
Fonction qui retourne un etudiant en fonction de l'etudid, code nip et code ine rentré en paramètres
|
||||
etudiant en fonction de l'etudid, code nip et code ine rentré en paramètres
|
||||
|
||||
etudid : None ou un int etudid
|
||||
nip : None ou un int code_nip
|
||||
ine : None ou un int code_ine
|
||||
|
||||
Exemple de résultat: <Itendite>
|
||||
Return None si étudiant inexistant.
|
||||
"""
|
||||
if etudid is None:
|
||||
if nip is None: # si ine
|
||||
|
@ -127,6 +127,9 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
||||
|
||||
def ue_rows(self, rows: list, ue_acronym: str, ue: dict, title_bg: tuple):
|
||||
"Décrit une UE dans la table synthèse: titre, sous-titre et liste modules"
|
||||
if (ue["type"] == UE_SPORT) and len(ue.get("modules", [])) == 0:
|
||||
# ne mentionne l'UE que s'il y a des modules
|
||||
return
|
||||
# 1er ligne titre UE
|
||||
moy_ue = ue.get("moyenne")
|
||||
t = {
|
||||
@ -206,7 +209,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
||||
for mod_code, mod in ue["modules"].items():
|
||||
rows.append(
|
||||
{
|
||||
"titre": f"{mod_code} {mod['titre']}",
|
||||
"titre": f"{mod_code or ''} {mod['titre'] or ''}",
|
||||
}
|
||||
)
|
||||
self.evaluations_rows(rows, mod["evaluations"])
|
||||
@ -313,7 +316,7 @@ class BulletinGeneratorStandardBUT(BulletinGeneratorStandard):
|
||||
"lignes des évaluations"
|
||||
for e in evaluations:
|
||||
t = {
|
||||
"titre": f"{e['description']}",
|
||||
"titre": f"{e['description'] or ''}",
|
||||
"moyenne": e["note"]["value"],
|
||||
"_moyenne_pdf": Paragraph(
|
||||
f"""<para align=right>{e["note"]["value"]}</para>"""
|
||||
|
@ -146,6 +146,7 @@ class Identite(db.Model):
|
||||
return {
|
||||
"id": self.id,
|
||||
"nip": self.code_nip,
|
||||
"ine": self.code_ine,
|
||||
"nom": self.nom,
|
||||
"nom_usuel": self.nom_usuel,
|
||||
"prenom": self.prenom,
|
||||
|
@ -178,11 +178,12 @@ def evaluation_enrich_dict(e):
|
||||
else:
|
||||
e["descrheure"] = ""
|
||||
# matin, apresmidi: utile pour se referer aux absences:
|
||||
if heure_debut_dt < datetime.time(12, 00):
|
||||
|
||||
if e["jour"] and heure_debut_dt < datetime.time(12, 00):
|
||||
e["matin"] = 1
|
||||
else:
|
||||
e["matin"] = 0
|
||||
if heure_fin_dt > datetime.time(12, 00):
|
||||
if e["jour"] and heure_fin_dt > datetime.time(12, 00):
|
||||
e["apresmidi"] = 1
|
||||
else:
|
||||
e["apresmidi"] = 0
|
||||
|
@ -139,6 +139,7 @@ class FormSemestre(db.Model):
|
||||
else:
|
||||
d["date_fin"] = d["date_fin_iso"] = ""
|
||||
d["responsables"] = [u.id for u in self.responsables]
|
||||
d["titre_formation"] = self.titre_formation()
|
||||
return d
|
||||
|
||||
def to_dict_api(self):
|
||||
@ -351,9 +352,10 @@ class FormSemestre(db.Model):
|
||||
|
||||
ANNEE=annee universitaire de debut (exemple: un S2 de 2013-2014 sera S2-2013)
|
||||
"""
|
||||
imputation_dept = sco_preferences.get_preference("ImputationDept", self.id)
|
||||
prefs = sco_preferences.SemPreferences(dept_id=self.dept_id)
|
||||
imputation_dept = prefs["ImputationDept"]
|
||||
if not imputation_dept:
|
||||
imputation_dept = sco_preferences.get_preference("DeptName")
|
||||
imputation_dept = prefs["DeptName"]
|
||||
imputation_dept = imputation_dept.upper()
|
||||
parcours_name = self.formation.get_parcours().NAME
|
||||
modalite = self.modalite
|
||||
@ -368,7 +370,7 @@ class FormSemestre(db.Model):
|
||||
scu.annee_scolaire_debut(self.date_debut.year, self.date_debut.month)
|
||||
)
|
||||
return scu.sanitize_string(
|
||||
"-".join((imputation_dept, parcours_name, modalite, semestre_id, annee_sco))
|
||||
f"{imputation_dept}-{parcours_name}-{modalite}-{semestre_id}-{annee_sco}"
|
||||
)
|
||||
|
||||
def titre_annee(self) -> str:
|
||||
@ -380,6 +382,12 @@ class FormSemestre(db.Model):
|
||||
titre_annee += "-" + str(self.date_fin.year)
|
||||
return titre_annee
|
||||
|
||||
def titre_formation(self):
|
||||
"""Titre avec formation, court, pour passerelle: "BUT R&T"
|
||||
(méthode de formsemestre car on pourrait ajouter le semestre, ou d'autres infos, à voir)
|
||||
"""
|
||||
return self.formation.acronyme
|
||||
|
||||
def titre_mois(self) -> str:
|
||||
"""Le titre et les dates du semestre, pour affichage dans des listes
|
||||
Ex: "BUT QLIO (PN 2022) semestre 1 FI (Sept 2022 - Jan 2023)"
|
||||
|
@ -97,7 +97,7 @@ class SetTag(pe_tagtable.TableTag):
|
||||
"""Mémorise les semtag nécessaires au jury."""
|
||||
self.SemTagDict = {fid: SemTagDict[fid] for fid in self.get_Fids_in_settag()}
|
||||
if PE_DEBUG >= 1:
|
||||
pe_print(u" => %d semestres fusionnés" % len(self.SemTagDict))
|
||||
pe_print(" => %d semestres fusionnés" % len(self.SemTagDict))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def comp_data_settag(self):
|
||||
@ -243,7 +243,7 @@ class SetTagInterClasse(pe_tagtable.TableTag):
|
||||
fid: SetTagDict[fid] for fid in self.get_Fids_in_settag() if fid != None
|
||||
}
|
||||
if PE_DEBUG >= 1:
|
||||
pe_print(u" => %d semestres utilisés" % len(self.SetTagDict))
|
||||
pe_print(" => %d semestres utilisés" % len(self.SetTagDict))
|
||||
|
||||
# -------------------------------------------------------------------------------------------------------------------
|
||||
def comp_data_settag(self):
|
||||
|
@ -965,7 +965,7 @@ def _tables_abs_etud(
|
||||
)[0]
|
||||
if format == "html":
|
||||
ex.append(
|
||||
f"""<a href="{url_for('notes.moduleimpl_status',
|
||||
f"""<a title="{mod['module']['titre']}" href="{url_for('notes.moduleimpl_status',
|
||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=mod["moduleimpl_id"])}
|
||||
">{mod["module"]["code"] or "(module sans code)"}</a>"""
|
||||
)
|
||||
|
@ -132,11 +132,14 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
|
||||
if sco_preferences.get_preference(
|
||||
"bul_show_minmax_mod", formsemestre_id
|
||||
):
|
||||
rang_minmax = '%s <span class="bul_minmax" title="[min, max] UE">[%s, %s]</span>' % (
|
||||
rang_minmax = (
|
||||
'%s <span class="bul_minmax" title="[min, max] UE">[%s, %s]</span>'
|
||||
% (
|
||||
mod["mod_rang_txt"],
|
||||
scu.fmt_note(mod["stats"]["min"]),
|
||||
scu.fmt_note(mod["stats"]["max"]),
|
||||
)
|
||||
)
|
||||
else:
|
||||
rang_minmax = mod["mod_rang_txt"] # vide si pas option rang
|
||||
H.append(
|
||||
|
@ -131,8 +131,10 @@ def index_html(showcodes=0, showsemtable=0):
|
||||
if not showsemtable:
|
||||
H.append(
|
||||
f"""<hr>
|
||||
<p><a class="stdlink" href="{url_for('scolar.index_html', scodoc_dept=g.scodoc_dept, showsemtable=1)
|
||||
}">Voir tous les semestres ({len(othersems)} verrouillés)</a>
|
||||
<p><a class="stdlink" href="{url_for('scolar.index_html',
|
||||
scodoc_dept=g.scodoc_dept, showsemtable=1)
|
||||
}">Voir table des semestres (dont {len(othersems)}
|
||||
verrouillé{'s' if len(othersems) else ''})</a>
|
||||
</p>"""
|
||||
)
|
||||
|
||||
|
@ -534,12 +534,15 @@ def formsemestre_inscription_option(etudid, formsemestre_id):
|
||||
ue_status = nt.get_etud_ue_status(etudid, ue_id)
|
||||
if ue_status and ue_status["is_capitalized"]:
|
||||
sem_origin = sco_formsemestre.get_formsemestre(ue_status["formsemestre_id"])
|
||||
ue_descr += ' <a class="discretelink" href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" title="%s">(capitalisée le %s)' % (
|
||||
ue_descr += (
|
||||
' <a class="discretelink" href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" title="%s">(capitalisée le %s)'
|
||||
% (
|
||||
sem_origin["formsemestre_id"],
|
||||
etudid,
|
||||
sem_origin["titreannee"],
|
||||
ndb.DateISOtoDMY(ue_status["event_date"]),
|
||||
)
|
||||
)
|
||||
descr.append(
|
||||
(
|
||||
"sec_%s" % ue_id,
|
||||
|
@ -303,10 +303,13 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
|
||||
)
|
||||
for mod in options:
|
||||
if can_change:
|
||||
c_link = '<a class="discretelink" href="moduleimpl_inscriptions_edit?moduleimpl_id=%s">%s</a>' % (
|
||||
c_link = (
|
||||
'<a class="discretelink" href="moduleimpl_inscriptions_edit?moduleimpl_id=%s">%s</a>'
|
||||
% (
|
||||
mod["moduleimpl_id"],
|
||||
mod["descri"] or "<i>(inscrire des étudiants)</i>",
|
||||
)
|
||||
)
|
||||
else:
|
||||
c_link = mod["descri"]
|
||||
H.append(
|
||||
|
@ -296,9 +296,9 @@ def ficheEtud(etudid=None):
|
||||
if not sco_permissions_check.can_suppress_annotation(a["id"]):
|
||||
a["dellink"] = ""
|
||||
else:
|
||||
a[
|
||||
"dellink"
|
||||
] = '<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>' % (
|
||||
a["dellink"] = (
|
||||
'<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>'
|
||||
% (
|
||||
etudid,
|
||||
a["id"],
|
||||
scu.icontag(
|
||||
@ -308,6 +308,7 @@ def ficheEtud(etudid=None):
|
||||
title="Supprimer cette annotation",
|
||||
),
|
||||
)
|
||||
)
|
||||
author = sco_users.user_info(a["author"])
|
||||
alist.append(
|
||||
f"""<tr><td><span class="annodate">Le {a['date']} par {author['prenomnom']} :
|
||||
|
@ -132,8 +132,11 @@ def clear_base_preferences():
|
||||
g._SCO_BASE_PREFERENCES = {} # { dept_id: BasePreferences instance }
|
||||
|
||||
|
||||
def get_base_preferences():
|
||||
"""Return global preferences for the current department"""
|
||||
def get_base_preferences(dept_id: int = None):
|
||||
"""Return global preferences for the specified department
|
||||
or the current departement
|
||||
"""
|
||||
if dept_id is None:
|
||||
dept_id = g.scodoc_dept_id
|
||||
if not hasattr(g, "_SCO_BASE_PREFERENCES"):
|
||||
g._SCO_BASE_PREFERENCES = {}
|
||||
@ -142,12 +145,12 @@ def get_base_preferences():
|
||||
return g._SCO_BASE_PREFERENCES[dept_id]
|
||||
|
||||
|
||||
def get_preference(name, formsemestre_id=None):
|
||||
def get_preference(name, formsemestre_id=None, dept_id=None):
|
||||
"""Returns value of named preference.
|
||||
All preferences have a sensible default value, so this
|
||||
function always returns a usable value for all defined preferences names.
|
||||
"""
|
||||
return get_base_preferences().get(formsemestre_id, name)
|
||||
return get_base_preferences(dept_id=dept_id).get(formsemestre_id, name)
|
||||
|
||||
|
||||
def _convert_pref_type(p, pref_spec):
|
||||
@ -2145,9 +2148,9 @@ class BasePreferences(object):
|
||||
class SemPreferences:
|
||||
"""Preferences for a formsemestre"""
|
||||
|
||||
def __init__(self, formsemestre_id=None):
|
||||
def __init__(self, formsemestre_id=None, dept_id=None):
|
||||
self.formsemestre_id = formsemestre_id
|
||||
self.base_prefs = get_base_preferences()
|
||||
self.base_prefs = get_base_preferences(dept_id=dept_id)
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self.base_prefs.get(self.formsemestre_id, name)
|
||||
|
@ -799,22 +799,22 @@ def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
evals = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||
if not evals:
|
||||
raise ScoValueError("invalid evaluation_id")
|
||||
E = evals[0]
|
||||
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
||||
eval_dict = evals[0]
|
||||
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=eval_dict["moduleimpl_id"])[0]
|
||||
formsemestre_id = M["formsemestre_id"]
|
||||
Mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0]
|
||||
sem = sco_formsemestre.get_formsemestre(M["formsemestre_id"])
|
||||
mod_responsable = sco_users.user_info(M["responsable_id"])
|
||||
if E["jour"]:
|
||||
indication_date = ndb.DateDMYtoISO(E["jour"])
|
||||
if eval_dict["jour"]:
|
||||
indication_date = ndb.DateDMYtoISO(eval_dict["jour"])
|
||||
else:
|
||||
indication_date = scu.sanitize_filename(E["description"])[:12]
|
||||
evalname = "%s-%s" % (Mod["code"], indication_date)
|
||||
indication_date = scu.sanitize_filename(eval_dict["description"])[:12]
|
||||
eval_name = "%s-%s" % (Mod["code"], indication_date)
|
||||
|
||||
if E["description"]:
|
||||
evaltitre = "%s du %s" % (E["description"], E["jour"])
|
||||
if eval_dict["description"]:
|
||||
evaltitre = "%s du %s" % (eval_dict["description"], eval_dict["jour"])
|
||||
else:
|
||||
evaltitre = "évaluation du %s" % E["jour"]
|
||||
evaltitre = "évaluation du %s" % eval_dict["jour"]
|
||||
description = "%s en %s (%s) resp. %s" % (
|
||||
evaltitre,
|
||||
Mod["abbrev"] or "",
|
||||
@ -847,7 +847,7 @@ def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
# une liste de liste de chaines: lignes de la feuille de calcul
|
||||
L = []
|
||||
|
||||
etuds = _get_sorted_etuds(E, etudids, formsemestre_id)
|
||||
etuds = _get_sorted_etuds(eval_dict, etudids, formsemestre_id)
|
||||
for e in etuds:
|
||||
etudid = e["etudid"]
|
||||
groups = sco_groups.get_etud_groups(etudid, formsemestre_id)
|
||||
@ -865,8 +865,10 @@ def feuille_saisie_notes(evaluation_id, group_ids=[]):
|
||||
]
|
||||
)
|
||||
|
||||
filename = "notes_%s_%s" % (evalname, gr_title_filename)
|
||||
xls = sco_excel.excel_feuille_saisie(E, sem["titreannee"], description, lines=L)
|
||||
filename = "notes_%s_%s" % (eval_name, gr_title_filename)
|
||||
xls = sco_excel.excel_feuille_saisie(
|
||||
eval_dict, sem["titreannee"], description, lines=L
|
||||
)
|
||||
return scu.send_file(xls, filename, scu.XLSX_SUFFIX, mime=scu.XLSX_MIMETYPE)
|
||||
# return sco_excel.send_excel_file(xls, filename)
|
||||
|
||||
@ -1008,10 +1010,9 @@ def saisie_notes(evaluation_id, group_ids=[]):
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def _get_sorted_etuds(E, etudids, formsemestre_id):
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
def _get_sorted_etuds(eval_dict: dict, etudids: list, formsemestre_id: int):
|
||||
notes_db = sco_evaluation_db.do_evaluation_get_all_notes(
|
||||
E["evaluation_id"]
|
||||
eval_dict["evaluation_id"]
|
||||
) # Notes existantes
|
||||
cnx = ndb.GetDBConnexion()
|
||||
etuds = []
|
||||
@ -1028,9 +1029,9 @@ def _get_sorted_etuds(E, etudids, formsemestre_id):
|
||||
e["groups"] = sco_groups.get_etud_groups(etudid, formsemestre_id)
|
||||
|
||||
# Information sur absence (tenant compte de la demi-journée)
|
||||
jour_iso = ndb.DateDMYtoISO(E["jour"])
|
||||
jour_iso = ndb.DateDMYtoISO(eval_dict["jour"])
|
||||
warn_abs_lst = []
|
||||
if E["matin"]:
|
||||
if eval_dict["matin"]:
|
||||
nbabs = sco_abs.count_abs(etudid, jour_iso, jour_iso, matin=1)
|
||||
nbabsjust = sco_abs.count_abs_just(etudid, jour_iso, jour_iso, matin=1)
|
||||
if nbabs:
|
||||
@ -1038,7 +1039,7 @@ def _get_sorted_etuds(E, etudids, formsemestre_id):
|
||||
warn_abs_lst.append("absent justifié le matin !")
|
||||
else:
|
||||
warn_abs_lst.append("absent le matin !")
|
||||
if E["apresmidi"]:
|
||||
if eval_dict["apresmidi"]:
|
||||
nbabs = sco_abs.count_abs(etudid, jour_iso, jour_iso, matin=0)
|
||||
nbabsjust = sco_abs.count_abs_just(etudid, jour_iso, jour_iso, matin=0)
|
||||
if nbabs:
|
||||
|
@ -14,17 +14,17 @@ config = context.config
|
||||
# Interpret the config file for Python logging.
|
||||
# This line sets up loggers basically.
|
||||
fileConfig(config.config_file_name)
|
||||
logger = logging.getLogger('alembic.env')
|
||||
logger = logging.getLogger("alembic.env")
|
||||
|
||||
# add your model's MetaData object here
|
||||
# for 'autogenerate' support
|
||||
# from myapp import mymodel
|
||||
# target_metadata = mymodel.Base.metadata
|
||||
config.set_main_option(
|
||||
'sqlalchemy.url',
|
||||
str(current_app.extensions['migrate'].db.get_engine().url).replace(
|
||||
'%', '%%'))
|
||||
target_metadata = current_app.extensions['migrate'].db.metadata
|
||||
"sqlalchemy.url",
|
||||
str(current_app.extensions["migrate"].db.get_engine().url).replace("%", "%%"),
|
||||
)
|
||||
target_metadata = current_app.extensions["migrate"].db.metadata
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
# can be acquired:
|
||||
@ -45,9 +45,7 @@ def run_migrations_offline():
|
||||
|
||||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
context.configure(
|
||||
url=url, target_metadata=target_metadata, literal_binds=True
|
||||
)
|
||||
context.configure(url=url, target_metadata=target_metadata, literal_binds=True)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
@ -65,20 +63,20 @@ def run_migrations_online():
|
||||
# when there are no changes to the schema
|
||||
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
|
||||
def process_revision_directives(context, revision, directives):
|
||||
if getattr(config.cmd_opts, 'autogenerate', False):
|
||||
if getattr(config.cmd_opts, "autogenerate", False):
|
||||
script = directives[0]
|
||||
if script.upgrade_ops.is_empty():
|
||||
directives[:] = []
|
||||
logger.info('No changes in schema detected.')
|
||||
logger.info("No changes in schema detected.")
|
||||
|
||||
connectable = current_app.extensions['migrate'].db.get_engine()
|
||||
connectable = current_app.extensions["migrate"].db.get_engine()
|
||||
|
||||
with connectable.connect() as connection:
|
||||
context.configure(
|
||||
connection=connection,
|
||||
target_metadata=target_metadata,
|
||||
process_revision_directives=process_revision_directives,
|
||||
**current_app.extensions['migrate'].configure_args
|
||||
**current_app.extensions["migrate"].configure_args
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
|
@ -10,21 +10,23 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '017e32eb4773'
|
||||
down_revision = '6b071b7947e5'
|
||||
revision = "017e32eb4773"
|
||||
down_revision = "6b071b7947e5"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('identite', sa.Column('scodoc7_id', sa.Text(), nullable=True))
|
||||
op.add_column('notes_formsemestre', sa.Column('scodoc7_id', sa.Text(), nullable=True))
|
||||
op.add_column("identite", sa.Column("scodoc7_id", sa.Text(), nullable=True))
|
||||
op.add_column(
|
||||
"notes_formsemestre", sa.Column("scodoc7_id", sa.Text(), nullable=True)
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('notes_formsemestre', 'scodoc7_id')
|
||||
op.drop_column('identite', 'scodoc7_id')
|
||||
op.drop_column("notes_formsemestre", "scodoc7_id")
|
||||
op.drop_column("identite", "scodoc7_id")
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,21 +10,38 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '1efe07413835'
|
||||
down_revision = '75cf18659984'
|
||||
revision = "1efe07413835"
|
||||
down_revision = "75cf18659984"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint('absences_notifications_formsemestre_id_fkey', 'absences_notifications', type_='foreignkey')
|
||||
op.create_foreign_key(None, 'absences_notifications', 'notes_formsemestre', ['formsemestre_id'], ['id'], ondelete='CASCADE')
|
||||
op.drop_constraint(
|
||||
"absences_notifications_formsemestre_id_fkey",
|
||||
"absences_notifications",
|
||||
type_="foreignkey",
|
||||
)
|
||||
op.create_foreign_key(
|
||||
None,
|
||||
"absences_notifications",
|
||||
"notes_formsemestre",
|
||||
["formsemestre_id"],
|
||||
["id"],
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'absences_notifications', type_='foreignkey')
|
||||
op.create_foreign_key('absences_notifications_formsemestre_id_fkey', 'absences_notifications', 'notes_formsemestre', ['formsemestre_id'], ['id'])
|
||||
op.drop_constraint(None, "absences_notifications", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
"absences_notifications_formsemestre_id_fkey",
|
||||
"absences_notifications",
|
||||
"notes_formsemestre",
|
||||
["formsemestre_id"],
|
||||
["id"],
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,25 +10,57 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '39818df276aa'
|
||||
down_revision = '1efe07413835'
|
||||
revision = "39818df276aa"
|
||||
down_revision = "1efe07413835"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint('itemsuivi_tags_assoc_tag_id_fkey', 'itemsuivi_tags_assoc', type_='foreignkey')
|
||||
op.drop_constraint('itemsuivi_tags_assoc_itemsuivi_id_fkey', 'itemsuivi_tags_assoc', type_='foreignkey')
|
||||
op.create_foreign_key(None, 'itemsuivi_tags_assoc', 'itemsuivi', ['itemsuivi_id'], ['id'], ondelete='CASCADE')
|
||||
op.create_foreign_key(None, 'itemsuivi_tags_assoc', 'itemsuivi_tags', ['tag_id'], ['id'], ondelete='CASCADE')
|
||||
op.drop_constraint(
|
||||
"itemsuivi_tags_assoc_tag_id_fkey", "itemsuivi_tags_assoc", type_="foreignkey"
|
||||
)
|
||||
op.drop_constraint(
|
||||
"itemsuivi_tags_assoc_itemsuivi_id_fkey",
|
||||
"itemsuivi_tags_assoc",
|
||||
type_="foreignkey",
|
||||
)
|
||||
op.create_foreign_key(
|
||||
None,
|
||||
"itemsuivi_tags_assoc",
|
||||
"itemsuivi",
|
||||
["itemsuivi_id"],
|
||||
["id"],
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
op.create_foreign_key(
|
||||
None,
|
||||
"itemsuivi_tags_assoc",
|
||||
"itemsuivi_tags",
|
||||
["tag_id"],
|
||||
["id"],
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'itemsuivi_tags_assoc', type_='foreignkey')
|
||||
op.drop_constraint(None, 'itemsuivi_tags_assoc', type_='foreignkey')
|
||||
op.create_foreign_key('itemsuivi_tags_assoc_itemsuivi_id_fkey', 'itemsuivi_tags_assoc', 'itemsuivi', ['itemsuivi_id'], ['id'])
|
||||
op.create_foreign_key('itemsuivi_tags_assoc_tag_id_fkey', 'itemsuivi_tags_assoc', 'itemsuivi_tags', ['tag_id'], ['id'])
|
||||
op.drop_constraint(None, "itemsuivi_tags_assoc", type_="foreignkey")
|
||||
op.drop_constraint(None, "itemsuivi_tags_assoc", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
"itemsuivi_tags_assoc_itemsuivi_id_fkey",
|
||||
"itemsuivi_tags_assoc",
|
||||
"itemsuivi",
|
||||
["itemsuivi_id"],
|
||||
["id"],
|
||||
)
|
||||
op.create_foreign_key(
|
||||
"itemsuivi_tags_assoc_tag_id_fkey",
|
||||
"itemsuivi_tags_assoc",
|
||||
"itemsuivi_tags",
|
||||
["tag_id"],
|
||||
["id"],
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,19 +10,24 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '669065fb2d20'
|
||||
down_revision = 'a217bf588f4c'
|
||||
revision = "669065fb2d20"
|
||||
down_revision = "a217bf588f4c"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('notes_formsemestre', sa.Column('block_moyennes', sa.Boolean(), server_default='false', nullable=False))
|
||||
op.add_column(
|
||||
"notes_formsemestre",
|
||||
sa.Column(
|
||||
"block_moyennes", sa.Boolean(), server_default="false", nullable=False
|
||||
),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('notes_formsemestre', 'block_moyennes')
|
||||
op.drop_column("notes_formsemestre", "block_moyennes")
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,25 +10,31 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '6b071b7947e5'
|
||||
down_revision = '993ce4a01d57'
|
||||
revision = "6b071b7947e5"
|
||||
down_revision = "993ce4a01d57"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.alter_column('notes_modules', 'code',
|
||||
op.alter_column(
|
||||
"notes_modules",
|
||||
"code",
|
||||
existing_type=sa.VARCHAR(length=32),
|
||||
type_=sa.Text(),
|
||||
existing_nullable=False)
|
||||
existing_nullable=False,
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.alter_column('notes_modules', 'code',
|
||||
op.alter_column(
|
||||
"notes_modules",
|
||||
"code",
|
||||
existing_type=sa.Text(),
|
||||
type_=sa.VARCHAR(length=32),
|
||||
existing_nullable=False)
|
||||
existing_nullable=False,
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,26 +10,33 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '6cfc21a7ae1b'
|
||||
down_revision = 'ada0d1f3d84f'
|
||||
revision = "6cfc21a7ae1b"
|
||||
down_revision = "ada0d1f3d84f"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('module_ue_coef',
|
||||
sa.Column('module_id', sa.Integer(), nullable=False),
|
||||
sa.Column('ue_id', sa.Integer(), nullable=False),
|
||||
sa.Column('coef', sa.Float(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['module_id'], ['notes_modules.id'], ),
|
||||
sa.ForeignKeyConstraint(['ue_id'], ['notes_ue.id'], ),
|
||||
sa.PrimaryKeyConstraint('module_id', 'ue_id')
|
||||
op.create_table(
|
||||
"module_ue_coef",
|
||||
sa.Column("module_id", sa.Integer(), nullable=False),
|
||||
sa.Column("ue_id", sa.Integer(), nullable=False),
|
||||
sa.Column("coef", sa.Float(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["module_id"],
|
||||
["notes_modules.id"],
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["ue_id"],
|
||||
["notes_ue.id"],
|
||||
),
|
||||
sa.PrimaryKeyConstraint("module_id", "ue_id"),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('module_ue_coef')
|
||||
op.drop_table("module_ue_coef")
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,25 +10,50 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '75cf18659984'
|
||||
down_revision = 'd74b4e16fb3c'
|
||||
revision = "75cf18659984"
|
||||
down_revision = "d74b4e16fb3c"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint('notes_modules_tags_tag_id_fkey', 'notes_modules_tags', type_='foreignkey')
|
||||
op.drop_constraint('notes_modules_tags_module_id_fkey', 'notes_modules_tags', type_='foreignkey')
|
||||
op.create_foreign_key(None, 'notes_modules_tags', 'notes_tags', ['tag_id'], ['id'], ondelete='CASCADE')
|
||||
op.create_foreign_key(None, 'notes_modules_tags', 'notes_modules', ['module_id'], ['id'], ondelete='CASCADE')
|
||||
op.drop_constraint(
|
||||
"notes_modules_tags_tag_id_fkey", "notes_modules_tags", type_="foreignkey"
|
||||
)
|
||||
op.drop_constraint(
|
||||
"notes_modules_tags_module_id_fkey", "notes_modules_tags", type_="foreignkey"
|
||||
)
|
||||
op.create_foreign_key(
|
||||
None, "notes_modules_tags", "notes_tags", ["tag_id"], ["id"], ondelete="CASCADE"
|
||||
)
|
||||
op.create_foreign_key(
|
||||
None,
|
||||
"notes_modules_tags",
|
||||
"notes_modules",
|
||||
["module_id"],
|
||||
["id"],
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'notes_modules_tags', type_='foreignkey')
|
||||
op.drop_constraint(None, 'notes_modules_tags', type_='foreignkey')
|
||||
op.create_foreign_key('notes_modules_tags_module_id_fkey', 'notes_modules_tags', 'notes_modules', ['module_id'], ['id'])
|
||||
op.create_foreign_key('notes_modules_tags_tag_id_fkey', 'notes_modules_tags', 'notes_tags', ['tag_id'], ['id'])
|
||||
op.drop_constraint(None, "notes_modules_tags", type_="foreignkey")
|
||||
op.drop_constraint(None, "notes_modules_tags", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
"notes_modules_tags_module_id_fkey",
|
||||
"notes_modules_tags",
|
||||
"notes_modules",
|
||||
["module_id"],
|
||||
["id"],
|
||||
)
|
||||
op.create_foreign_key(
|
||||
"notes_modules_tags_tag_id_fkey",
|
||||
"notes_modules_tags",
|
||||
"notes_tags",
|
||||
["tag_id"],
|
||||
["id"],
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,46 +10,77 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '92789d50f6b6'
|
||||
down_revision = '00ad500fb118'
|
||||
revision = "92789d50f6b6"
|
||||
down_revision = "00ad500fb118"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('modules_acs')
|
||||
op.drop_table('app_crit')
|
||||
op.add_column('apc_annee_parcours', sa.Column('ordre', sa.Integer(), nullable=True))
|
||||
op.drop_column('apc_annee_parcours', 'numero')
|
||||
op.create_index(op.f('ix_apc_app_critique_code'), 'apc_app_critique', ['code'], unique=False)
|
||||
op.create_unique_constraint('apc_competence_referentiel_id_titre_key', 'apc_competence', ['referentiel_id', 'titre'])
|
||||
op.create_index(op.f('ix_apc_competence_titre'), 'apc_competence', ['titre'], unique=False)
|
||||
op.add_column('apc_referentiel_competences', sa.Column('scodoc_date_loaded', sa.DateTime(), nullable=True))
|
||||
op.add_column('apc_referentiel_competences', sa.Column('scodoc_orig_filename', sa.Text(), nullable=True))
|
||||
op.drop_table("modules_acs")
|
||||
op.drop_table("app_crit")
|
||||
op.add_column("apc_annee_parcours", sa.Column("ordre", sa.Integer(), nullable=True))
|
||||
op.drop_column("apc_annee_parcours", "numero")
|
||||
op.create_index(
|
||||
op.f("ix_apc_app_critique_code"), "apc_app_critique", ["code"], unique=False
|
||||
)
|
||||
op.create_unique_constraint(
|
||||
"apc_competence_referentiel_id_titre_key",
|
||||
"apc_competence",
|
||||
["referentiel_id", "titre"],
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_apc_competence_titre"), "apc_competence", ["titre"], unique=False
|
||||
)
|
||||
op.add_column(
|
||||
"apc_referentiel_competences",
|
||||
sa.Column("scodoc_date_loaded", sa.DateTime(), nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"apc_referentiel_competences",
|
||||
sa.Column("scodoc_orig_filename", sa.Text(), nullable=True),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('apc_referentiel_competences', 'scodoc_orig_filename')
|
||||
op.drop_column('apc_referentiel_competences', 'scodoc_date_loaded')
|
||||
op.drop_index(op.f('ix_apc_competence_titre'), table_name='apc_competence')
|
||||
op.drop_constraint('apc_competence_referentiel_id_titre_key', 'apc_competence', type_='unique')
|
||||
op.drop_index(op.f('ix_apc_app_critique_code'), table_name='apc_app_critique')
|
||||
op.add_column('apc_annee_parcours', sa.Column('numero', sa.INTEGER(), autoincrement=False, nullable=True))
|
||||
op.drop_column('apc_annee_parcours', 'ordre')
|
||||
op.create_table('app_crit',
|
||||
sa.Column('id', sa.INTEGER(), server_default=sa.text("nextval('app_crit_id_seq'::regclass)"), autoincrement=True, nullable=False),
|
||||
sa.Column('code', sa.TEXT(), autoincrement=False, nullable=False),
|
||||
sa.Column('titre', sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.PrimaryKeyConstraint('id', name='app_crit_pkey'),
|
||||
postgresql_ignore_search_path=False
|
||||
op.drop_column("apc_referentiel_competences", "scodoc_orig_filename")
|
||||
op.drop_column("apc_referentiel_competences", "scodoc_date_loaded")
|
||||
op.drop_index(op.f("ix_apc_competence_titre"), table_name="apc_competence")
|
||||
op.drop_constraint(
|
||||
"apc_competence_referentiel_id_titre_key", "apc_competence", type_="unique"
|
||||
)
|
||||
op.create_table('modules_acs',
|
||||
sa.Column('module_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('ac_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.ForeignKeyConstraint(['ac_id'], ['app_crit.id'], name='modules_acs_ac_id_fkey'),
|
||||
sa.ForeignKeyConstraint(['module_id'], ['notes_modules.id'], name='modules_acs_module_id_fkey')
|
||||
op.drop_index(op.f("ix_apc_app_critique_code"), table_name="apc_app_critique")
|
||||
op.add_column(
|
||||
"apc_annee_parcours",
|
||||
sa.Column("numero", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
)
|
||||
op.drop_column("apc_annee_parcours", "ordre")
|
||||
op.create_table(
|
||||
"app_crit",
|
||||
sa.Column(
|
||||
"id",
|
||||
sa.INTEGER(),
|
||||
server_default=sa.text("nextval('app_crit_id_seq'::regclass)"),
|
||||
autoincrement=True,
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("code", sa.TEXT(), autoincrement=False, nullable=False),
|
||||
sa.Column("titre", sa.TEXT(), autoincrement=False, nullable=True),
|
||||
sa.PrimaryKeyConstraint("id", name="app_crit_pkey"),
|
||||
postgresql_ignore_search_path=False,
|
||||
)
|
||||
op.create_table(
|
||||
"modules_acs",
|
||||
sa.Column("module_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column("ac_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.ForeignKeyConstraint(
|
||||
["ac_id"], ["app_crit.id"], name="modules_acs_ac_id_fkey"
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["module_id"], ["notes_modules.id"], name="modules_acs_module_id_fkey"
|
||||
),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,27 +10,50 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'a217bf588f4c'
|
||||
down_revision = 'f73251d1d825'
|
||||
revision = "a217bf588f4c"
|
||||
down_revision = "f73251d1d825"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.alter_column('notes_semset_formsemestre', 'semset_id',
|
||||
op.alter_column(
|
||||
"notes_semset_formsemestre",
|
||||
"semset_id",
|
||||
existing_type=sa.INTEGER(),
|
||||
nullable=False)
|
||||
op.drop_constraint('notes_semset_formsemestre_semset_id_fkey', 'notes_semset_formsemestre', type_='foreignkey')
|
||||
op.create_foreign_key(None, 'notes_semset_formsemestre', 'notes_semset', ['semset_id'], ['id'], ondelete='CASCADE')
|
||||
nullable=False,
|
||||
)
|
||||
op.drop_constraint(
|
||||
"notes_semset_formsemestre_semset_id_fkey",
|
||||
"notes_semset_formsemestre",
|
||||
type_="foreignkey",
|
||||
)
|
||||
op.create_foreign_key(
|
||||
None,
|
||||
"notes_semset_formsemestre",
|
||||
"notes_semset",
|
||||
["semset_id"],
|
||||
["id"],
|
||||
ondelete="CASCADE",
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'notes_semset_formsemestre', type_='foreignkey')
|
||||
op.create_foreign_key('notes_semset_formsemestre_semset_id_fkey', 'notes_semset_formsemestre', 'notes_semset', ['semset_id'], ['id'])
|
||||
op.alter_column('notes_semset_formsemestre', 'semset_id',
|
||||
op.drop_constraint(None, "notes_semset_formsemestre", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
"notes_semset_formsemestre_semset_id_fkey",
|
||||
"notes_semset_formsemestre",
|
||||
"notes_semset",
|
||||
["semset_id"],
|
||||
["id"],
|
||||
)
|
||||
op.alter_column(
|
||||
"notes_semset_formsemestre",
|
||||
"semset_id",
|
||||
existing_type=sa.INTEGER(),
|
||||
nullable=True)
|
||||
nullable=True,
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,21 +10,23 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'c8efc54586d8'
|
||||
down_revision = '6cfc21a7ae1b'
|
||||
revision = "c8efc54586d8"
|
||||
down_revision = "6cfc21a7ae1b"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('notes_ue', sa.Column('semestre_idx', sa.Integer(), nullable=True))
|
||||
op.create_index(op.f('ix_notes_ue_semestre_idx'), 'notes_ue', ['semestre_idx'], unique=False)
|
||||
op.add_column("notes_ue", sa.Column("semestre_idx", sa.Integer(), nullable=True))
|
||||
op.create_index(
|
||||
op.f("ix_notes_ue_semestre_idx"), "notes_ue", ["semestre_idx"], unique=False
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_notes_ue_semestre_idx'), table_name='notes_ue')
|
||||
op.drop_column('notes_ue', 'semestre_idx')
|
||||
op.drop_index(op.f("ix_notes_ue_semestre_idx"), table_name="notes_ue")
|
||||
op.drop_column("notes_ue", "semestre_idx")
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,23 +10,25 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'd3d92b2d0092'
|
||||
down_revision = '017e32eb4773'
|
||||
revision = "d3d92b2d0092"
|
||||
down_revision = "017e32eb4773"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('itemsuivi_tags', sa.Column('dept_id', sa.Integer(), nullable=True))
|
||||
op.create_index(op.f('ix_itemsuivi_tags_dept_id'), 'itemsuivi_tags', ['dept_id'], unique=False)
|
||||
op.create_foreign_key(None, 'itemsuivi_tags', 'departement', ['dept_id'], ['id'])
|
||||
op.add_column("itemsuivi_tags", sa.Column("dept_id", sa.Integer(), nullable=True))
|
||||
op.create_index(
|
||||
op.f("ix_itemsuivi_tags_dept_id"), "itemsuivi_tags", ["dept_id"], unique=False
|
||||
)
|
||||
op.create_foreign_key(None, "itemsuivi_tags", "departement", ["dept_id"], ["id"])
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'itemsuivi_tags', type_='foreignkey')
|
||||
op.drop_index(op.f('ix_itemsuivi_tags_dept_id'), table_name='itemsuivi_tags')
|
||||
op.drop_column('itemsuivi_tags', 'dept_id')
|
||||
op.drop_constraint(None, "itemsuivi_tags", type_="foreignkey")
|
||||
op.drop_index(op.f("ix_itemsuivi_tags_dept_id"), table_name="itemsuivi_tags")
|
||||
op.drop_column("itemsuivi_tags", "dept_id")
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,49 +10,73 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'f6e7d2e01be1'
|
||||
down_revision = 'd3d92b2d0092'
|
||||
revision = "f6e7d2e01be1"
|
||||
down_revision = "d3d92b2d0092"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.alter_column('notes_formsemestre_etapes', 'etape_apo',
|
||||
op.alter_column(
|
||||
"notes_formsemestre_etapes",
|
||||
"etape_apo",
|
||||
existing_type=sa.VARCHAR(length=16),
|
||||
type_=sa.String(length=24),
|
||||
existing_nullable=True)
|
||||
op.alter_column('notes_formsemestre_inscription', 'etape',
|
||||
existing_nullable=True,
|
||||
)
|
||||
op.alter_column(
|
||||
"notes_formsemestre_inscription",
|
||||
"etape",
|
||||
existing_type=sa.VARCHAR(length=16),
|
||||
type_=sa.String(length=24),
|
||||
existing_nullable=True)
|
||||
op.alter_column('notes_modules', 'code_apogee',
|
||||
existing_nullable=True,
|
||||
)
|
||||
op.alter_column(
|
||||
"notes_modules",
|
||||
"code_apogee",
|
||||
existing_type=sa.VARCHAR(length=16),
|
||||
type_=sa.String(length=24),
|
||||
existing_nullable=True)
|
||||
op.alter_column('notes_ue', 'code_apogee',
|
||||
existing_nullable=True,
|
||||
)
|
||||
op.alter_column(
|
||||
"notes_ue",
|
||||
"code_apogee",
|
||||
existing_type=sa.VARCHAR(length=16),
|
||||
type_=sa.String(length=24),
|
||||
existing_nullable=True)
|
||||
existing_nullable=True,
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.alter_column('notes_ue', 'code_apogee',
|
||||
op.alter_column(
|
||||
"notes_ue",
|
||||
"code_apogee",
|
||||
existing_type=sa.String(length=24),
|
||||
type_=sa.VARCHAR(length=16),
|
||||
existing_nullable=True)
|
||||
op.alter_column('notes_modules', 'code_apogee',
|
||||
existing_nullable=True,
|
||||
)
|
||||
op.alter_column(
|
||||
"notes_modules",
|
||||
"code_apogee",
|
||||
existing_type=sa.String(length=24),
|
||||
type_=sa.VARCHAR(length=16),
|
||||
existing_nullable=True)
|
||||
op.alter_column('notes_formsemestre_inscription', 'etape',
|
||||
existing_nullable=True,
|
||||
)
|
||||
op.alter_column(
|
||||
"notes_formsemestre_inscription",
|
||||
"etape",
|
||||
existing_type=sa.String(length=24),
|
||||
type_=sa.VARCHAR(length=16),
|
||||
existing_nullable=True)
|
||||
op.alter_column('notes_formsemestre_etapes', 'etape_apo',
|
||||
existing_nullable=True,
|
||||
)
|
||||
op.alter_column(
|
||||
"notes_formsemestre_etapes",
|
||||
"etape_apo",
|
||||
existing_type=sa.String(length=24),
|
||||
type_=sa.VARCHAR(length=16),
|
||||
existing_nullable=True)
|
||||
existing_nullable=True,
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,26 +10,29 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'f73251d1d825'
|
||||
down_revision = 'f6e7d2e01be1'
|
||||
revision = "f73251d1d825"
|
||||
down_revision = "f6e7d2e01be1"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('scodoc_site_config',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=128), nullable=False),
|
||||
sa.Column('value', sa.Text(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
op.create_table(
|
||||
"scodoc_site_config",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("name", sa.String(length=128), nullable=False),
|
||||
sa.Column("value", sa.Text(), nullable=True),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.create_index(
|
||||
op.f("ix_scodoc_site_config_name"), "scodoc_site_config", ["name"], unique=False
|
||||
)
|
||||
op.create_index(op.f('ix_scodoc_site_config_name'), 'scodoc_site_config', ['name'], unique=False)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_scodoc_site_config_name'), table_name='scodoc_site_config')
|
||||
op.drop_table('scodoc_site_config')
|
||||
op.drop_index(op.f("ix_scodoc_site_config_name"), table_name="scodoc_site_config")
|
||||
op.drop_table("scodoc_site_config")
|
||||
# ### end Alembic commands ###
|
||||
|
@ -10,21 +10,31 @@ import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'f86c013c9fbd'
|
||||
down_revision = '669065fb2d20'
|
||||
revision = "f86c013c9fbd"
|
||||
down_revision = "669065fb2d20"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint('notes_formations_acronyme_titre_version_key', 'notes_formations', type_='unique')
|
||||
op.create_unique_constraint(None, 'notes_formations', ['dept_id', 'acronyme', 'titre', 'version'])
|
||||
op.drop_constraint(
|
||||
"notes_formations_acronyme_titre_version_key",
|
||||
"notes_formations",
|
||||
type_="unique",
|
||||
)
|
||||
op.create_unique_constraint(
|
||||
None, "notes_formations", ["dept_id", "acronyme", "titre", "version"]
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'notes_formations', type_='unique')
|
||||
op.create_unique_constraint('notes_formations_acronyme_titre_version_key', 'notes_formations', ['acronyme', 'titre', 'version'])
|
||||
op.drop_constraint(None, "notes_formations", type_="unique")
|
||||
op.create_unique_constraint(
|
||||
"notes_formations_acronyme_titre_version_key",
|
||||
"notes_formations",
|
||||
["acronyme", "titre", "version"],
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
@ -7,64 +7,83 @@ Source: http://wikipython.flibuste.net/moin.py/JouerAvecUnicode#head-1213938516c
|
||||
"""
|
||||
|
||||
_reptable = {}
|
||||
|
||||
|
||||
def _fill_reptable():
|
||||
_corresp = [
|
||||
(u"A", [0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x0100,0x0102,0x0104]),
|
||||
(u"AE", [0x00C6]),
|
||||
(u"a", [0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x0101,0x0103,0x0105]),
|
||||
(u"ae", [0x00E6]),
|
||||
(u"C", [0x00C7,0x0106,0x0108,0x010A,0x010C]),
|
||||
(u"c", [0x00E7,0x0107,0x0109,0x010B,0x010D]),
|
||||
(u"D", [0x00D0,0x010E,0x0110]),
|
||||
(u"d", [0x00F0,0x010F,0x0111]),
|
||||
(u"E", [0x00C8,0x00C9,0x00CA,0x00CB,0x0112,0x0114,0x0116,0x0118,0x011A]),
|
||||
(u"e", [0x00E8,0x00E9,0x00EA,0x00EB,0x0113,0x0115,0x0117,0x0119,0x011B]),
|
||||
(u"G", [0x011C,0x011E,0x0120,0x0122]),
|
||||
(u"g", [0x011D,0x011F,0x0121,0x0123]),
|
||||
(u"H", [0x0124,0x0126]),
|
||||
(u"h", [0x0125,0x0127]),
|
||||
(u"I", [0x00CC,0x00CD,0x00CE,0x00CF,0x0128,0x012A,0x012C,0x012E,0x0130]),
|
||||
(u"i", [0x00EC,0x00ED,0x00EE,0x00EF,0x0129,0x012B,0x012D,0x012F,0x0131]),
|
||||
(u"IJ", [0x0132]),
|
||||
(u"ij", [0x0133]),
|
||||
(u"J", [0x0134]),
|
||||
(u"j", [0x0135]),
|
||||
(u"K", [0x0136]),
|
||||
(u"k", [0x0137,0x0138]),
|
||||
(u"L", [0x0139,0x013B,0x013D,0x013F,0x0141]),
|
||||
(u"l", [0x013A,0x013C,0x013E,0x0140,0x0142]),
|
||||
(u"N", [0x00D1,0x0143,0x0145,0x0147,0x014A]),
|
||||
(u"n", [0x00F1,0x0144,0x0146,0x0148,0x0149,0x014B]),
|
||||
(u"O", [0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D8,0x014C,0x014E,0x0150]),
|
||||
(u"o", [0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F8,0x014D,0x014F,0x0151]),
|
||||
(u"OE", [0x0152]),
|
||||
(u"oe", [0x0153]),
|
||||
(u"R", [0x0154,0x0156,0x0158]),
|
||||
(u"r", [0x0155,0x0157,0x0159]),
|
||||
(u"S", [0x015A,0x015C,0x015E,0x0160]),
|
||||
(u"s", [0x015B,0x015D,0x015F,0x01610,0x017F]),
|
||||
(u"T", [0x0162,0x0164,0x0166]),
|
||||
(u"t", [0x0163,0x0165,0x0167]),
|
||||
(u"U", [0x00D9,0x00DA,0x00DB,0x00DC,0x0168,0x016A,0x016C,0x016E,0x0170,0x172]),
|
||||
(u"u", [0x00F9,0x00FA,0x00FB,0x00FC,0x0169,0x016B,0x016D,0x016F,0x0171]),
|
||||
(u"W", [0x0174]),
|
||||
(u"w", [0x0175]),
|
||||
(u"Y", [0x00DD,0x0176,0x0178]),
|
||||
(u"y", [0x00FD,0x00FF,0x0177]),
|
||||
(u"Z", [0x0179,0x017B,0x017D]),
|
||||
(u"z", [0x017A,0x017C,0x017E]),
|
||||
(u"2", [0x00B2]), # deux exposant
|
||||
(u" ", [0x00A0]), #  
|
||||
(u"", [0xB0]), # degre
|
||||
(u"", [0xA9]), # copyright
|
||||
(u"1/2", [0xBD]), # 1/2
|
||||
("A", [0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x0100, 0x0102, 0x0104]),
|
||||
("AE", [0x00C6]),
|
||||
("a", [0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x0101, 0x0103, 0x0105]),
|
||||
("ae", [0x00E6]),
|
||||
("C", [0x00C7, 0x0106, 0x0108, 0x010A, 0x010C]),
|
||||
("c", [0x00E7, 0x0107, 0x0109, 0x010B, 0x010D]),
|
||||
("D", [0x00D0, 0x010E, 0x0110]),
|
||||
("d", [0x00F0, 0x010F, 0x0111]),
|
||||
("E", [0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0112, 0x0114, 0x0116, 0x0118, 0x011A]),
|
||||
("e", [0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0113, 0x0115, 0x0117, 0x0119, 0x011B]),
|
||||
("G", [0x011C, 0x011E, 0x0120, 0x0122]),
|
||||
("g", [0x011D, 0x011F, 0x0121, 0x0123]),
|
||||
("H", [0x0124, 0x0126]),
|
||||
("h", [0x0125, 0x0127]),
|
||||
("I", [0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x0128, 0x012A, 0x012C, 0x012E, 0x0130]),
|
||||
("i", [0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x0129, 0x012B, 0x012D, 0x012F, 0x0131]),
|
||||
("IJ", [0x0132]),
|
||||
("ij", [0x0133]),
|
||||
("J", [0x0134]),
|
||||
("j", [0x0135]),
|
||||
("K", [0x0136]),
|
||||
("k", [0x0137, 0x0138]),
|
||||
("L", [0x0139, 0x013B, 0x013D, 0x013F, 0x0141]),
|
||||
("l", [0x013A, 0x013C, 0x013E, 0x0140, 0x0142]),
|
||||
("N", [0x00D1, 0x0143, 0x0145, 0x0147, 0x014A]),
|
||||
("n", [0x00F1, 0x0144, 0x0146, 0x0148, 0x0149, 0x014B]),
|
||||
("O", [0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D8, 0x014C, 0x014E, 0x0150]),
|
||||
("o", [0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F8, 0x014D, 0x014F, 0x0151]),
|
||||
("OE", [0x0152]),
|
||||
("oe", [0x0153]),
|
||||
("R", [0x0154, 0x0156, 0x0158]),
|
||||
("r", [0x0155, 0x0157, 0x0159]),
|
||||
("S", [0x015A, 0x015C, 0x015E, 0x0160]),
|
||||
("s", [0x015B, 0x015D, 0x015F, 0x01610, 0x017F]),
|
||||
("T", [0x0162, 0x0164, 0x0166]),
|
||||
("t", [0x0163, 0x0165, 0x0167]),
|
||||
(
|
||||
"U",
|
||||
[
|
||||
0x00D9,
|
||||
0x00DA,
|
||||
0x00DB,
|
||||
0x00DC,
|
||||
0x0168,
|
||||
0x016A,
|
||||
0x016C,
|
||||
0x016E,
|
||||
0x0170,
|
||||
0x172,
|
||||
],
|
||||
),
|
||||
("u", [0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x016D, 0x016F, 0x0171]),
|
||||
("W", [0x0174]),
|
||||
("w", [0x0175]),
|
||||
("Y", [0x00DD, 0x0176, 0x0178]),
|
||||
("y", [0x00FD, 0x00FF, 0x0177]),
|
||||
("Z", [0x0179, 0x017B, 0x017D]),
|
||||
("z", [0x017A, 0x017C, 0x017E]),
|
||||
("2", [0x00B2]), # deux exposant
|
||||
(" ", [0x00A0]), #  
|
||||
("", [0xB0]), # degre
|
||||
("", [0xA9]), # copyright
|
||||
("1/2", [0xBD]), # 1/2
|
||||
]
|
||||
global _reptable
|
||||
for repchar, codes in _corresp:
|
||||
for code in codes:
|
||||
_reptable[code] = repchar
|
||||
|
||||
|
||||
_fill_reptable()
|
||||
|
||||
|
||||
def suppression_diacritics(s):
|
||||
"""Suppression des accents et autres marques.
|
||||
|
||||
|
@ -20,112 +20,100 @@ Utilisation :
|
||||
import requests
|
||||
|
||||
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
|
||||
from tests.api.tools_test_api import verify_fields
|
||||
from tests.api.tools_test_api import verify_fields, DEPARTEMENT_FIELDS
|
||||
|
||||
|
||||
def test_departements(api_headers):
|
||||
""" "
|
||||
Routes: /departements_ids, /departement, /departement/<string:dept>/formsemestres_ids
|
||||
|
||||
"""
|
||||
Test 'departements'
|
||||
|
||||
Route :
|
||||
- /departements
|
||||
"""
|
||||
|
||||
fields = [
|
||||
"id",
|
||||
"acronym",
|
||||
"description",
|
||||
"visible",
|
||||
"date_creation",
|
||||
]
|
||||
|
||||
# --- Liste des ids
|
||||
r = requests.get(
|
||||
API_URL + "/departements",
|
||||
API_URL + "/departements_ids",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert len(r.json()) == 1
|
||||
departements_ids = r.json()
|
||||
assert isinstance(departements_ids, list)
|
||||
assert len(departements_ids) > 0
|
||||
assert all(isinstance(x, int) for x in departements_ids)
|
||||
|
||||
dept = r.json()[0]
|
||||
dept_id = departements_ids[0]
|
||||
# --- Infos sur un département, accès par id
|
||||
r = requests.get(
|
||||
f"{API_URL}/departement/{dept_id}",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
dept_a = r.json()
|
||||
assert verify_fields(dept_a, DEPARTEMENT_FIELDS) is True
|
||||
# --- Infos sur un département, accès par acronyme4
|
||||
r = requests.get(
|
||||
f"{API_URL}/departement/{dept_a['acronym']}",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
dept_b = r.json()
|
||||
assert dept_a == dept_b
|
||||
|
||||
fields_OK = verify_fields(dept, fields)
|
||||
|
||||
assert fields_OK is True
|
||||
# Liste des formsemestres
|
||||
r = requests.get(
|
||||
f"{API_URL}/departement/{dept_a['acronym']}/formsemestres_ids",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
dept_ids = r.json()
|
||||
assert isinstance(dept_ids, list)
|
||||
assert all(isinstance(x, int) for x in dept_ids)
|
||||
assert len(dept_ids) > 0
|
||||
assert dept_id in dept_ids
|
||||
|
||||
|
||||
def test_list_etudiants(api_headers):
|
||||
"""
|
||||
Test 'list_etudiants'
|
||||
|
||||
Routes :
|
||||
- /departements/<string:dept>/etudiants/list
|
||||
- /departements/<string:dept>/etudiants/list/<int:formsemestre_id>
|
||||
"""
|
||||
fields = {
|
||||
"civilite",
|
||||
"code_ine",
|
||||
"code_nip",
|
||||
"date_naissance",
|
||||
"email",
|
||||
"emailperso",
|
||||
"etudid",
|
||||
"nom",
|
||||
"prenom",
|
||||
"nomprenom",
|
||||
"lieu_naissance",
|
||||
"dept_naissance",
|
||||
"nationalite",
|
||||
"boursier",
|
||||
"id",
|
||||
"codepostaldomicile",
|
||||
"paysdomicile",
|
||||
"telephonemobile",
|
||||
"typeadresse",
|
||||
"domicile",
|
||||
"villedomicile",
|
||||
"telephone",
|
||||
"fax",
|
||||
"description",
|
||||
}
|
||||
fields = {"id", "nip", "ine", "nom", "nom_usuel", "prenom", "civilite"}
|
||||
|
||||
r = requests.get(
|
||||
API_URL + "/departements/TAPI/etudiants/list",
|
||||
API_URL + "/departement/TAPI/etudiants",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
|
||||
etu = r.json()[0]
|
||||
|
||||
fields_OK = verify_fields(etu, fields)
|
||||
|
||||
assert r.status_code == 200
|
||||
assert len(r.json()) == 16
|
||||
assert fields_OK is True
|
||||
etud = r.json()[0]
|
||||
assert verify_fields(etud, fields) is True
|
||||
assert isinstance(etud["id"], int)
|
||||
|
||||
r = requests.get(
|
||||
API_URL + "/departements/TAPI/etudiants/list/1",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
|
||||
etu = r.json()[0]
|
||||
|
||||
fields_OK = verify_fields(etu, fields)
|
||||
|
||||
assert r.status_code == 200
|
||||
assert len(r.json()) == 16
|
||||
assert fields_OK is True
|
||||
# Vérification que chaque id, nip et ine sont uniques (EN CHANTIER)
|
||||
# all_uniques = True
|
||||
# d = dict()
|
||||
# i = 0
|
||||
#
|
||||
# for etu in r.json():
|
||||
# d[i] = [etu["id"], etu["nip"], etu["ine"]]
|
||||
# i += 1
|
||||
#
|
||||
# d[4][2] = 65
|
||||
#
|
||||
# for i in range(len(d)-1):
|
||||
# if d[i][0] == d[i+1][0]:
|
||||
# all_uniques = False
|
||||
# else:
|
||||
# if d[i][1] == d[i+1][1]:
|
||||
# all_uniques = False
|
||||
# else:
|
||||
# if d[i][2] == d[i+1][2]:
|
||||
# all_uniques = False
|
||||
# i += 1
|
||||
#
|
||||
# assert all_uniques is True
|
||||
|
||||
|
||||
# liste_semestres_courant
|
||||
def test_semestres_courant(api_headers):
|
||||
"""
|
||||
Test 'liste_semestres_courant'
|
||||
|
||||
Route :
|
||||
- /departements/<string:dept>/semestres_courants
|
||||
"""
|
||||
fields = [
|
||||
"titre",
|
||||
"gestion_semestrielle",
|
||||
@ -149,22 +137,39 @@ def test_semestres_courant(api_headers):
|
||||
"block_moyennes",
|
||||
"formsemestre_id",
|
||||
"titre_num",
|
||||
"titre_formation",
|
||||
"date_debut_iso",
|
||||
"date_fin_iso",
|
||||
"responsables",
|
||||
"titre_court",
|
||||
]
|
||||
|
||||
dept_id = 1
|
||||
r = requests.get(
|
||||
API_URL + "/departements/TAPI/semestres_courants",
|
||||
f"{API_URL}/departement/{dept_id}",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
|
||||
sem = r.json()[0]
|
||||
|
||||
fields_OK = verify_fields(sem, fields)
|
||||
|
||||
assert r.status_code == 200
|
||||
assert len(r.json()) == 1
|
||||
assert fields_OK is True
|
||||
dept = r.json()
|
||||
assert dept["id"] == dept_id
|
||||
# Accès via acronyme
|
||||
r = requests.get(
|
||||
f"{API_URL}/departement/{dept['acronym']}/formsemestres_courants",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
result_a = r.json()
|
||||
assert isinstance(result_a, list) # liste de formsemestres
|
||||
assert len(result_a) > 0
|
||||
sem = result_a[0]
|
||||
assert verify_fields(sem, fields) is True
|
||||
|
||||
# accès via dept_id
|
||||
r = requests.get(
|
||||
f"{API_URL}/departement/{dept['id']}/formsemestres_courants",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
result_b = r.json()
|
||||
assert result_a == result_b
|
||||
|
@ -16,30 +16,19 @@ Utilisation :
|
||||
Lancer :
|
||||
pytest tests/api/test_api_etudiants.py
|
||||
"""
|
||||
from random import randint
|
||||
|
||||
import requests
|
||||
|
||||
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
|
||||
from tests.api.tools_test_api import verify_fields
|
||||
from tests.api.tools_test_api import ETUD_FIELDS, FSEM_FIELDS
|
||||
|
||||
|
||||
# etudiants_courant
|
||||
def test_etudiants_courant(api_headers):
|
||||
"""
|
||||
Test 'etudiants_courant'
|
||||
|
||||
Routes :
|
||||
- /etudiants/courant
|
||||
- /etudiants/courant/long
|
||||
Route: /etudiants/courant
|
||||
"""
|
||||
fields = [
|
||||
"id",
|
||||
"nip",
|
||||
"nom",
|
||||
"nom_usuel",
|
||||
"prenom",
|
||||
"civilite",
|
||||
]
|
||||
fields = {"id", "nip", "nom", "prenom", "civilite"}
|
||||
|
||||
r = requests.get(
|
||||
API_URL + "/etudiants/courant",
|
||||
@ -48,43 +37,26 @@ def test_etudiants_courant(api_headers):
|
||||
)
|
||||
assert r.status_code == 200
|
||||
etudiants = r.json()
|
||||
assert len(etudiants) == 16 # XXX HARDCODED
|
||||
assert len(etudiants) > 0
|
||||
|
||||
etud = etudiants[-1]
|
||||
assert verify_fields(etud, fields) is True
|
||||
assert isinstance(etud["id"], int)
|
||||
assert isinstance(etud["nip"], str)
|
||||
assert isinstance(etud["nom"], str)
|
||||
assert isinstance(etud["prenom"], str)
|
||||
assert isinstance(etud["civilite"], str)
|
||||
|
||||
fields_ok = verify_fields(etud, fields)
|
||||
all_unique = True
|
||||
list_ids = [etu["id"] for etu in etudiants]
|
||||
|
||||
assert fields_ok is True
|
||||
for i in range(len(etudiants) - 1):
|
||||
if etudiants.count(list_ids[i]) > 1:
|
||||
all_unique = False
|
||||
|
||||
assert all_unique is True
|
||||
|
||||
########## Version long ################
|
||||
|
||||
fields_long = [
|
||||
"civilite",
|
||||
"code_ine",
|
||||
"code_nip",
|
||||
"date_naissance",
|
||||
"email",
|
||||
"emailperso",
|
||||
"etudid",
|
||||
"nom",
|
||||
"prenom",
|
||||
"nomprenom",
|
||||
"lieu_naissance",
|
||||
"dept_naissance",
|
||||
"nationalite",
|
||||
"boursier",
|
||||
"id",
|
||||
"codepostaldomicile",
|
||||
"paysdomicile",
|
||||
"telephonemobile",
|
||||
"typeadresse",
|
||||
"domicile",
|
||||
"villedomicile",
|
||||
"telephone",
|
||||
"fax",
|
||||
"description",
|
||||
]
|
||||
|
||||
r = requests.get(
|
||||
API_URL + "/etudiants/courant/long",
|
||||
headers=api_headers,
|
||||
@ -95,46 +67,13 @@ def test_etudiants_courant(api_headers):
|
||||
assert len(etudiants) == 16 # HARDCODED
|
||||
|
||||
etud = etudiants[-1]
|
||||
fields_ok = verify_fields(etud, fields_long)
|
||||
|
||||
assert fields_ok is True
|
||||
assert verify_fields(etud, ETUD_FIELDS) is True
|
||||
|
||||
|
||||
def test_etudiant(api_headers):
|
||||
"""
|
||||
Test 'etudiant'
|
||||
|
||||
Routes :
|
||||
- /etudiant/etudid/<int:etudid>
|
||||
- /etudiant/nip/<int:nip>
|
||||
- /etudiant/ine/<int:ine>
|
||||
Route:
|
||||
"""
|
||||
fields = [
|
||||
"civilite",
|
||||
"code_ine",
|
||||
"code_nip",
|
||||
"date_naissance",
|
||||
"email",
|
||||
"emailperso",
|
||||
"etudid",
|
||||
"nom",
|
||||
"prenom",
|
||||
"nomprenom",
|
||||
"lieu_naissance",
|
||||
"dept_naissance",
|
||||
"nationalite",
|
||||
"boursier",
|
||||
"id",
|
||||
"domicile",
|
||||
"villedomicile",
|
||||
"telephone",
|
||||
"fax",
|
||||
"description",
|
||||
"codepostaldomicile",
|
||||
"paysdomicile",
|
||||
"telephonemobile",
|
||||
"typeadresse",
|
||||
]
|
||||
|
||||
######### Test etudid #########
|
||||
r = requests.get(
|
||||
@ -144,10 +83,8 @@ def test_etudiant(api_headers):
|
||||
)
|
||||
assert r.status_code == 200
|
||||
etud = r.json()
|
||||
assert len(etud) == 24 # ? HARDCODED
|
||||
|
||||
fields_ok = verify_fields(etud, fields)
|
||||
assert fields_ok is True
|
||||
assert verify_fields(etud, ETUD_FIELDS) is True
|
||||
|
||||
######### Test code nip #########
|
||||
|
||||
@ -158,8 +95,7 @@ def test_etudiant(api_headers):
|
||||
)
|
||||
assert r.status_code == 200
|
||||
etud = r.json()
|
||||
assert len(etud) == 24
|
||||
fields_ok = verify_fields(etud, fields)
|
||||
fields_ok = verify_fields(etud, ETUD_FIELDS)
|
||||
assert fields_ok is True
|
||||
|
||||
######### Test code ine #########
|
||||
@ -172,47 +108,14 @@ def test_etudiant(api_headers):
|
||||
assert r.status_code == 200
|
||||
etud = r.json()
|
||||
assert len(etud) == 24
|
||||
fields_ok = verify_fields(etud, fields)
|
||||
fields_ok = verify_fields(etud, ETUD_FIELDS)
|
||||
assert fields_ok is True
|
||||
|
||||
|
||||
def test_etudiant_formsemestres(api_headers):
|
||||
"""
|
||||
Test 'etudiant_formsemestres'
|
||||
|
||||
Routes :
|
||||
- /etudiant/etudid/<int:etudid>/formsemestres
|
||||
- /etudiant/nip/<int:nip>/formsemestres
|
||||
- /etudiant/ine/<int:ine>/formsemestres
|
||||
Route: /etudiant/etudid/<etudid:int>/formsemestres
|
||||
"""
|
||||
fields = [
|
||||
"date_fin",
|
||||
"resp_can_edit",
|
||||
"dept_id",
|
||||
"etat",
|
||||
"resp_can_change_ens",
|
||||
"id",
|
||||
"modalite",
|
||||
"ens_can_edit_eval",
|
||||
"formation_id",
|
||||
"gestion_compensation",
|
||||
"elt_sem_apo",
|
||||
"semestre_id",
|
||||
"bul_hide_xml",
|
||||
"elt_annee_apo",
|
||||
"titre",
|
||||
"block_moyennes",
|
||||
"scodoc7_id",
|
||||
"date_debut",
|
||||
"gestion_semestrielle",
|
||||
"bul_bgcolor",
|
||||
"formsemestre_id",
|
||||
"titre_num",
|
||||
"date_debut_iso",
|
||||
"date_fin_iso",
|
||||
"responsables",
|
||||
"titre_court",
|
||||
]
|
||||
|
||||
######### Test etudid #########
|
||||
|
||||
@ -226,9 +129,7 @@ def test_etudiant_formsemestres(api_headers):
|
||||
assert len(formsemestres) == 1
|
||||
|
||||
formsemestre = formsemestres[0]
|
||||
|
||||
fields_ok = verify_fields(formsemestre, fields)
|
||||
assert fields_ok is True
|
||||
assert verify_fields(formsemestre, FSEM_FIELDS) is True
|
||||
|
||||
######### Test code nip #########
|
||||
r = requests.get(
|
||||
@ -241,9 +142,7 @@ def test_etudiant_formsemestres(api_headers):
|
||||
assert len(formsemestres) == 1
|
||||
|
||||
formsemestre = formsemestres[0]
|
||||
|
||||
fields_ok = verify_fields(formsemestre, fields)
|
||||
assert fields_ok is True
|
||||
assert verify_fields(formsemestre, FSEM_FIELDS) is True
|
||||
|
||||
######### Test code ine #########
|
||||
r = requests.get(
|
||||
@ -256,28 +155,12 @@ def test_etudiant_formsemestres(api_headers):
|
||||
assert len(formsemestres) == 1
|
||||
|
||||
formsemestre = formsemestres[0]
|
||||
|
||||
fields_ok = verify_fields(formsemestre, fields)
|
||||
assert fields_ok is True
|
||||
assert verify_fields(formsemestre, FSEM_FIELDS) is True
|
||||
|
||||
|
||||
def test_etudiant_bulletin_semestre(api_headers):
|
||||
"""
|
||||
Test 'etudiant_bulletin_semestre'
|
||||
|
||||
Routes :
|
||||
- /etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin
|
||||
- /etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin
|
||||
- /etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin
|
||||
- /etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin/pdf
|
||||
- /etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin/pdf
|
||||
- /etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin/pdf
|
||||
- /etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin/short
|
||||
- /etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin/short
|
||||
- /etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin/short
|
||||
- /etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf
|
||||
- /etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf
|
||||
- /etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf
|
||||
Route: /etudiant/etudid/<etudid>/formsemestre/<formsemestre_id>/bulletin
|
||||
"""
|
||||
######### Test etudid #########
|
||||
|
||||
@ -311,15 +194,19 @@ def test_etudiant_bulletin_semestre(api_headers):
|
||||
bul = r.json()
|
||||
assert len(bul) == 13 # HARDCODED
|
||||
|
||||
### --- Test étudiant inexistant
|
||||
r = requests.get(
|
||||
API_URL + "/etudiant/ine/189919919119191/formsemestre/1/bulletin",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 404
|
||||
|
||||
|
||||
def test_etudiant_groups(api_headers):
|
||||
"""
|
||||
Test 'etudiant_groups'
|
||||
|
||||
Routes :
|
||||
- /etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/groups
|
||||
- /etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/groups
|
||||
- /etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/groups
|
||||
Route:
|
||||
/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/groups
|
||||
"""
|
||||
fields = [
|
||||
"partition_id",
|
||||
|
@ -21,15 +21,12 @@ import requests
|
||||
|
||||
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
|
||||
from tests.api.tools_test_api import verify_fields
|
||||
from tests.api.tools_test_api import FORMATION_FIELDS, MODIMPL_FIELDS
|
||||
|
||||
|
||||
# formations
|
||||
def test_formations_ids(api_headers):
|
||||
"""
|
||||
Test 'formations_ids'
|
||||
|
||||
Routes :
|
||||
- /formations_ids
|
||||
Route: /formations_ids
|
||||
"""
|
||||
r = requests.get(
|
||||
API_URL + "/formations_ids",
|
||||
@ -44,150 +41,67 @@ def test_formations_ids(api_headers):
|
||||
assert all(isinstance(x, int) for x in formations_ids)
|
||||
|
||||
|
||||
# formations_by_id
|
||||
def test_formations_by_id(api_headers):
|
||||
"""
|
||||
Test 'formations_by_id'
|
||||
|
||||
Routes :
|
||||
- /formations/<int:formation_id>
|
||||
Route: /formation/<int:formation_id>
|
||||
"""
|
||||
fields = [
|
||||
"id",
|
||||
"acronyme",
|
||||
"titre_officiel",
|
||||
"formation_code",
|
||||
"code_specialite",
|
||||
"dept_id",
|
||||
"titre",
|
||||
"version",
|
||||
"type_parcours",
|
||||
"referentiel_competence_id",
|
||||
"formation_id",
|
||||
]
|
||||
|
||||
r = requests.get(
|
||||
API_URL + "/formations/1",
|
||||
API_URL + "/formation/1",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
formation = r.json()
|
||||
|
||||
fields_ok = verify_fields(formation, fields)
|
||||
assert fields_ok is True
|
||||
assert verify_fields(formation, FORMATION_FIELDS) is True
|
||||
# TODO tester le contenu de certains champs
|
||||
|
||||
|
||||
def test_formation_export(api_headers):
|
||||
"""
|
||||
Test 'formation_export_by_formation_id'
|
||||
|
||||
Routes :
|
||||
- /formations/formation_export/<int:formation_id>
|
||||
- /formations/formation_export/<int:formation_id>/with_ids
|
||||
Route: /formation/formation_export/<int:formation_id>
|
||||
"""
|
||||
fields = [
|
||||
"id",
|
||||
"acronyme",
|
||||
"titre_officiel",
|
||||
"formation_code",
|
||||
"code_specialite",
|
||||
"dept_id",
|
||||
"titre",
|
||||
"version",
|
||||
"type_parcours",
|
||||
"referentiel_competence_id",
|
||||
"formation_id",
|
||||
"ue",
|
||||
]
|
||||
r = requests.get(
|
||||
API_URL + "/formations/formation_export/1",
|
||||
API_URL + "/formation/formation_export/1",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
|
||||
export_formation = r.json()
|
||||
|
||||
fields_ok = verify_fields(export_formation, fields)
|
||||
assert fields_ok is True
|
||||
assert verify_fields(export_formation, FORMATION_FIELDS) is True
|
||||
# TODO tester le contenu de certains champs
|
||||
|
||||
|
||||
# TODO
|
||||
# def test_formsemestre_apo(api_headers):
|
||||
# r = requests.get(
|
||||
# API_URL + "/formation/apo/<string:etape_apo>",
|
||||
# headers=api_headers,
|
||||
# verify=CHECK_CERTIFICATE,
|
||||
# )
|
||||
# assert r.status_code == 200
|
||||
|
||||
|
||||
def test_moduleimpl(api_headers):
|
||||
"""
|
||||
Test 'moduleimpl'
|
||||
|
||||
Route :
|
||||
- /formations/moduleimpl/<int:moduleimpl_id>
|
||||
Route: /formation/moduleimpl/<int:moduleimpl_id>
|
||||
"""
|
||||
fields = [
|
||||
"id",
|
||||
"formsemestre_id",
|
||||
"computation_expr",
|
||||
"module_id",
|
||||
"responsable_id",
|
||||
"moduleimpl_id",
|
||||
"ens",
|
||||
"module",
|
||||
]
|
||||
|
||||
r = requests.get(
|
||||
API_URL + "/formations/moduleimpl/1",
|
||||
API_URL + "/formation/moduleimpl/1",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
moduleimpl = r.json()
|
||||
|
||||
fields_ok = verify_fields(moduleimpl, fields)
|
||||
assert fields_ok is True
|
||||
assert verify_fields(moduleimpl, MODIMPL_FIELDS) is True
|
||||
# TODO tester le contenu de certains champs
|
||||
|
||||
|
||||
def test_moduleimpls_sem(api_headers):
|
||||
"""
|
||||
Test 'moduleimpls_sem'
|
||||
|
||||
Route :
|
||||
- /formations/moduleimpl/formsemestre/<int:formsemestre_id>/list
|
||||
"""
|
||||
fields = [
|
||||
"id",
|
||||
"formsemestre_id",
|
||||
"computation_expr",
|
||||
"module_id",
|
||||
"responsable_id",
|
||||
"moduleimpl_id",
|
||||
"ens",
|
||||
"module",
|
||||
"moduleimpl_id",
|
||||
"ens",
|
||||
]
|
||||
r = requests.get(
|
||||
API_URL + "/formations/moduleimpl/formsemestre/1/list",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
moduleimpls = r.json()
|
||||
moduleimpl = moduleimpls[0]
|
||||
|
||||
fields_ok = verify_fields(moduleimpl, fields)
|
||||
assert len(moduleimpls) == 21 # XXX HARDCODED !
|
||||
assert fields_ok is True
|
||||
|
||||
|
||||
def test_referentiel_competences(api_headers):
|
||||
"""
|
||||
Test 'referentiel_competences'
|
||||
|
||||
Route :
|
||||
- /formations/<int:formation_id>/referentiel_competences
|
||||
Route: "/formation/<int:formation_id>/referentiel_competences",
|
||||
"""
|
||||
r = requests.get(
|
||||
API_URL + "/formations/1/referentiel_competences",
|
||||
API_URL + "/formation/1/referentiel_competences",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
|
@ -18,17 +18,16 @@ Utilisation :
|
||||
"""
|
||||
|
||||
import requests
|
||||
from app.api.formsemestres import formsemestre
|
||||
|
||||
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
|
||||
from tests.api.tools_test_api import verify_fields
|
||||
from tests.api.tools_test_api import MODIMPL_FIELDS, verify_fields
|
||||
from tests.api.tools_test_api import FSEM_FIELDS, UE_FIELDS, MODULE_FIELDS
|
||||
|
||||
|
||||
def test_formsemestre(api_headers):
|
||||
"""
|
||||
Test 'formsemestre'
|
||||
|
||||
Route :
|
||||
- /formsemestre/<int:formsemestre_id>
|
||||
Route: /formsemestre/<id>
|
||||
"""
|
||||
r = requests.get(
|
||||
API_URL + "/formsemestre/1",
|
||||
@ -36,64 +35,48 @@ def test_formsemestre(api_headers):
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
|
||||
formsemestre = r.json()
|
||||
|
||||
fields = [
|
||||
"date_fin",
|
||||
"resp_can_edit",
|
||||
"dept_id",
|
||||
"etat",
|
||||
"resp_can_change_ens",
|
||||
"id",
|
||||
"modalite",
|
||||
"ens_can_edit_eval",
|
||||
"formation_id",
|
||||
"gestion_compensation",
|
||||
"elt_sem_apo",
|
||||
"semestre_id",
|
||||
"bul_hide_xml",
|
||||
"elt_annee_apo",
|
||||
"titre",
|
||||
"block_moyennes",
|
||||
"scodoc7_id",
|
||||
"date_debut",
|
||||
"gestion_semestrielle",
|
||||
"bul_bgcolor",
|
||||
"formsemestre_id",
|
||||
"titre_num",
|
||||
"date_debut_iso",
|
||||
"date_fin_iso",
|
||||
"responsables",
|
||||
]
|
||||
|
||||
fields_ok = verify_fields(formsemestre, fields)
|
||||
|
||||
assert fields_ok is True
|
||||
assert verify_fields(formsemestre, FSEM_FIELDS)
|
||||
|
||||
|
||||
# TODO
|
||||
# def test_formsemestre_apo(api_headers):
|
||||
# """
|
||||
# Test 'formsemestre_apo'
|
||||
#
|
||||
# Route :
|
||||
# - /formsemestre/apo/<string:etape_apo>
|
||||
# """
|
||||
# r = requests.get(
|
||||
# API_URL + "/formations/apo/<string:etape_apo>",
|
||||
# headers=api_headers,
|
||||
# verify=CHECK_CERTIFICATE,
|
||||
# )
|
||||
# assert r.status_code == 200
|
||||
def test_etudiant_bulletin(api_headers):
|
||||
"""
|
||||
Route:
|
||||
"""
|
||||
formsemestre_id = 1
|
||||
r = requests.get(
|
||||
f"{API_URL}/etudiant/etudid/1/formsemestre/{formsemestre_id}/bulletin",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
bull_a = r.json()
|
||||
|
||||
r = requests.get(
|
||||
f"{API_URL}/etudiant/nip/1/formsemestre/{formsemestre_id}/bulletin",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
bull_b = r.json()
|
||||
|
||||
r = requests.get(
|
||||
f"{API_URL}/etudiant/ine/1/formsemestre/{formsemestre_id}/bulletin",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
bull_c = r.json()
|
||||
# elimine les dates de publication pour comparer les autres champs
|
||||
del bull_a["date"]
|
||||
del bull_b["date"]
|
||||
del bull_c["date"]
|
||||
assert bull_a == bull_b == bull_c
|
||||
|
||||
|
||||
def test_bulletins(api_headers):
|
||||
"""
|
||||
Test 'bulletins'
|
||||
|
||||
Route:
|
||||
- /formsemestre/<int:formsemestre_id>/bulletins
|
||||
"""
|
||||
r = requests.get(
|
||||
API_URL + "/formsemestre/1/bulletins",
|
||||
@ -105,12 +88,6 @@ def test_bulletins(api_headers):
|
||||
|
||||
# # jury
|
||||
# def test_jury():
|
||||
# """
|
||||
# Test 'jury'
|
||||
#
|
||||
# Route :
|
||||
# - /formsemestre/<int:formsemestre_id>/jury
|
||||
# """
|
||||
# r = requests.get(
|
||||
# API_URL + "/formsemestre/1/jury",
|
||||
# headers=api_headers,
|
||||
@ -118,70 +95,11 @@ def test_bulletins(api_headers):
|
||||
# )
|
||||
# assert r.status_code == 200
|
||||
|
||||
# TODO A revoir
|
||||
def test_programme(api_headers):
|
||||
|
||||
def test_formsemestre_programme(api_headers):
|
||||
"""
|
||||
Test 'programme'
|
||||
|
||||
Route :
|
||||
- /formsemestre/<int:formsemestre_id>/programme
|
||||
Route: /formsemestre/1/programme
|
||||
"""
|
||||
ue_fields = [
|
||||
"semestre_idx",
|
||||
"type",
|
||||
"formation_id",
|
||||
"ue_code",
|
||||
"id",
|
||||
"ects",
|
||||
"acronyme",
|
||||
"is_external",
|
||||
"numero",
|
||||
"code_apogee",
|
||||
"titre",
|
||||
"coefficient",
|
||||
"color",
|
||||
"ue_id",
|
||||
]
|
||||
|
||||
ressource_fields = [
|
||||
"heures_tp",
|
||||
"code_apogee",
|
||||
"titre",
|
||||
"coefficient",
|
||||
"module_type",
|
||||
"id",
|
||||
"ects",
|
||||
"abbrev",
|
||||
"ue_id",
|
||||
"code",
|
||||
"formation_id",
|
||||
"heures_cours",
|
||||
"matiere_id",
|
||||
"heures_td",
|
||||
"semestre_id",
|
||||
"numero",
|
||||
"module_id",
|
||||
]
|
||||
|
||||
sae_fields = [
|
||||
"heures_tp",
|
||||
"code_apogee",
|
||||
"titre",
|
||||
"coefficient",
|
||||
"module_type",
|
||||
"id",
|
||||
"ects",
|
||||
"abbrev",
|
||||
"ue_id",
|
||||
"code",
|
||||
"formation_id",
|
||||
"heures_cours",
|
||||
"matiere_id",
|
||||
"heures_td",
|
||||
"semestre_id",
|
||||
"numero",
|
||||
"module_id",
|
||||
]
|
||||
|
||||
r = requests.get(
|
||||
API_URL + "/formsemestre/1/programme",
|
||||
@ -189,16 +107,22 @@ def test_programme(api_headers):
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert len(r.json()) == 3
|
||||
prog = r.json()
|
||||
assert isinstance(prog, dict)
|
||||
assert "ues" in prog
|
||||
assert "modules" in prog
|
||||
assert "ressources" in prog
|
||||
assert "saes" in prog
|
||||
assert isinstance(prog["ues"], list)
|
||||
assert isinstance(prog["modules"], list)
|
||||
ue = prog["ues"][0]
|
||||
modules = prog["modules"]
|
||||
# Il y a toujours au moins une SAE et une ressources dans notre base de test
|
||||
ressource = prog["ressources"][0]
|
||||
sae = prog["saes"][0]
|
||||
|
||||
ue = r.json()["ues"][0]
|
||||
ressource = r.json()["ressources"][0]
|
||||
sae = r.json()["saes"][0]
|
||||
|
||||
fields_ue_OK = verify_fields(ue, ue_fields)
|
||||
fields_ressource_OK = verify_fields(ressource, ressource_fields)
|
||||
fields_sae_OK = verify_fields(sae, sae_fields)
|
||||
|
||||
assert fields_ue_OK is True
|
||||
assert fields_ressource_OK is True
|
||||
assert fields_sae_OK is True
|
||||
assert verify_fields(ue, UE_FIELDS)
|
||||
if len(modules) > 1:
|
||||
assert verify_fields(modules[0], MODIMPL_FIELDS)
|
||||
assert verify_fields(ressource, MODIMPL_FIELDS)
|
||||
assert verify_fields(sae, MODIMPL_FIELDS)
|
||||
|
@ -43,6 +43,8 @@ def test_permissions(api_headers):
|
||||
# "date_debut":
|
||||
# "date_fin":
|
||||
"dept": "TAPI",
|
||||
"dept_ident": "TAPI",
|
||||
"dept_id": 1,
|
||||
"etape_apo": "???",
|
||||
"etat": "I",
|
||||
"evaluation_id": 1,
|
||||
|
@ -2,16 +2,138 @@
|
||||
"""
|
||||
|
||||
|
||||
def verify_fields(json_response: dict, fields: set) -> bool:
|
||||
def verify_fields(json_response: dict, expected_fields: set) -> bool:
|
||||
"""
|
||||
Vérifie si les champs attendu de la réponse json sont présents
|
||||
|
||||
json_response : la réponse de la requête
|
||||
fields : ensemble des champs à vérifier
|
||||
expected_fields : ensemble des champs à vérifier
|
||||
|
||||
Retourne True ou False
|
||||
"""
|
||||
for field in json_response:
|
||||
if field not in fields:
|
||||
return False
|
||||
return True
|
||||
return all(field in json_response for field in expected_fields)
|
||||
|
||||
|
||||
DEPARTEMENT_FIELDS = [
|
||||
"id",
|
||||
"acronym",
|
||||
"description",
|
||||
"visible",
|
||||
"date_creation",
|
||||
]
|
||||
|
||||
ETUD_FIELDS = {
|
||||
"boursier",
|
||||
"civilite",
|
||||
"code_ine",
|
||||
"code_nip",
|
||||
"codepostaldomicile",
|
||||
"date_naissance",
|
||||
"dept_naissance",
|
||||
"description",
|
||||
"domicile",
|
||||
"email",
|
||||
"emailperso",
|
||||
"etudid",
|
||||
"id",
|
||||
"lieu_naissance",
|
||||
"nationalite",
|
||||
"nom",
|
||||
"nomprenom",
|
||||
"paysdomicile",
|
||||
"prenom",
|
||||
"telephone",
|
||||
"telephonemobile",
|
||||
"typeadresse",
|
||||
"villedomicile",
|
||||
}
|
||||
|
||||
FORMATION_FIELDS = {
|
||||
"id",
|
||||
"acronyme",
|
||||
"titre_officiel",
|
||||
"formation_code",
|
||||
"code_specialite",
|
||||
"dept_id",
|
||||
"titre",
|
||||
"version",
|
||||
"type_parcours",
|
||||
"referentiel_competence_id",
|
||||
"formation_id",
|
||||
}
|
||||
|
||||
FSEM_FIELDS = {
|
||||
"block_moyennes",
|
||||
"bul_bgcolor",
|
||||
"bul_hide_xml",
|
||||
"date_debut_iso",
|
||||
"date_debut",
|
||||
"date_fin_iso",
|
||||
"date_fin",
|
||||
"dept_id",
|
||||
"elt_annee_apo",
|
||||
"elt_sem_apo",
|
||||
"ens_can_edit_eval",
|
||||
"etat",
|
||||
"formation_id",
|
||||
"formsemestre_id",
|
||||
"gestion_compensation",
|
||||
"gestion_semestrielle",
|
||||
"id",
|
||||
"modalite",
|
||||
"resp_can_change_ens",
|
||||
"resp_can_edit",
|
||||
"responsables",
|
||||
"semestre_id",
|
||||
"titre_formation",
|
||||
"titre_num",
|
||||
"titre",
|
||||
}
|
||||
|
||||
MODIMPL_FIELDS = {
|
||||
"id",
|
||||
"formsemestre_id",
|
||||
"computation_expr",
|
||||
"module_id",
|
||||
"responsable_id",
|
||||
"moduleimpl_id",
|
||||
"ens",
|
||||
"module",
|
||||
}
|
||||
|
||||
MODULE_FIELDS = {
|
||||
"heures_tp",
|
||||
"code_apogee",
|
||||
"titre",
|
||||
"coefficient",
|
||||
"module_type",
|
||||
"id",
|
||||
"ects",
|
||||
"abbrev",
|
||||
"ue_id",
|
||||
"code",
|
||||
"formation_id",
|
||||
"heures_cours",
|
||||
"matiere_id",
|
||||
"heures_td",
|
||||
"semestre_id",
|
||||
"numero",
|
||||
"module_id",
|
||||
}
|
||||
|
||||
UE_FIELDS = {
|
||||
"semestre_idx",
|
||||
"type",
|
||||
"formation_id",
|
||||
"ue_code",
|
||||
"id",
|
||||
"ects",
|
||||
"acronyme",
|
||||
"is_external",
|
||||
"numero",
|
||||
"code_apogee",
|
||||
"titre",
|
||||
"coefficient",
|
||||
"color",
|
||||
"ue_id",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user