diff --git a/app/api/formsemestres.py b/app/api/formsemestres.py index af73d6f2f..81df34ede 100644 --- a/app/api/formsemestres.py +++ b/app/api/formsemestres.py @@ -14,14 +14,17 @@ """ import base64 +import datetime import io from operator import attrgetter, itemgetter from flask import g, make_response, request from flask_json import as_json from flask_login import current_user, login_required +from flask_sqlalchemy.query import Query import PIL import sqlalchemy as sa + import app from app import db, log from app.api import api_bp as bp, api_web_bp, API_CLIENT_ERROR @@ -76,37 +79,30 @@ def formsemestre_get(formsemestre_id: int): return formsemestre.to_dict_api() -@bp.route("/formsemestres/query") -@api_web_bp.route("/formsemestres/query") +@bp.route("/formsemestre//with_description") +@api_web_bp.route("/formsemestre//with_description") @login_required @scodoc @permission_required(Permission.ScoView) @as_json -def formsemestres_query(): +def formsemestre_get_with_description(formsemestre_id: int): """ - Retourne les formsemestres filtrés par étape Apogée ou année scolaire - ou département (acronyme ou id) ou état ou code étudiant. + Information sur le formsemestre indiqué, avec description externe et champs pour AutoSco. - PARAMS - ------ - etape_apo : un code étape apogée - annee_scolaire : année de début de l'année scolaire - dept_acronym : acronyme du département (eg "RT") - dept_id : id du département - ine ou nip: code d'un étudiant: ramène alors tous les semestres auxquels il est inscrit. - etat: 0 si verrouillé, 1 sinon - - QUERY - ----- - etape_apo: - annee_scolaire: - dept_acronym: - dept_id: - etat: - nip: - ine: + formsemestre_id : l'id du formsemestre + SAMPLES + ------- + /formsemestre/1/with_description """ + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) + sem = formsemestre.to_dict_api() + _add_description(formsemestre, sem) + return sem + + +def _list_formsemestres_query() -> Query: + """Recupère les formsemestres selon les arguments passés (request.args)""" etape_apo = request.args.get("etape_apo") annee_scolaire = request.args.get("annee_scolaire") dept_acronym = request.args.get("dept_acronym") @@ -157,16 +153,48 @@ def formsemestres_query(): if not inscr_joined: formsemestres = formsemestres.join(FormSemestreInscription).join(Identite) formsemestres = formsemestres.filter_by(code_ine=ine) + return formsemestres.order_by( + FormSemestre.date_debut.desc(), + FormSemestre.modalite, + FormSemestre.semestre_id, + FormSemestre.titre, + ) - return [ - formsemestre.to_dict_api() - for formsemestre in formsemestres.order_by( - FormSemestre.date_debut.desc(), - FormSemestre.modalite, - FormSemestre.semestre_id, - FormSemestre.titre, - ) - ] + +@bp.route("/formsemestres/query") +@api_web_bp.route("/formsemestres/query") +@login_required +@scodoc +@permission_required(Permission.ScoView) +@as_json +def formsemestres_query(): + """ + Retourne les formsemestres filtrés par étape Apogée ou année scolaire + ou département (acronyme ou id) ou état ou code étudiant. + + PARAMS + ------ + etape_apo : un code étape apogée + annee_scolaire : année de début de l'année scolaire + dept_acronym : acronyme du département (eg "RT") + dept_id : id du département + ine ou nip: code d'un étudiant: ramène alors tous les semestres auxquels il est inscrit. + etat: 0 si verrouillé, 1 sinon + + QUERY + ----- + etape_apo: + annee_scolaire: + dept_acronym: + dept_id: + etat: + nip: + ine: + + """ + formsemestres = _list_formsemestres_query() + + return [formsemestre.to_dict_api() for formsemestre in formsemestres] @bp.route("/formsemestre//edit", methods=["POST"]) @@ -815,6 +843,55 @@ def formsemestre_get_description(formsemestre_id: int): return formsemestre.description.to_dict() if formsemestre.description else {} +def _add_description(formsemestre: FormSemestre, sem: dict): + """Add description and autosco fields to sem""" + if formsemestre.description is None: + sem["autosco"] = {} + sem["descr"] = {} + return + sem["descr"] = formsemestre.description.to_dict() + + # Champs calculés pour AutoSco: + nb_inscrits = len(formsemestre.get_inscrits(etats={scu.INSCRIT, scu.DEF})) + nb_dispo = ( + (formsemestre.capacite_accueil - nb_inscrits) + if formsemestre.capacite_accueil is not None + else None + ) + descr: FormSemestreDescription = formsemestre.description + now = datetime.datetime.now(scu.TIME_ZONE) + sem["autosco"] = { + "visible": formsemestre.etat and not formsemestre.bul_hide_xml, + "inscription_autorisee": formsemestre.etat + and (nb_dispo is None or nb_dispo > 0) + and (not descr.date_debut_inscriptions or now >= descr.date_debut_inscriptions) + and (not descr.date_fin_inscriptions or now <= descr.date_fin_inscriptions), + "nb_inscrits": nb_inscrits, + "nb_dispo": nb_dispo, + } + + +@bp.route("/formsemestres/with_description/query") +@api_web_bp.route("/formsemestres/with_description/query") +@login_required +@scodoc +@permission_required(Permission.ScoView) +@as_json +def formsemestres_with_description(): + """Liste des formsemestres (filtrés selon query, voir formsemestres/query) + avec description externe pour AutoSco. + """ + formsemestre: FormSemestre + formsemestres = _list_formsemestres_query() + res = [] + for formsemestre in formsemestres: + sem = formsemestre.to_dict_api() + _add_description(formsemestre, sem) + res.append(sem) + + return res + + @bp.post("/formsemestre//description/edit") @api_web_bp.post("/formsemestre//description/edit") @login_required diff --git a/sco_version.py b/sco_version.py index 7e1128f8c..2b2c72958 100644 --- a/sco_version.py +++ b/sco_version.py @@ -3,7 +3,7 @@ "Infos sur version ScoDoc" -SCOVERSION = "9.7.50" +SCOVERSION = "9.7.51" SCONAME = "ScoDoc"