From 2e1dcce69d961c5cb9d32ce0c9e748a2c2d97efb Mon Sep 17 00:00:00 2001 From: leonard_montalbano Date: Fri, 18 Feb 2022 11:26:17 +0100 Subject: [PATCH] =?UTF-8?q?r=C3=A9solution=20des=20conflis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/sco_api.py | 531 +++++++++++++++++++++++++++++++-------------- 1 file changed, 363 insertions(+), 168 deletions(-) diff --git a/app/api/sco_api.py b/app/api/sco_api.py index c8b20f913..22dbc3e5b 100644 --- a/app/api/sco_api.py +++ b/app/api/sco_api.py @@ -50,38 +50,17 @@ from app.api.errors import error_response from app import models from app.models import FormSemestre, FormSemestreInscription, Identite from app.models import ApcReferentielCompetences +from app.scodoc.sco_abs import annule_absence, annule_justif +from app.scodoc.sco_bulletins import formsemestre_bulletinetud_dict +from app.scodoc.sco_bulletins_json import make_json_formsemestre_bulletinetud +from app.scodoc.sco_formations import formation_export +from app.scodoc.sco_formsemestre_inscriptions import do_formsemestre_inscription_listinscrits +from app.scodoc.sco_groups import setGroups, get_etud_groups +from app.scodoc.sco_moduleimpl import moduleimpl_list from app.scodoc.sco_permissions import Permission -@bp.route("/list_depts", methods=["GET"]) -@token_auth.login_required -def list_depts(): - depts = models.Departement.query.filter_by(visible=True).all() - data = [d.to_dict() for d in depts] - return jsonify(data) - - -@bp.route("/etudiants/courant", methods=["GET"]) -@token_auth.login_required -def etudiants(): - """Liste de tous les étudiants actuellement inscrits à un semestre - en cours. - """ - # Vérification de l'accès: permission Observateur sur tous les départements - # (c'est un exemple à compléter) - if not g.current_user.has_permission(Permission.ScoObservateur, None): - return error_response(401, message="accès interdit") - - query = db.session.query(Identite).filter( - FormSemestreInscription.formsemestre_id == FormSemestre.id, - FormSemestreInscription.etudid == Identite.id, - FormSemestre.date_debut <= func.now(), - FormSemestre.date_fin >= func.now(), - ) - return jsonify([e.to_dict_bul(include_urls=False) for e in query]) - - -######################## Departements ################################## +############################################### Departements ########################################################## @bp.route("/departements", methods=["GET"]) @@ -97,7 +76,7 @@ def departements(): @bp.route("/departements//etudiants/liste/", methods=["GET"]) @token_auth.login_required -def liste_etudiants(dept, *args, sem_id): # XXX TODO A REVOIR +def liste_etudiants(dept: str, *args, sem_id): # XXX TODO A REVOIR """ Liste des étudiants d'un département """ @@ -133,145 +112,273 @@ def liste_etudiants(dept, *args, sem_id): # XXX TODO A REVOIR @bp.route("/departements//semestres_actifs", methods=["GET"]) @token_auth.login_required -def liste_semestres_actifs(dept): # TODO : changer nom +def liste_semestres_courant(dept: str): """ Liste des semestres actifs d'un départements donné """ - # Récupération de l'id du dept - dept_id = models.Departement.query.filter(models.Departement.acronym == dept) - # Puis ici récupération du FormSemestre correspondant - depts_actifs = models.FormSemestre.query.filter_by( - etat=True, - dept_id=dept_id, - ) - data = [da.to_dict() for da in depts_actifs] + depts = models.Departement.query.filter_by(acronym=dept).all() - # return jsonify(data) - return error_response(501, message="Not implemented") + id_dept = depts[0].id + semestres = models.FormSemestre.query.filter_by(dept_id=id_dept, etat=True).all() -@bp.route("/referentiel_competences/") -@token_auth.login_required -def referentiel_competences(referentiel_competence_id): + data = semestres[0].to_dict() + + return jsonify(data) + +@bp.route( + "/departements//formations//referentiel_competences", + methods=["GET"], +) +def referenciel_competences(dept: str, formation_id: int): """ Le référentiel de compétences """ - ref = ApcReferentielCompetences.query.get_or_404(referentiel_competence_id) + # depts = models.Departement.query.filter_by(acronym=dept).all() + # + # id_dept = depts[0].id + # + # formations = models.Formation.query.filter_by(id=formation_id, dept_id=id_dept).all() + # + # ref_comp = formations[0].referentiel_competence_id + # + # if ref_comp is None: + # return error_response(204, message="Pas de référenciel de compétences pour cette formation") + # else: + # return jsonify(ref_comp) + + ref = ApcReferentielCompetences.query.get_or_404(formation_id) + return jsonify(ref.to_dict()) -####################### Etudiants ################################## - - -@bp.route("/etudiant/", methods=["GET"]) -@token_auth.login_required -def etudiant(etudid): +@bp.route("/departements//formations/programme/", methods=["GET"]) +def semestre_index(dept: str, sem_idx: str): """ - Un dictionnaire avec les informations de l'étudiant correspondant à l'id passé en paramètres. + """ - etud: Identite = Identite.query.get_or_404(etudid) - return jsonify(etud.to_dict_bul()) + return error_response(501, message="not implemented") -@bp.route("/etudiant//semestre//bulletin", methods=["GET"]) -@token_auth.login_required -def etudiant_bulletin_semestre(etudid, sem_id): +#################################################### Etudiants ######################################################## + + +@bp.route("/etudiants", methods=["GET"]) +def etudiants(): + """ + La liste des étudiants + """ + etu = models.Identite.query.all() + + data = [d.to_dict_bul(include_urls=False) for d in etu] + + return jsonify(data) + # return error_response(501, message="Not implemented") + + +@bp.route("/etudiants/courant", methods=["GET"]) +def etudiants_courant(): + """ + La liste des étudiants courant + """ + etus = models.Identite.query.all() + + data = [] + for etu in etus: + if etu.inscription_courante() is not None: + data.append(etu.to_dict_bul(include_urls=False)) + + return jsonify(data) + # return error_response(501, message="Not implemented") + +@bp.route("/etudiant/etudid/", methods=["GET"]) +@bp.route("/etudiant/nip/", methods=["GET"]) +@bp.route("/etudiant/ine/", methods=["GET"]) +def etudiant(etudid=None, nip=None, ine=None): + """ + Les informations de l'étudiant correspondant à l'id passé en paramètres. + """ + etu = [] + if etudid is not None: + etu = models.Identite.query.filter_by(id=etudid).first() + if nip is not None: + etu = models.Identite.query.filter_by(code_nip=etudid).first() + if ine is not None: + etu = models.Identite.query.filter_by(code_ine=etudid).first() + + data = etu.to_dict_bul(include_urls=False) + + return jsonify(data) + +@bp.route("/etudiant/etudid//formsemestres") +@bp.route("/etudiant/nip//formsemestres") +@bp.route("/etudiant/ine//formsemestres") +def etudiant_formsemestres(etudid=None, nip=None, ine=None): + """ + Retourne les semestres qu'un étudiant a suivi + """ + + inscriptions = models.FormSemestreInscription.query.all() + + sems = [] + for sem in inscriptions: + if etudid is not None: + if sem.etudid == etudid: + sems.append(sem) + if nip is not None: + etu = models.Identite.query.filter_by(code_nip=nip).first() + if sem.etudid == etu.etudid: + sems.append(sem) + if ine is not None: + etu = models.Identite.query.filter_by(code_ine=ine).firt() + if sem.etudid == etu.etudid: + sems.append(sem) + + data_inscriptions = [d.to_dict() for d in sems] + + formsemestres = [] + + for sem in data_inscriptions: + res = models.FormSemestre.query.filter_by(id=sem['formsemestre_id']).first() + formsemestres.append(res) + + data = [] + for formsem in formsemestres: + data.append(formsem.to_dict()) + + return jsonify(data) + + +@bp.route("/etudiant/etudid//formsemestre//bulletin", methods=["GET"]) +@bp.route("/etudiant/nip//formsemestre//bulletin", methods=["GET"]) +@bp.route("/etudiant/ine//formsemestre//bulletin", methods=["GET"]) +def etudiant_bulletin_semestre(formsemestre_id, etudid=None, nip=None, ine=None): """ Le bulletin d'un étudiant en fonction de son id et d'un semestre donné """ - # return jsonify(models.BulAppreciations.query.filter_by(etudid=etudid, formsemestre_id=sem_id)) - return error_response(501, message="Not implemented") - - -@bp.route( - "/formsemestre//departements//etudiant/nip//releve", - methods=["GET"], -) -@bp.route( - "/formsemestre//departements//etudiant/id//releve", - methods=["GET"], -) -@bp.route( - "/formsemestre//departements//etudiant/ine//releve", - methods=["GET"], -) -@token_auth.login_required -def etudiant_bulletin(formsemestre_id, dept, etudid, format="json", *args, size): - """ - Un bulletin de note - """ - formsemestres = models.FormSemestre.query.filter_by(id=formsemestre_id) - depts = models.Departement.query.filter_by(acronym=dept) - etud = "" - - data = [] - if args[0] == "short": - pass - elif args[0] == "selectevals": - pass - elif args[0] == "long": - pass + # fonction to use: make_json_formsemestre_bulletinetud() + if etudid is not None: + return make_json_formsemestre_bulletinetud(formsemestre_id, etudid) else: - return "erreur" + etu = None + if nip is not None: + etu = models.Identite.query.filter_by(code_nip=nip).first() - # return jsonify(data) - return error_response(501, message="Not implemented") + if ine is not None: + etu = models.Identite.query.filter_by(code_nip=ine).first() + + if etu is not None: + return make_json_formsemestre_bulletinetud(formsemestre_id, etu.etudid) + + # return error_response(501, message="Not implemented") @bp.route( - "/etudiant//semestre//groups", methods=["GET"] + "/etudiant/etudid//semestre//groups", methods=["GET"] ) -@token_auth.login_required -def etudiant_groups(etudid: int, formsemestre_id: int): +@bp.route( + "/etudiant/nip//semestre//groups", methods=["GET"] +) +@bp.route( + "/etudiant/ine//semestre//groups", methods=["GET"] +) +def etudiant_groups(formsemestre_id: int, etudid=None, nip=None, ine=None): """ Liste des groupes auxquels appartient l'étudiant dans le semestre indiqué """ - semestre = models.FormSemestre.query.filter_by(id=formsemestre_id) - etudiant = models.Identite.query.filter_by(id=etudid) + # fonction to use : get_etud_groups - groups = models.Partition.query.filter( - models.Partition.formsemestre_id == semestre, - models.GroupDescr.etudiants == etudiant, - ) - data = [d.to_dict() for d in groups] - # return jsonify(data) + if etudid is None: + if nip is not None: + etu = models.Identite.query.filter_by(code_nip=nip).first() + etudid = etu.etudid + if ine is not None: + etu = models.Identite.query.filter_by(code_ine=ine).first() + etudid = etu.etudid + sem = models.FormSemestre.query.filter_by(id=formsemestre_id).first() + try: + data = get_etud_groups(etudid, sem.to_dict()) + except ValueError: + return error_response(409, message="La requête ne peut être traitée en l’état actuel") - return error_response(501, message="Not implemented") + return jsonify(data) - -#######################" Programmes de formations ######################### +##############################################" Formations ############################################################ @bp.route("/formations", methods=["GET"]) -@bp.route("/formations/", methods=["GET"]) -@token_auth.login_required -def formations(formation_id: int): +def formations(): """ Liste des formations """ - formations = models.Formation.query.filter_by(id=formation_id) - data = [d.to_dict() for d in formations] - # return jsonify(data) + list_formations = models.Formation.query.all() - return error_response(501, message="Not implemented") + data = [d.to_dict() for d in list_formations] + + return jsonify(data) + + +@bp.route("/formations/", methods=["GET"]) +def formations_by_id(formation_id: int): + """ + Formation en fonction d'un id donné + """ + forma = models.Formation.query.filter_by(id=formation_id).all() + + data = [d.to_dict() for d in forma] + + return jsonify(data) @bp.route("/formations/formation_export/", methods=["GET"]) -@token_auth.login_required -def formation_export(formation_id: int, export_ids=False): +def formation_export_by_formation_id(formation_id: int, export_ids=False): """ La formation, avec UE, matières, modules """ + data = formation_export(formation_id) + + return jsonify(data) + + +@bp.route("/formations/apo/", methods=["GET"]) +def formsemestre_apo(etape_apo: int): + """ + Information sur les formsemestres + """ return error_response(501, message="Not implemented") -###################### UE ####################################### +@bp.route("/formations/moduleimpl/", methods=["GET"]) +def moduleimpls(moduleimpl_id: int): + """ + Liste des moduleimpl + """ + list_moduleimpls = models.ModuleImpl.query.filter_by(id=moduleimpl_id) + + data = list_moduleimpls[0].to_dict() + + return jsonify(data) + + +@bp.route( + "/formations/moduleimpl//formsemestre/", + methods=["GET"], +) +def moduleimpls_sem(moduleimpl_id: int, formsemestre_id: int): + """ + Liste de moduleimpl d'un semestre + """ + data = moduleimpl_list(moduleimpl_id, formsemestre_id) + return jsonify(data) + # return error_response(501, message="Not implemented") + + +#################################################### UE ############################################################### @bp.route( "/departements//formations/programme/", methods=["GET"] ) -@token_auth.login_required def eus(dept: str, sem_id: int): """ Liste des UES, ressources et SAE d'un semestre @@ -279,42 +386,70 @@ def eus(dept: str, sem_id: int): return error_response(501, message="Not implemented") -######## Semestres de formation ############### +########################################## Formsemestres ############################################################## @bp.route("/formations/formsemestre/", methods=["GET"]) -@bp.route("/formations/apo/", methods=["GET"]) -@token_auth.login_required -def formsemestre( - id: int, -): +def formsemestre(formsemestre_id: int): """ - Information sur les formsemestres + Information sur le formsemestre correspondant au formsemestre_id """ - return error_response(501, message="Not implemented") + list_formsemetre = models.FormSemestre.query.filter_by(id=formsemestre_id) + + data = list_formsemetre[0].to_dict() + + return jsonify(data) -############ Modules de formation ############## - - -@bp.route("/formations/moduleimpl/", methods=["GET"]) @bp.route( - "/formations/moduleimpl//formsemestre/", + "/formsemestre//departements//etudiant/etudid//bulletin", methods=["GET"], ) -@token_auth.login_required -def moduleimpl(id: int): +@bp.route( + "/formsemestre//departements//etudiant/nip//bulletin", + methods=["GET"], +) +@bp.route( + "/formsemestre//departements//etudiant/ine//bulletin", + methods=["GET"], +) +def etudiant_bulletin(formsemestre_id, dept, etudid, format="json", *args, size): """ - Liste de moduleimpl + Un bulletin de note + """ + data = [] + if args[0] == "short": + data = formsemestre_bulletinetud_dict(formsemestre_id, etudid, version=args[0]) + elif args[0] == "selectevals": + data = formsemestre_bulletinetud_dict(formsemestre_id, etudid, version=args[0]) + elif args[0] == "long": + data = formsemestre_bulletinetud_dict(formsemestre_id, etudid) + else: + return error_response(501, message="Not implemented") + + return jsonify(data) + + +@bp.route("/formsemestre//bulletins", methods=["GET"]) +def bulletins(formsemestre_id: int): + """ + Les bulletins d'un formsemestre donné """ return error_response(501, message="Not implemented") -########### Groupes et partitions ############### +@bp.route("/formsemestre//jury", methods=["GET"]) +def jury(formsemestre_id: int): + """ + + """ + return error_response(501, message="Not implemented") + + +############################################### Partitions ############################################################ @bp.route("/partitions/", methods=["GET"]) -@token_auth.login_required def partition(formsemestre_id: int): """ La liste de toutes les partitions d'un formsemestre @@ -330,7 +465,6 @@ def partition(formsemestre_id: int): "/partitions/formsemestre//groups/group_ids?with_codes=&all_groups=&etat=", methods=["GET"], ) -@token_auth.login_required def groups(formsemestre_id: int, group_ids: int): """ Liste des étudiants dans un groupe @@ -339,24 +473,27 @@ def groups(formsemestre_id: int, group_ids: int): @bp.route( - "/partitions/set_groups?partition_id=&groups=&groups_to_delete=&groups_to_create=", - methods=["POST"], + "/partitions/set_groups?partition_id=&groups_lists=&groups_to_create=&groups_to_delete=", methods=["POST"], ) @token_auth.login_required def set_groups( - partition_id: int, groups: int, groups_to_delete: int, groups_to_create: int + partition_id: int, groups_lists: int, groups_to_delete: int, groups_to_create: int ): """ Set les groups """ - return error_response(501, message="Not implemented") + try: + 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") -####### Bulletins de notes ########### +################################################### Evaluations ####################################################### @bp.route("/evaluations/", methods=["GET"]) -@token_auth.login_required def evaluations(moduleimpl_id: int): """ Liste des évaluations à partir de l'id d'un moduleimpl @@ -364,22 +501,21 @@ def evaluations(moduleimpl_id: int): evals = models.Evaluation.query.filter_by(id=moduleimpl_id) data = [d.to_dict() for d in evals] - # return jsonify(data) - return error_response(501, message="Not implemented") + return jsonify(data) + # return error_response(501, message="Not implemented") @bp.route("/evaluations/eval_notes/", methods=["GET"]) -@token_auth.login_required def evaluation_notes(evaluation_id: int): """ Liste des notes à partir de l'id d'une évaluation donnée """ - evals = models.Evaluation.query.filter_by(id=evaluation_id) - notes = evals.get_notes() + notes = models.NotesNotes.query.filter_by(evaluation_id=evaluation_id).all() data = [d.to_dict() for d in notes] - # return jsonify(data) - return error_response(501, message="Not implemented") + + return jsonify(data) + # return error_response(501, message="Not implemented") @bp.route( @@ -394,20 +530,52 @@ def evaluation_set_notes(eval_id: int, etudid: int, note: float): return error_response(501, message="Not implemented") -############## Absences ############# +#################################################### Absences ######################################################### @bp.route("/absences/", methods=["GET"]) +def absences(etudid=None, nip=None, ine=None): + """ + Liste des absences d'un étudiant donné + """ + abs = "" + if etudid is not None: + abs = models.Absence.query.filter_by(etudid=etudid).all() + else: + if nip is not None: + etu = models.Identite.query.filter_by(code_nip=nip).first() + abs = models.Absence.query.filter_by(etudid=etu.etudid).all() + if ine is not None: + etu = models.Identite.query.filter_by(code_ine=ine).first() + abs = models.Absence.query.filter_by(etudid=etu.etudid).all() + + if abs != "": + data = [d.to_dict() for d in abs] + + return jsonify(data) + return error_response(501, message="Not implemented") + + @bp.route("/absences//abs_just_only", methods=["GET"]) -def absences(etudid: int): +def absences_justify(etudid=None, nip=None, ine=None): """ - Liste des absences d'un étudiant donnée + Liste des absences justifiés d'un étudiant donné """ - abs = models.Absence.query.filter_by(id=etudid) + abs = "" + if etudid is not None: + abs = models.Absence.query.filter_by(etudid=etudid, estjust=True).all() + else: + if nip is not None: + etu = models.Identite.query.filter_by(code_nip=nip).first() + abs = models.Absence.query.filter_by(etudid=etu.etudid, estjust=True).all() + if ine is not None: + etu = models.Identite.query.filter_by(code_ine=ine).first() + abs = models.Absence.query.filter_by(etudid=etu.etudid, estjust=True).all() - data = [d.to_dict() for d in abs] + if abs != "": + data = [d.to_dict() for d in abs] - # return jsonify(data) + return jsonify(data) return error_response(501, message="Not implemented") @@ -420,43 +588,73 @@ def abs_signale(): return error_response(501, message="Not implemented") -@bp.route("/absences/abs_annule", methods=["POST"]) +@bp.route("/absences/abs_annule?etudid=&jour=&matin=", methods=["POST"]) +@bp.route("/absences/abs_annule?nip=&jour=&matin=", methods=["POST"]) +@bp.route("/absences/abs_annule?ine=&jour=&matin=", methods=["POST"]) @token_auth.login_required -def abs_annule(): +def abs_annule(jour: datetime, matin: str, etudid=None, nip=None, ine=None): """ Retourne un html """ - return error_response(501, message="Not implemented") + # fonction to use : annule_absence + if etudid is None: + if nip is not None: + etu = models.Identite.query.filter_by(code_nip=nip).first() + etudid = etu.etudid + if ine is not None: + etu = models.Identite.query.filter_by(code_ine=ine).first() + etudid = etu.etudid + try: + annule_absence(etudid, jour, matin) + except ValueError: + return error_response(409, message="La requête ne peut être traitée en l’état actuel") + + return error_response(200, message="OK") -@bp.route("/absences/abs_annule_justif", methods=["POST"]) +@bp.route("/absences/abs_annule_justif?etudid=&jour=&matin=", methods=["POST"]) +@bp.route("/absences/abs_annule_justif?nip=&jour=&matin=", methods=["POST"]) +@bp.route("/absences/abs_annule_justif?ine=&jour=&matin=", methods=["POST"]) @token_auth.login_required -def abs_annule_justif(): +def abs_annule_justif(jour: datetime, matin: str, etudid=None, nip=None, ine=None): """ Retourne un html """ - return error_response(501, message="Not implemented") + # fonction to use : annule_justif + if etudid is None: + if nip is not None: + etu = models.Identite.query.filter_by(code_nip=nip).first() + etudid = etu.etudid + if ine is not None: + etu = models.Identite.query.filter_by(code_ine=ine).first() + etudid = etu.etudid + try: + annule_justif(etudid, jour, matin) + except ValueError: + return error_response(409, message="La requête ne peut être traitée en l’état actuel") + + return error_response(200, message="OK") @bp.route( "/absences/abs_group_etat/?group_ids=&date_debut=date_debut&date_fin=date_fin", methods=["GET"], ) -@token_auth.login_required def abs_groupe_etat( - group_ids: int, date_debut, date_fin, with_boursier=True, format="html" + group_ids: int, date_debut, date_fin, with_boursier=True, format="html" ): """ Liste des absences d'un ou plusieurs groupes entre deux dates """ + + # list_abs_date return error_response(501, message="Not implemented") -################ Logos ################ +###################################################### Logos ########################################################## @bp.route("/logos", methods=["GET"]) -@token_auth.login_required def liste_logos(format="json"): """ Liste des logos définis pour le site scodoc. @@ -465,7 +663,6 @@ def liste_logos(format="json"): @bp.route("/logos/", methods=["GET"]) -@token_auth.login_required def recup_logo_global(nom: str): """ Retourne l'image au format png ou jpg @@ -474,7 +671,6 @@ def recup_logo_global(nom: str): @bp.route("/departements//logos", methods=["GET"]) -@token_auth.login_required def logo_dept(dept: str): """ Liste des logos définis pour le département visé. @@ -483,7 +679,6 @@ def logo_dept(dept: str): @bp.route("/departement//logos/", methods=["GET"]) -@token_auth.login_required def recup_logo_dept_global(dept: str, nom: str): """ L'image format png ou jpg