diff --git a/app/api/assiduites.py b/app/api/assiduites.py index 50677b74a..c78ccab17 100644 --- a/app/api/assiduites.py +++ b/app/api/assiduites.py @@ -24,13 +24,6 @@ import app.scodoc.sco_utils as scu import app.scodoc.sco_assiduites as scass -""" -TODO: - - Faire une nouvelle route pour obtenir toutes les assiduites d'un formsemstre - - Ajouter des variantes "batch" pour chaque route POST pour envoyer des listes d'objets -""" - - @bp.route("/assiduite/") @api_web_bp.route("/assiduite/") @scodoc @@ -111,52 +104,13 @@ def count_assiduites(etudid: int = None, with_query: bool = False): metric: str = "all" if with_query: - # cas 1 : etat assiduite - etat = request.args.get("etat") - if etat is not None: - filter["etat"] = etat + metric, filter = count_manager(request) - # cas 2 : date de début - deb = request.args.get("date_debut") - deb: datetime = scu.is_iso_formated(deb, True) - if deb is not None: - filter["date_debut"] = deb - - # cas 3 : date de fin - fin = request.args.get("date_fin") - fin = scu.is_iso_formated(fin, True) - - if fin is not None: - filter["date_fin"] = fin - - # cas 4 : moduleimpl_id - module = request.args.get("moduleimpl_id", False) - try: - if module is False: - raise Exception - if module != "": - module = int(module) - else: - module = None - except Exception: - module = False - - if module is not False: - filter["moduleimpl_id"] = module - - # cas 5 : formsemestre_id - formsemestre_id = request.args.get("formsemestre_id") - - if formsemestre_id is not None: - formsemestre: FormSemestre = None - formsemestre_id = int(formsemestre_id) - formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first() - filter["formsemestre"] = formsemestre - - # cas 6 : type - metric = request.args.get("metric", "count") - - return jsonify(scass.get_assiduite_stats(etud=etud, metric=metric, filter=filter)) + return jsonify( + scass.get_assiduites_stats( + assiduites=etud.assiduites, metric=metric, filter=filter + ) + ) @bp.route("/assiduites/", defaults={"with_query": False}) @@ -192,6 +146,9 @@ def assiduites(etudid: int = None, with_query: bool = False): query?moduleimpl_id=[- int ou vide -] ex: query?moduleimpl_id=1234 query?moduleimpl_od= + Formsemstre_id (l'id du formsemestre concerné par l'assiduité) + query?formsemstre_id=[int] + ex query?formsemestre_id=3 """ @@ -204,48 +161,7 @@ def assiduites(etudid: int = None, with_query: bool = False): assiduites = etud.assiduites if with_query: - # cas 1 : etat assiduite - etat = request.args.get("etat") - if etat is not None: - assiduites = scass.filter_by_etat(assiduites, etat) - - # cas 2 : date de début - deb = request.args.get("date_debut") - deb: datetime = scu.is_iso_formated(deb, True) - if deb is not None: - - assiduites = scass.filter_by_date(assiduites, deb, sup=True) - - # cas 3 : date de fin - fin = request.args.get("date_fin") - fin = scu.is_iso_formated(fin, True) - - if fin is not None: - assiduites = scass.filter_by_date(assiduites, fin, sup=False) - - # cas 4 : moduleimpl_id - module = request.args.get("moduleimpl_id", False) - try: - if module is False: - raise Exception - if module != "": - module = int(module) - else: - module = None - except Exception: - module = False - - if module is not False: - assiduites = scass.filter_by_module_impl(assiduites, module) - - # cas 5 : formsemestre_id - formsemestre_id = request.args.get("formsemestre_id") - - if formsemestre_id is not None: - formsemestre: FormSemestre = None - formsemestre_id = int(formsemestre_id) - formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first() - assiduites = scass.filter_by_formsemstre(assiduites, formsemestre) + assiduites = filter_manager(request, assiduites) data_set: List[dict] = [] for ass in assiduites.all(): @@ -255,12 +171,24 @@ def assiduites(etudid: int = None, with_query: bool = False): return jsonify(data_set) -@bp.route("/assiduites/formsemestre/") -@api_web_bp.route("/assiduites/formsemestre/") +@bp.route( + "/assiduites/formsemestre/", defaults={"with_query": False} +) +@api_web_bp.route( + "/assiduites/formsemestre/", defaults={"with_query": False} +) +@bp.route( + "/assiduites/formsemestre//query", + defaults={"with_query": True}, +) +@api_web_bp.route( + "/assiduites/formsemestre//query", + defaults={"with_query": True}, +) @login_required @scodoc @permission_required(Permission.ScoView) -def assiduites_formsemestre(formsemestre_id: int = None): +def assiduites_formsemestre(formsemestre_id: int = None, with_query: bool = False): if formsemestre_id is not None: formsemestre: FormSemestre = None formsemestre_id = int(formsemestre_id) @@ -270,14 +198,16 @@ def assiduites_formsemestre(formsemestre_id: int = None): json_error(404, "le paramètre 'formsemestre_id' n'existe pas") etuds = formsemestre.etuds.all() - assiduites = [] - for etud in etuds: - assiduites.extend( - scass.filter_by_formsemstre(etud.assiduites, formsemestre).all() - ) + etuds_id = [etud.id for etud in etuds] + + assiduites = Assiduite.query.filter(Assiduite.etudid.in_(etuds_id)) + assiduites = scass.filter_by_formsemstre(assiduites, formsemestre) + + if with_query: + assiduites = filter_manager(request, assiduites) data_set: List[dict] = [] - for ass in assiduites: + for ass in assiduites.all(): data = ass.to_dict() data_set.append(change_etat(data)) @@ -287,6 +217,52 @@ def assiduites_formsemestre(formsemestre_id: int = None): return json_error(404, "le paramètre 'formsemestre_id doit être renseigné'") +@bp.route( + "/assiduites/formsemestre//count", + defaults={"with_query": False}, +) +@api_web_bp.route( + "/assiduites/formsemestre//count", + defaults={"with_query": False}, +) +@bp.route( + "/assiduites/formsemestre//count/query", + defaults={"with_query": True}, +) +@api_web_bp.route( + "/assiduites/formsemestre//count/query", + defaults={"with_query": True}, +) +@login_required +@scodoc +@permission_required(Permission.ScoView) +def count_assiduites_formsemestre( + formsemestre_id: int = None, with_query: bool = False +): + if formsemestre_id is not None: + formsemestre: FormSemestre = None + formsemestre_id = int(formsemestre_id) + formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first() + + if formsemestre is None: + json_error(404, "le paramètre 'formsemestre_id' n'existe pas") + + etuds = formsemestre.etuds.all() + etuds_id = [etud.id for etud in etuds] + + assiduites = Assiduite.query.filter(Assiduite.etudid.in_(etuds_id)) + assiduites = scass.filter_by_formsemstre(assiduites, formsemestre) + metric: str = "all" + filter: dict = {} + if with_query: + metric, filter = count_manager(request) + + return jsonify(scass.get_assiduites_stats(assiduites, metric, filter)) + + else: + return json_error(404, "le paramètre 'formsemestre_id doit être renseigné'") + + @bp.route("/assiduite//create", methods=["POST"], defaults={"batch": False}) @api_web_bp.route( "/assiduite//create", methods=["POST"], defaults={"batch": False} @@ -444,7 +420,7 @@ def delete(batch: bool = False): output["success"].append({ass: msg}) else: code, msg = delete_singular( - request.get_json(force=True).get("assiduite_id", -1), db + request.get_json(force=True).get("assiduiteid", -1), db ) output[code] = msg @@ -460,26 +436,12 @@ def delete_singular(assiduite_id: int, db): return (200, "OK") -@bp.route( - "/assiduite//edit", methods=["POST"], defaults={"batch": False} -) -@api_web_bp.route( - "/assiduite//edit", methods=["POST"], defaults={"batch": False} -) -@bp.route( - "/assiduite//edit/batch", - methods=["POST"], - defaults={"batch": True}, -) -@api_web_bp.route( - "/assiduite//edit/batch", - methods=["POST"], - defaults={"batch": True}, -) +@bp.route("/assiduite//edit", methods=["POST"]) +@api_web_bp.route("/assiduite//edit", methods=["POST"]) @login_required @scodoc @permission_required(Permission.ScoAssiduiteChange) -def edit(assiduiteid: int, batch: bool = False): +def edit(assiduiteid: int): """ Edition d'une assiduité à partir de son id La requête doit avoir un content type "application/json": @@ -527,8 +489,6 @@ def edit(assiduiteid: int, batch: bool = False): # -- Utils -- - - def change_etat(data: dict, from_int: bool = True): """change dans un json la valeur du champs état""" if from_int: @@ -536,3 +496,106 @@ def change_etat(data: dict, from_int: bool = True): else: data["etat"] = scu.ETATS_ASSIDUITE.get(data["etat"]) return data + + +def count_manager(request) -> tuple[str, dict]: + """ + Retourne la/les métriques à utiliser ainsi que le filtre donnés en query de la requête + """ + filter: dict = {} + # cas 1 : etat assiduite + etat = request.args.get("etat") + if etat is not None: + filter["etat"] = etat + + # cas 2 : date de début + deb = request.args.get("date_debut") + deb: datetime = scu.is_iso_formated(deb, True) + if deb is not None: + filter["date_debut"] = deb + + # cas 3 : date de fin + fin = request.args.get("date_fin") + fin = scu.is_iso_formated(fin, True) + + if fin is not None: + filter["date_fin"] = fin + + # cas 4 : moduleimpl_id + module = request.args.get("moduleimpl_id", False) + try: + if module is False: + raise Exception + if module != "": + module = int(module) + else: + module = None + except Exception: + module = False + + if module is not False: + filter["moduleimpl_id"] = module + + # cas 5 : formsemestre_id + formsemestre_id = request.args.get("formsemestre_id") + + if formsemestre_id is not None: + formsemestre: FormSemestre = None + formsemestre_id = int(formsemestre_id) + formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first() + filter["formsemestre"] = formsemestre + + # cas 6 : type + metric = request.args.get("metric", "all") + + return (metric, filter) + + +def filter_manager(request, assiduites): + """ + Retourne les assiduites entrées filtrées en fonction de la request + """ + # cas 1 : etat assiduite + etat = request.args.get("etat") + if etat is not None: + assiduites = scass.filter_by_etat(assiduites, etat) + + # cas 2 : date de début + deb = request.args.get("date_debut") + deb: datetime = scu.is_iso_formated(deb, True) + if deb is not None: + + assiduites = scass.filter_by_date(assiduites, deb, sup=True) + + # cas 3 : date de fin + fin = request.args.get("date_fin") + fin = scu.is_iso_formated(fin, True) + + if fin is not None: + assiduites = scass.filter_by_date(assiduites, fin, sup=False) + + # cas 4 : moduleimpl_id + module = request.args.get("moduleimpl_id", False) + try: + if module is False: + raise Exception + if module != "": + module = int(module) + else: + module = None + except Exception: + module = False + + if module is not False: + assiduites = scass.filter_by_module_impl(assiduites, module) + + # cas 5 : formsemestre_id + formsemestre_id = request.args.get("formsemestre_id") + + if formsemestre_id is not None: + formsemestre: FormSemestre = None + formsemestre_id = int(formsemestre_id) + formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first() + assiduites = scass.filter_by_formsemstre(assiduites, formsemestre) + + return assiduites diff --git a/app/scodoc/sco_assiduites.py b/app/scodoc/sco_assiduites.py index a3d8c4067..d1faf1844 100644 --- a/app/scodoc/sco_assiduites.py +++ b/app/scodoc/sco_assiduites.py @@ -7,11 +7,9 @@ from datetime import datetime, date, time, timedelta # TOTALK: Réfléchir sur le fractionnement d'une assiduite prolongée -def get_assiduite_stats( - etud: Identite, metric: str = "all", filter: dict[str, object] = {} +def get_assiduites_stats( + assiduites: Assiduite, metric: str = "all", filter: dict[str, object] = {} ) -> Assiduite: - assiduites: Assiduite = etud.assiduites - if filter != {}: for key in filter: if key == "etat":