forked from ScoDoc/ScoDoc
WIP: new API revue et corrigée (en cours)
This commit is contained in:
parent
455ce295d8
commit
ca1fe679db
@ -31,4 +31,3 @@ from app.api import evaluations
|
||||
from app.api import jury
|
||||
from app.api import absences
|
||||
from app.api import logos
|
||||
from app.api import debug
|
||||
|
@ -1,15 +1,22 @@
|
||||
#################################################### Absences #########################################################
|
||||
##############################################################################
|
||||
# ScoDoc
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
# See LICENSE
|
||||
##############################################################################
|
||||
"""ScoDoc 9 API : Absences
|
||||
"""
|
||||
|
||||
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.models import Identite, FormSemestre
|
||||
from app.models import Identite
|
||||
|
||||
from app.scodoc import notesdb as ndb
|
||||
from app.scodoc import sco_abs
|
||||
from app.scodoc.sco_abs import list_abs_date, annule_absence, annule_justif, add_abslist
|
||||
|
||||
# from app.scodoc.sco_abs import annule_absence, annule_justif, add_abslist
|
||||
from app.scodoc.sco_groups import get_group_members
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
@ -53,10 +60,10 @@ def absences(etudid: int = None):
|
||||
)
|
||||
# Absences de l'étudiant
|
||||
ndb.open_db_connection()
|
||||
absences = sco_abs.list_abs_date(etud.id)
|
||||
for absence in absences:
|
||||
abs_list = sco_abs.list_abs_date(etud.id)
|
||||
for absence in abs_list:
|
||||
absence["jour"] = absence["jour"].isoformat()
|
||||
return jsonify(absences)
|
||||
return jsonify(abs_list)
|
||||
|
||||
|
||||
@bp.route("/absences/etudid/<int:etudid>/just", methods=["GET"])
|
||||
@ -158,9 +165,6 @@ def abs_groupe_etat(group_id: int, date_debut=None, date_fin=None):
|
||||
...
|
||||
]
|
||||
"""
|
||||
# Fonction utilisée : app.scodoc.sco_groups.get_group_members() et app.scodoc.sco_abs.list_abs_date()
|
||||
|
||||
# Utilisation de la fonction get_group_members
|
||||
members = get_group_members(group_id)
|
||||
|
||||
data = []
|
||||
@ -175,88 +179,89 @@ def abs_groupe_etat(group_id: int, date_debut=None, date_fin=None):
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@bp.route(
|
||||
"/absences/etudid/<int:etudid>/list_abs/<string:list_abs>/reset_etud_abs",
|
||||
methods=["POST"],
|
||||
defaults={"just_or_not": 0},
|
||||
)
|
||||
@bp.route(
|
||||
"/absences/etudid/<int:etudid>/list_abs/<string:list_abs>/reset_etud_abs/only_not_just",
|
||||
methods=["POST"],
|
||||
defaults={"just_or_not": 1},
|
||||
)
|
||||
@bp.route(
|
||||
"/absences/etudid/<int:etudid>/list_abs/<string:list_abs>/reset_etud_abs/only_just",
|
||||
methods=["POST"],
|
||||
defaults={"just_or_not": 2},
|
||||
)
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIAbsChange)
|
||||
def reset_etud_abs(etudid: int, list_abs, just_or_not: int = 0):
|
||||
"""
|
||||
Set la liste des absences d'un étudiant sur tout un semestre.
|
||||
(les absences existant pour cet étudiant sur cette période sont effacées)
|
||||
# XXX TODO EV: A REVOIR (data json dans le POST + modifier les routes)
|
||||
# @bp.route(
|
||||
# "/absences/etudid/<int:etudid>/list_abs/<string:list_abs>/reset_etud_abs",
|
||||
# methods=["POST"],
|
||||
# defaults={"just_or_not": 0},
|
||||
# )
|
||||
# @bp.route(
|
||||
# "/absences/etudid/<int:etudid>/list_abs/<string:list_abs>/reset_etud_abs/only_not_just",
|
||||
# methods=["POST"],
|
||||
# defaults={"just_or_not": 1},
|
||||
# )
|
||||
# @bp.route(
|
||||
# "/absences/etudid/<int:etudid>/list_abs/<string:list_abs>/reset_etud_abs/only_just",
|
||||
# methods=["POST"],
|
||||
# defaults={"just_or_not": 2},
|
||||
# )
|
||||
# @token_auth.login_required
|
||||
# @token_permission_required(Permission.APIAbsChange)
|
||||
# def reset_etud_abs(etudid: int, list_abs: str, just_or_not: int = 0):
|
||||
# """
|
||||
# Set la liste des absences d'un étudiant sur tout un semestre.
|
||||
# (les absences existant pour cet étudiant sur cette période sont effacées)
|
||||
|
||||
etudid : l'id d'un étudiant
|
||||
list_abs : json d'absences
|
||||
just_or_not : 0 (pour les absences justifiées et non justifiées),
|
||||
1 (pour les absences justifiées),
|
||||
2 (pour les absences non justifiées)
|
||||
"""
|
||||
# Toutes les absences
|
||||
if just_or_not == 0:
|
||||
# suppression des absences et justificatif déjà existant pour éviter les doublons
|
||||
for abs in list_abs:
|
||||
# Récupération de la date au format iso
|
||||
jour = abs["jour"].isoformat()
|
||||
if abs["matin"] is True:
|
||||
annule_absence(etudid, jour, True)
|
||||
annule_justif(etudid, jour, True)
|
||||
else:
|
||||
annule_absence(etudid, jour, False)
|
||||
annule_justif(etudid, jour, False)
|
||||
# etudid : l'id d'un étudiant
|
||||
# list_abs : json d'absences
|
||||
# just_or_not : 0 (pour les absences justifiées et non justifiées),
|
||||
# 1 (pour les absences justifiées),
|
||||
# 2 (pour les absences non justifiées)
|
||||
# """
|
||||
# # Toutes les absences
|
||||
# if just_or_not == 0:
|
||||
# # suppression des absences et justificatif déjà existant pour éviter les doublons
|
||||
# for abs in list_abs:
|
||||
# # Récupération de la date au format iso
|
||||
# jour = abs["jour"].isoformat()
|
||||
# if abs["matin"] is True:
|
||||
# annule_absence(etudid, jour, True)
|
||||
# annule_justif(etudid, jour, True)
|
||||
# else:
|
||||
# annule_absence(etudid, jour, False)
|
||||
# annule_justif(etudid, jour, False)
|
||||
|
||||
# Ajout de la liste d'absences en base
|
||||
add_abslist(list_abs)
|
||||
# # Ajout de la liste d'absences en base
|
||||
# add_abslist(list_abs)
|
||||
|
||||
# Uniquement les absences justifiées
|
||||
elif just_or_not == 1:
|
||||
list_abs_not_just = []
|
||||
# Trie des absences justifiées
|
||||
for abs in list_abs:
|
||||
if abs["estjust"] is False:
|
||||
list_abs_not_just.append(abs)
|
||||
# suppression des absences et justificatif déjà existant pour éviter les doublons
|
||||
for abs in list_abs:
|
||||
# Récupération de la date au format iso
|
||||
jour = abs["jour"].isoformat()
|
||||
if abs["matin"] is True:
|
||||
annule_absence(etudid, jour, True)
|
||||
annule_justif(etudid, jour, True)
|
||||
else:
|
||||
annule_absence(etudid, jour, False)
|
||||
annule_justif(etudid, jour, False)
|
||||
# # Uniquement les absences justifiées
|
||||
# elif just_or_not == 1:
|
||||
# list_abs_not_just = []
|
||||
# # Trie des absences justifiées
|
||||
# for abs in list_abs:
|
||||
# if abs["estjust"] is False:
|
||||
# list_abs_not_just.append(abs)
|
||||
# # suppression des absences et justificatif déjà existant pour éviter les doublons
|
||||
# for abs in list_abs:
|
||||
# # Récupération de la date au format iso
|
||||
# jour = abs["jour"].isoformat()
|
||||
# if abs["matin"] is True:
|
||||
# annule_absence(etudid, jour, True)
|
||||
# annule_justif(etudid, jour, True)
|
||||
# else:
|
||||
# annule_absence(etudid, jour, False)
|
||||
# annule_justif(etudid, jour, False)
|
||||
|
||||
# Ajout de la liste d'absences en base
|
||||
add_abslist(list_abs_not_just)
|
||||
# # Ajout de la liste d'absences en base
|
||||
# add_abslist(list_abs_not_just)
|
||||
|
||||
# Uniquement les absences non justifiées
|
||||
elif just_or_not == 2:
|
||||
list_abs_just = []
|
||||
# Trie des absences non justifiées
|
||||
for abs in list_abs:
|
||||
if abs["estjust"] is True:
|
||||
list_abs_just.append(abs)
|
||||
# suppression des absences et justificatif déjà existant pour éviter les doublons
|
||||
for abs in list_abs:
|
||||
# Récupération de la date au format iso
|
||||
jour = abs["jour"].isoformat()
|
||||
if abs["matin"] is True:
|
||||
annule_absence(etudid, jour, True)
|
||||
annule_justif(etudid, jour, True)
|
||||
else:
|
||||
annule_absence(etudid, jour, False)
|
||||
annule_justif(etudid, jour, False)
|
||||
# # Uniquement les absences non justifiées
|
||||
# elif just_or_not == 2:
|
||||
# list_abs_just = []
|
||||
# # Trie des absences non justifiées
|
||||
# for abs in list_abs:
|
||||
# if abs["estjust"] is True:
|
||||
# list_abs_just.append(abs)
|
||||
# # suppression des absences et justificatif déjà existant pour éviter les doublons
|
||||
# for abs in list_abs:
|
||||
# # Récupération de la date au format iso
|
||||
# jour = abs["jour"].isoformat()
|
||||
# if abs["matin"] is True:
|
||||
# annule_absence(etudid, jour, True)
|
||||
# annule_justif(etudid, jour, True)
|
||||
# else:
|
||||
# annule_absence(etudid, jour, False)
|
||||
# annule_justif(etudid, jour, False)
|
||||
|
||||
# Ajout de la liste d'absences en base
|
||||
add_abslist(list_abs_just)
|
||||
# # Ajout de la liste d'absences en base
|
||||
# add_abslist(list_abs_just)
|
||||
|
@ -1,31 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gestion scolarite IUT
|
||||
#
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Emmanuel Viennet emmanuel.viennet@viennet.net
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
!!! ATTENTION !!!
|
||||
Fichier a utilisé uniquement à des fins de debug
|
||||
"""
|
@ -14,12 +14,13 @@ import app
|
||||
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_last_instance_etud_from_etudid_or_nip_or_ine
|
||||
from app.api import tools
|
||||
from app.models import Departement, 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_permissions import Permission
|
||||
from app.scodoc import sco_utils as scu
|
||||
|
||||
|
||||
@bp.route("/etudiants/courants", defaults={"long": False})
|
||||
@ -106,7 +107,7 @@ def etudiant(etudid: int = None, nip: str = None, ine: str = None):
|
||||
"description": ""
|
||||
}
|
||||
"""
|
||||
etud = get_last_instance_etud_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||
etud = tools.get_etud(etudid, nip, ine)
|
||||
|
||||
if etud is None:
|
||||
return error_response(
|
||||
@ -153,36 +154,39 @@ def etudiants(etudid: int = None, nip: str = None, ine: str = None):
|
||||
def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None):
|
||||
"""
|
||||
Liste des semestres qu'un étudiant a suivi, triés par ordre chronologique.
|
||||
Attention, si accès via NIP ou INE, les semestres peuvent être de départements différents
|
||||
(si l'étudiant a changé de département). L'id du département est `dept_id`.
|
||||
|
||||
Accès par etudid, nip ou ine
|
||||
|
||||
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,
|
||||
"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",
|
||||
"resp_can_change_ens": true,
|
||||
"resp_can_edit": false,
|
||||
"responsables": []
|
||||
"scodoc7_id": null,
|
||||
"semestre_id": 1,
|
||||
"titre_num": "Semestre test semestre 1",
|
||||
"titre": "Semestre test",
|
||||
},
|
||||
...
|
||||
]
|
||||
@ -263,22 +267,21 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None)
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "pdf": False},
|
||||
)
|
||||
# Version PDF non fonctionnelle
|
||||
# @bp.route(
|
||||
# "/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
# methods=["GET"],
|
||||
# defaults={"version": "short", "pdf": True},
|
||||
# )
|
||||
# @bp.route(
|
||||
# "/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
# methods=["GET"],
|
||||
# defaults={"version": "short", "pdf": True},
|
||||
# )
|
||||
# @bp.route(
|
||||
# "/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
# methods=["GET"],
|
||||
# defaults={"version": "short", "pdf": True},
|
||||
# )
|
||||
@bp.route(
|
||||
"/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "pdf": True},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "pdf": True},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/bulletin/short/pdf",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short", "pdf": True},
|
||||
)
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def etudiant_bulletin_semestre( # XXX TODO Ajouter la possibilité de retourner en version pdf
|
||||
@ -296,150 +299,8 @@ def etudiant_bulletin_semestre( # XXX TODO Ajouter la possibilité de retourner
|
||||
etudid : l'etudid d'un étudiant
|
||||
nip : le code nip d'un étudiant
|
||||
ine : le code ine d'un étudiant
|
||||
Exemple de résultat :
|
||||
{
|
||||
"version": "0",
|
||||
"type": "BUT",
|
||||
"date": "2022-04-27T07:18:16.450634Z",
|
||||
"publie": true,
|
||||
"etudiant": {
|
||||
"civilite": "X",
|
||||
"code_ine": "1",
|
||||
"code_nip": "1",
|
||||
"date_naissance": "",
|
||||
"email": "SACHA.COSTA@example.com",
|
||||
"emailperso": "",
|
||||
"etudid": 1,
|
||||
"nom": "COSTA",
|
||||
"prenom": "SACHA",
|
||||
"nomprenom": "Sacha COSTA",
|
||||
"lieu_naissance": "",
|
||||
"dept_naissance": "",
|
||||
"nationalite": "",
|
||||
"boursier": "",
|
||||
"fiche_url": "/ScoDoc/TAPI/Scolarite/ficheEtud?etudid=1",
|
||||
"photo_url": "/ScoDoc/TAPI/Scolarite/get_photo_image?etudid=1&size=small",
|
||||
"id": 1,
|
||||
"codepostaldomicile": "",
|
||||
"paysdomicile": "",
|
||||
"telephonemobile": "",
|
||||
"typeadresse": "domicile",
|
||||
"domicile": "",
|
||||
"villedomicile": "",
|
||||
"telephone": "",
|
||||
"fax": "",
|
||||
"description": "",
|
||||
},
|
||||
"formation": {
|
||||
"id": 1,
|
||||
"acronyme": "BUT R&T",
|
||||
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
|
||||
"titre": "BUT R&T",
|
||||
},
|
||||
"formsemestre_id": 1,
|
||||
"etat_inscription": "I",
|
||||
"options": {
|
||||
"show_abs": true,
|
||||
"show_abs_modules": false,
|
||||
"show_ects": true,
|
||||
"show_codemodules": false,
|
||||
"show_matieres": false,
|
||||
"show_rangs": true,
|
||||
"show_ue_rangs": true,
|
||||
"show_mod_rangs": true,
|
||||
"show_moypromo": false,
|
||||
"show_minmax": false,
|
||||
"show_minmax_mod": false,
|
||||
"show_minmax_eval": false,
|
||||
"show_coef": true,
|
||||
"show_ue_cap_details": false,
|
||||
"show_ue_cap_current": true,
|
||||
"show_temporary": true,
|
||||
"temporary_txt": "Provisoire",
|
||||
"show_uevalid": true,
|
||||
"show_date_inscr": true,
|
||||
},
|
||||
"ressources": {
|
||||
"R101": {
|
||||
"id": 1,
|
||||
"titre": "Initiation aux r\u00e9seaux informatiques",
|
||||
"code_apogee": null,
|
||||
"url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=1",
|
||||
"moyenne": {},
|
||||
"evaluations": [
|
||||
{
|
||||
"id": 1,
|
||||
"description": "eval1",
|
||||
"date": "2022-04-20",
|
||||
"heure_debut": "08:00",
|
||||
"heure_fin": "09:00",
|
||||
"coef": "01.00",
|
||||
"poids": {
|
||||
"RT1.1": 1.0,
|
||||
},
|
||||
"note": {
|
||||
"value": "12.00",
|
||||
"min": "00.00",
|
||||
"max": "18.00",
|
||||
"moy": "10.88",
|
||||
},
|
||||
"url": "/ScoDoc/TAPI/Scolarite/Notes/evaluation_listenotes?evaluation_id=1",
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
"saes": {
|
||||
"SAE11": {
|
||||
"id": 2,
|
||||
"titre": "Se sensibiliser \u00e0 l'hygi\u00e8ne informatique et \u00e0 la cybers\u00e9curit\u00e9",
|
||||
"code_apogee": null,
|
||||
"url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=2",
|
||||
"moyenne": {},
|
||||
"evaluations": [],
|
||||
},
|
||||
},
|
||||
"ues": {
|
||||
"RT1.1": {
|
||||
"id": 1,
|
||||
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||
"numero": 1,
|
||||
"type": 0,
|
||||
"color": "#B80004",
|
||||
"competence": null,
|
||||
"moyenne": {
|
||||
"value": "08.50",
|
||||
"min": "06.00",
|
||||
"max": "16.50",
|
||||
"moy": "11.31",
|
||||
"rang": "12",
|
||||
"total": 16,
|
||||
},
|
||||
"bonus": "00.00",
|
||||
"malus": "00.00",
|
||||
"capitalise": null,
|
||||
"ressources": {
|
||||
"R101": {"id": 1, "coef": 12.0, "moyenne": "12.00"},
|
||||
},
|
||||
"saes": {
|
||||
"SAE11": {"id": 2, "coef": 16.0, "moyenne": "~"},
|
||||
},
|
||||
"ECTS": {"acquis": 0.0, "total": 12.0},
|
||||
},
|
||||
"semestre": {
|
||||
"etapes": [],
|
||||
"date_debut": "2021-09-01",
|
||||
"date_fin": "2022-08-31",
|
||||
"annee_universitaire": "2021 - 2022",
|
||||
"numero": 1,
|
||||
"inscription": "",
|
||||
"groupes": [],
|
||||
"absences": {"injustifie": 1, "total": 2},
|
||||
"ECTS": {"acquis": 0, "total": 30.0},
|
||||
"notes": {"value": "10.60", "min": "02.40", "moy": "11.05", "max": "17.40"},
|
||||
"rang": {"value": "10", "total": 16},
|
||||
},
|
||||
},
|
||||
}
|
||||
Exemple de résultat : voir https://scodoc.org/ScoDoc9API/#bulletin
|
||||
|
||||
"""
|
||||
formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first_or_404()
|
||||
dept = Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
||||
@ -466,11 +327,10 @@ def etudiant_bulletin_semestre( # XXX TODO Ajouter la possibilité de retourner
|
||||
app.set_sco_dept(dept.acronym)
|
||||
|
||||
if pdf:
|
||||
response = make_response(
|
||||
do_formsemestre_bulletinetud(formsemestre, etudid, version, "pdf")
|
||||
pdf_response, _ = do_formsemestre_bulletinetud(
|
||||
formsemestre, etudid, version=version, format="pdf"
|
||||
)
|
||||
response.headers["Content-Type"] = "application/json"
|
||||
return response
|
||||
return pdf_response
|
||||
|
||||
return sco_bulletins.get_formsemestre_bulletin_etud_json(
|
||||
formsemestre, etud, version=version
|
||||
|
@ -1,10 +1,18 @@
|
||||
############################################### Evaluations ###########################################################
|
||||
##############################################################################
|
||||
# ScoDoc
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
# See LICENSE
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
ScoDoc 9 API : accès aux évaluations
|
||||
"""
|
||||
|
||||
from flask import jsonify
|
||||
|
||||
import app
|
||||
|
||||
from app import models
|
||||
from app.models import Evaluation
|
||||
from app.api import bp
|
||||
from app.api.auth import token_auth, token_permission_required
|
||||
from app.api.errors import error_response
|
||||
@ -18,7 +26,7 @@ from app.scodoc.sco_permissions import Permission
|
||||
@token_permission_required(Permission.APIView)
|
||||
def evaluations(moduleimpl_id: int):
|
||||
"""
|
||||
Retourne la liste des évaluations à partir de l'id d'un moduleimpl
|
||||
Retourne la liste des évaluations d'un moduleimpl
|
||||
|
||||
moduleimpl_id : l'id d'un moduleimpl
|
||||
|
||||
@ -40,7 +48,7 @@ def evaluations(moduleimpl_id: int):
|
||||
"evaluation_id": 1,
|
||||
"jouriso": "2022-04-20",
|
||||
"duree": "1h",
|
||||
"descrheure": " de 08h00 \u00e0 09h00",
|
||||
"descrheure": " de 08h00 à 09h00",
|
||||
"matin": 1,
|
||||
"apresmidi": 0
|
||||
},
|
||||
@ -88,16 +96,11 @@ def evaluation_notes(evaluation_id: int):
|
||||
...
|
||||
}
|
||||
"""
|
||||
# Fonction utilisée : app.scodoc.sco_evaluation_db.do_evaluation_get_all_notes()
|
||||
|
||||
evaluation = models.Evaluation.query.filter_by(id=evaluation_id).first_or_404()
|
||||
dept = models.Departement.query.filter_by(
|
||||
id=evaluation.moduleimpl.formsemestre.dept_id
|
||||
).first()
|
||||
dept = evaluation.moduleimpl.formsemestre.departement
|
||||
app.set_sco_dept(dept.acronym)
|
||||
|
||||
try:
|
||||
# Utilisation de la fonction do_evaluation_get_all_notes
|
||||
data = do_evaluation_get_all_notes(evaluation_id)
|
||||
except AttributeError: # ???
|
||||
return error_response(
|
||||
|
@ -1,4 +1,13 @@
|
||||
##############################################" Formations ############################################################
|
||||
##############################################################################
|
||||
# ScoDoc
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
# See LICENSE
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
ScoDoc 9 API : accès aux formations
|
||||
"""
|
||||
|
||||
from flask import jsonify
|
||||
|
||||
import app
|
||||
@ -10,6 +19,7 @@ from app.models.formations import Formation
|
||||
from app.scodoc import sco_formations
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
|
||||
@bp.route("/formations", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
@ -17,16 +27,11 @@ def formations():
|
||||
"""
|
||||
Retourne la liste de toutes les formations (tous départements)
|
||||
|
||||
Exemple de résultat :
|
||||
"""
|
||||
# Récupération de toutes les formations
|
||||
list_formations = models.Formation.query.all()
|
||||
|
||||
# Mise en forme des données
|
||||
data = [d.to_dict() for d in list_formations]
|
||||
|
||||
data = [d.to_dict() for d in models.Formation.query]
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@bp.route("/formations_ids", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
@ -36,12 +41,7 @@ def formations_ids():
|
||||
|
||||
Exemple de résultat : [ 17, 99, 32 ]
|
||||
"""
|
||||
# Récupération de toutes les formations
|
||||
list_formations = models.Formation.query.all()
|
||||
|
||||
# Mise en forme des données
|
||||
data = [d.id for d in list_formations]
|
||||
|
||||
data = [d.id for d in models.Formation.query]
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ def formations_ids():
|
||||
@token_permission_required(Permission.APIView)
|
||||
def formation_by_id(formation_id: int):
|
||||
"""
|
||||
Retourne une formation en fonction d'un id donné
|
||||
La formation d'id donné
|
||||
|
||||
formation_id : l'id d'une formation
|
||||
|
||||
@ -58,7 +58,7 @@ def formation_by_id(formation_id: int):
|
||||
{
|
||||
"id": 1,
|
||||
"acronyme": "BUT R&T",
|
||||
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
|
||||
"titre_officiel": "Bachelor technologique réseaux et télécommunications",
|
||||
"formation_code": "V1RET",
|
||||
"code_specialite": null,
|
||||
"dept_id": 1,
|
||||
@ -69,13 +69,8 @@ def formation_by_id(formation_id: int):
|
||||
"formation_id": 1
|
||||
}
|
||||
"""
|
||||
# Récupération de la formation
|
||||
formation = models.Formation.query.filter_by(id=formation_id).first_or_404()
|
||||
|
||||
# Mise en forme des données
|
||||
data = formation.to_dict()
|
||||
|
||||
return jsonify(data)
|
||||
formation = models.Formation.query.get_or_404(formation_id)
|
||||
return jsonify(formation.to_dict())
|
||||
|
||||
|
||||
@bp.route(
|
||||
@ -187,10 +182,8 @@ def formation_export_by_formation_id(formation_id: int, export_ids=False):
|
||||
}
|
||||
"""
|
||||
formation = Formation.query.get_or_404(formation_id)
|
||||
dept = models.Departement.query.filter_by(id=formation.dept_id).first()
|
||||
app.set_sco_dept(dept.acronym)
|
||||
app.set_sco_dept(formation.departement.acronym)
|
||||
try:
|
||||
# Utilisation de la fonction formation_export
|
||||
data = sco_formations.formation_export(formation_id, export_ids)
|
||||
except ValueError:
|
||||
return error_response(500, message="Erreur inconnue")
|
||||
@ -236,9 +229,8 @@ def moduleimpl(moduleimpl_id: int):
|
||||
}
|
||||
}
|
||||
"""
|
||||
modimpl = models.ModuleImpl.query.filter_by(id=moduleimpl_id).first_or_404()
|
||||
data = modimpl.to_dict()
|
||||
return jsonify(data)
|
||||
modimpl = models.ModuleImpl.query.get_or_404(moduleimpl_id)
|
||||
return jsonify(modimpl.to_dict())
|
||||
|
||||
|
||||
@bp.route(
|
||||
@ -253,10 +245,9 @@ def referentiel_competences(formation_id: int):
|
||||
|
||||
formation_id : l'id d'une formation
|
||||
|
||||
return json, ou null si pas de référentiel associé.
|
||||
return null si pas de référentiel associé.
|
||||
"""
|
||||
formation = models.Formation.query.filter_by(id=formation_id).first_or_404()
|
||||
|
||||
formation = models.Formation.query.get_or_404(formation_id)
|
||||
if formation.referentiel_competence is None:
|
||||
return jsonify(None)
|
||||
return jsonify(formation.referentiel_competence.to_dict())
|
||||
|
@ -1,5 +1,12 @@
|
||||
########################################## Formsemestres ##############################################################
|
||||
import statistics
|
||||
##############################################################################
|
||||
# ScoDoc
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
# See LICENSE
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
ScoDoc 9 API : accès aux formsemestres
|
||||
"""
|
||||
|
||||
from flask import jsonify
|
||||
|
||||
@ -7,11 +14,10 @@ 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.comp import res_sem
|
||||
from app.comp.moy_mod import ModuleImplResults
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models import Departement, FormSemestre, FormSemestreEtape, ModuleImpl
|
||||
from app.models import Evaluation, FormSemestre, FormSemestreEtape, ModuleImpl
|
||||
from app.scodoc.sco_bulletins import get_formsemestre_bulletin_etud_json
|
||||
from app.scodoc.sco_groups import get_etud_groups
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
@ -22,7 +28,7 @@ import app.scodoc.sco_utils as scu
|
||||
@bp.route("/formsemestre/<int:formsemestre_id>", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def formsemestre(formsemestre_id: int):
|
||||
def formsemestre_infos(formsemestre_id: int):
|
||||
"""
|
||||
Information sur le formsemestre indiqué.
|
||||
|
||||
@ -59,17 +65,8 @@ def formsemestre(formsemestre_id: int):
|
||||
}
|
||||
|
||||
"""
|
||||
formsemestre: FormSemestre = models.FormSemestre.query.filter_by(
|
||||
id=formsemestre_id
|
||||
).first_or_404()
|
||||
data = formsemestre.to_dict(convert_parcours=True)
|
||||
# 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["annee_scolaire"] = formsemestre.annee_scolaire_str()
|
||||
data["session_id"] = formsemestre.session_id()
|
||||
return jsonify(data)
|
||||
formsemestre: FormSemestre = models.FormSemestre.query.get_or_404(formsemestre_id)
|
||||
return jsonify(formsemestre.to_dict_api())
|
||||
|
||||
|
||||
@bp.route("/formsemestre/apo/<string:etape_apo>", methods=["GET"])
|
||||
@ -92,9 +89,7 @@ def formsemestre_apo(etape_apo: str):
|
||||
FormSemestreEtape.formsemestre_id == FormSemestre.id,
|
||||
)
|
||||
|
||||
return jsonify(
|
||||
[formsemestre.to_dict(convert_parcours=True) for formsemestre in formsemestres]
|
||||
)
|
||||
return jsonify([formsemestre.to_dict_api() for formsemestre in formsemestres])
|
||||
|
||||
|
||||
@bp.route("/formsemestre/<int:formsemestre_id>/bulletins", methods=["GET"])
|
||||
@ -106,183 +101,10 @@ def bulletins(formsemestre_id: int):
|
||||
|
||||
formsemestre_id : l'id d'un formesemestre
|
||||
|
||||
Exemple de résultat :
|
||||
[
|
||||
{
|
||||
"version": "0",
|
||||
"type": "BUT",
|
||||
"date": "2022-04-27T07:18:16.450634Z",
|
||||
"publie": true,
|
||||
"etudiant": {
|
||||
"civilite": "X",
|
||||
"code_ine": "1",
|
||||
"code_nip": "1",
|
||||
"date_naissance": "",
|
||||
"email": "SACHA.COSTA@example.com",
|
||||
"emailperso": "",
|
||||
"etudid": 1,
|
||||
"nom": "COSTA",
|
||||
"prenom": "SACHA",
|
||||
"nomprenom": "Sacha COSTA",
|
||||
"lieu_naissance": "",
|
||||
"dept_naissance": "",
|
||||
"nationalite": "",
|
||||
"boursier": "",
|
||||
"fiche_url": "/ScoDoc/TAPI/Scolarite/ficheEtud?etudid=1",
|
||||
"photo_url": "/ScoDoc/TAPI/Scolarite/get_photo_image?etudid=1&size=small",
|
||||
"id": 1,
|
||||
"codepostaldomicile": "",
|
||||
"paysdomicile": "",
|
||||
"telephonemobile": "",
|
||||
"typeadresse": "domicile",
|
||||
"domicile": "",
|
||||
"villedomicile": "",
|
||||
"telephone": "",
|
||||
"fax": "",
|
||||
"description": ""
|
||||
},
|
||||
"formation": {
|
||||
"id": 1,
|
||||
"acronyme": "BUT R&T",
|
||||
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
|
||||
"titre": "BUT R&T"
|
||||
},
|
||||
"formsemestre_id": 1,
|
||||
"etat_inscription": "I",
|
||||
"options": {
|
||||
"show_abs": true,
|
||||
"show_abs_modules": false,
|
||||
"show_ects": true,
|
||||
"show_codemodules": false,
|
||||
"show_matieres": false,
|
||||
"show_rangs": true,
|
||||
"show_ue_rangs": true,
|
||||
"show_mod_rangs": true,
|
||||
"show_moypromo": false,
|
||||
"show_minmax": false,
|
||||
"show_minmax_mod": false,
|
||||
"show_minmax_eval": false,
|
||||
"show_coef": true,
|
||||
"show_ue_cap_details": false,
|
||||
"show_ue_cap_current": true,
|
||||
"show_temporary": true,
|
||||
"temporary_txt": "Provisoire",
|
||||
"show_uevalid": true,
|
||||
"show_date_inscr": true
|
||||
},
|
||||
"ressources": {
|
||||
"R101": {
|
||||
"id": 1,
|
||||
"titre": "Initiation aux r\u00e9seaux informatiques",
|
||||
"code_apogee": null,
|
||||
"url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=1",
|
||||
"moyenne": {},
|
||||
"evaluations": [
|
||||
{
|
||||
"id": 1,
|
||||
"description": "eval1",
|
||||
"date": "2022-04-20",
|
||||
"heure_debut": "08:00",
|
||||
"heure_fin": "09:00",
|
||||
"coef": "01.00",
|
||||
"poids": {
|
||||
"RT1.1": 1.0,
|
||||
},
|
||||
"note": {
|
||||
"value": "12.00",
|
||||
"min": "00.00",
|
||||
"max": "18.00",
|
||||
"moy": "10.88"
|
||||
},
|
||||
"url": "/ScoDoc/TAPI/Scolarite/Notes/evaluation_listenotes?evaluation_id=1"
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
"saes": {
|
||||
"SAE11": {
|
||||
"id": 2,
|
||||
"titre": "Se sensibiliser \u00e0 l'hygi\u00e8ne informatique et \u00e0 la cybers\u00e9curit\u00e9",
|
||||
"code_apogee": null,
|
||||
"url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=2",
|
||||
"moyenne": {},
|
||||
"evaluations": []
|
||||
},
|
||||
},
|
||||
"ues": {
|
||||
"RT1.1": {
|
||||
"id": 1,
|
||||
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||
"numero": 1,
|
||||
"type": 0,
|
||||
"color": "#B80004",
|
||||
"competence": null,
|
||||
"moyenne": {
|
||||
"value": "08.50",
|
||||
"min": "06.00",
|
||||
"max": "16.50",
|
||||
"moy": "11.31",
|
||||
"rang": "12",
|
||||
"total": 16
|
||||
},
|
||||
"bonus": "00.00",
|
||||
"malus": "00.00",
|
||||
"capitalise": null,
|
||||
"ressources": {
|
||||
"R101": {
|
||||
"id": 1,
|
||||
"coef": 12.0,
|
||||
"moyenne": "12.00"
|
||||
},
|
||||
},
|
||||
"saes": {
|
||||
"SAE11": {
|
||||
"id": 2,
|
||||
"coef": 16.0,
|
||||
"moyenne": "~"
|
||||
},
|
||||
},
|
||||
"ECTS": {
|
||||
"acquis": 0.0,
|
||||
"total": 12.0
|
||||
}
|
||||
},
|
||||
"semestre": {
|
||||
"etapes": [],
|
||||
"date_debut": "2021-09-01",
|
||||
"date_fin": "2022-08-31",
|
||||
"annee_universitaire": "2021 - 2022",
|
||||
"numero": 1,
|
||||
"inscription": "",
|
||||
"groupes": [],
|
||||
"absences": {
|
||||
"injustifie": 1,
|
||||
"total": 2
|
||||
},
|
||||
"ECTS": {
|
||||
"acquis": 0,
|
||||
"total": 30.0
|
||||
},
|
||||
"notes": {
|
||||
"value": "10.60",
|
||||
"min": "02.40",
|
||||
"moy": "11.05",
|
||||
"max": "17.40"
|
||||
},
|
||||
"rang": {
|
||||
"value": "10",
|
||||
"total": 16
|
||||
}
|
||||
}
|
||||
},
|
||||
...
|
||||
]
|
||||
Exemple de résultat : liste, voir https://scodoc.org/ScoDoc9API/#bulletin
|
||||
"""
|
||||
formsemestre = models.FormSemestre.query.filter_by(
|
||||
id=formsemestre_id
|
||||
).first_or_404()
|
||||
dept = models.Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
||||
app.set_sco_dept(dept.acronym)
|
||||
formsemestre = models.FormSemestre.query.get_or_404(formsemestre_id)
|
||||
app.set_sco_dept(formsemestre.departement.acronym)
|
||||
|
||||
data = []
|
||||
for etu in formsemestre.etuds:
|
||||
@ -292,44 +114,6 @@ def bulletins(formsemestre_id: int):
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
# XXX Attendre ScoDoc 9.3
|
||||
# @bp.route("/formsemestre/<int:formsemestre_id>/jury", methods=["GET"])
|
||||
# @token_auth.login_required
|
||||
# @token_permission_required(Permission.APIView)
|
||||
# def jury(formsemestre_id: int):
|
||||
# """
|
||||
# Retourne le récapitulatif des décisions jury
|
||||
|
||||
# formsemestre_id : l'id d'un formsemestre
|
||||
|
||||
# Exemple de résultat :
|
||||
|
||||
# """
|
||||
# # Fonction utilisée : app.scodoc.sco_pvjury.formsemestre_pvjury()
|
||||
|
||||
# formsemestre = models.FormSemestre.query.filter_by(
|
||||
# id=formsemestre_id
|
||||
# ).first_or_404()
|
||||
|
||||
# dept = models.Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
||||
|
||||
# app.set_sco_dept(dept.acronym)
|
||||
|
||||
# data = formsemestre_pvjury(formsemestre_id)
|
||||
|
||||
# # try:
|
||||
# # # Utilisation de la fonction formsemestre_pvjury
|
||||
# # data = formsemestre_pvjury(formsemestre_id)
|
||||
# # except AttributeError:
|
||||
# # 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 jsonify(data)
|
||||
|
||||
|
||||
@bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/programme",
|
||||
methods=["GET"],
|
||||
@ -401,10 +185,7 @@ def formsemestre_programme(formsemestre_id: int):
|
||||
"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()
|
||||
|
||||
formsemestre: FormSemestre = models.FormSemestre.query.get_or_404(formsemestre_id)
|
||||
ues = formsemestre.query_ues()
|
||||
m_list = {
|
||||
ModuleType.RESSOURCE: [],
|
||||
@ -428,48 +209,37 @@ def formsemestre_programme(formsemestre_id: int):
|
||||
@bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/etudiants",
|
||||
methods=["GET"],
|
||||
defaults={"etat": "I"},
|
||||
defaults={"etat": scu.INSCRIT},
|
||||
)
|
||||
@bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/etudiants/demissionnaires",
|
||||
methods=["GET"],
|
||||
defaults={"etat": "D"},
|
||||
defaults={"etat": scu.DEMISSION},
|
||||
)
|
||||
@bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/etudiants/defaillants",
|
||||
methods=["GET"],
|
||||
defaults={"etat": "DEF"},
|
||||
defaults={"etat": scu.DEF},
|
||||
)
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def formsemestre_etudiants(formsemestre_id: int, etat: str):
|
||||
"""
|
||||
Retourne la liste des étudiants d'un semestre
|
||||
Retourne la liste des étudiants d'un formsemestre
|
||||
|
||||
formsemestre_id : l'id d'un semestre
|
||||
formsemestre_id : l'id d'un formsemestre
|
||||
"""
|
||||
# fonction to use : sco_groups.get_etud_groups
|
||||
|
||||
formsemestre = models.FormSemestre.query.filter_by(
|
||||
formsemestre: FormSemestre = models.FormSemestre.query.filter_by(
|
||||
id=formsemestre_id
|
||||
).first_or_404()
|
||||
|
||||
# Récupération des étudiants du formsemestre
|
||||
etuds = [etu.to_dict_short() for etu in formsemestre.etuds]
|
||||
inscriptions = [ins for ins in formsemestre.inscriptions if ins.etat == etat]
|
||||
etuds = [ins.etud.to_dict_short() for ins in inscriptions]
|
||||
# Ajout des groupes de chaque étudiants
|
||||
for etud in etuds:
|
||||
etud["groups"] = get_etud_groups(etud["id"], formsemestre_id)
|
||||
|
||||
res = []
|
||||
# Trie des étudiants suivant leur état d'inscription voulu
|
||||
for etu in etuds:
|
||||
formsemestre_inscription = models.FormSemestreInscription.query.filter_by(
|
||||
formsemestre_id=formsemestre_id, etudid=etu["id"]
|
||||
).first_or_404()
|
||||
if formsemestre_inscription.etat == etat:
|
||||
res.append(etu)
|
||||
# Ajout des groups de chaques étudiants
|
||||
for etu in res:
|
||||
etu["groups"] = get_etud_groups(etu["id"], formsemestre_id)
|
||||
|
||||
return jsonify(res)
|
||||
return jsonify(etuds)
|
||||
|
||||
|
||||
@bp.route("/formsemestre/<int:formsemestre_id>/etat_evals", methods=["GET"])
|
||||
@ -477,15 +247,14 @@ def formsemestre_etudiants(formsemestre_id: int, etat: str):
|
||||
@token_permission_required(Permission.APIView)
|
||||
def etat_evals(formsemestre_id: int):
|
||||
"""
|
||||
Retourne les informations sur l'état des évaluations d'un semestre donnée
|
||||
Informations sur l'état des évaluations d'un formsemestre.
|
||||
|
||||
formsemestre_id : l'id d'un semestre
|
||||
|
||||
Exemple de résultat :
|
||||
[
|
||||
{
|
||||
"RT1.1": [
|
||||
{
|
||||
"id": 1,
|
||||
"id": 1, // moduleimpl_id
|
||||
"titre": "Initiation aux réseaux informatiques",
|
||||
"evaluations": [
|
||||
{
|
||||
@ -494,26 +263,9 @@ def etat_evals(formsemestre_id: int):
|
||||
"datetime_epreuve": null,
|
||||
"heure_fin": "09:00:00",
|
||||
"coefficient": "02.00"
|
||||
"comptee": "oui",
|
||||
"inscrits": 16,
|
||||
"manquantes": 0,
|
||||
"ABS": 0,
|
||||
"ATT": 0,
|
||||
"EXC": 0,
|
||||
"saisie_notes": {
|
||||
"datetime_debut": "2021-09-11T00:00:00+02:00",
|
||||
"datetime_fin": "2022-08-25T00:00:00+02:00",
|
||||
"datetime_mediane": "2022-03-19T00:00:00+01:00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"description": null,
|
||||
"datetime_epreuve": "Tue, 31 May 2022 00:00:00 GMT",
|
||||
"heure_fin": "08:00:00",
|
||||
"comptee": "oui",
|
||||
"inscrits": 16,
|
||||
"manquantes": 0,
|
||||
"is_complete": true,
|
||||
"nb_inscrits": 16,
|
||||
"nb_manquantes": 0,
|
||||
"ABS": 0,
|
||||
"ATT": 0,
|
||||
"EXC": 0,
|
||||
@ -523,67 +275,44 @@ def etat_evals(formsemestre_id: int):
|
||||
"datetime_mediane": "2022-03-19T00:00:00+01:00"
|
||||
}
|
||||
},
|
||||
...
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
"""
|
||||
# Récupération du semestre
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
|
||||
# Set du dept
|
||||
dept = Departement.query.get(formsemestre.dept_id)
|
||||
app.set_sco_dept(dept.acronym)
|
||||
|
||||
# Récupération des Ues
|
||||
list_ues = formsemestre.query_ues()
|
||||
|
||||
app.set_sco_dept(formsemestre.departement.acronym)
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
|
||||
ues = {}
|
||||
|
||||
for ue in list_ues:
|
||||
modules = []
|
||||
mods = ue.modules
|
||||
|
||||
for mod in mods:
|
||||
dict_module = {}
|
||||
moduleimpl = ModuleImpl.query.get_or_404(mod.id)
|
||||
|
||||
modimpl_results: ModuleImplResults = nt.modimpls_results[moduleimpl.id]
|
||||
|
||||
dict_module["id"] = mod.id
|
||||
dict_module["titre"] = mod.titre
|
||||
result = []
|
||||
for modimpl_id in nt.modimpls_results:
|
||||
modimpl_results: ModuleImplResults = nt.modimpls_results[modimpl_id]
|
||||
modimpl = ModuleImpl.query.get_or_404(modimpl_id)
|
||||
modimpl_dict = modimpl.to_dict()
|
||||
|
||||
list_eval = []
|
||||
for evaluation in moduleimpl.evaluations:
|
||||
eval_etat = modimpl_results.evaluations_etat[evaluation.id]
|
||||
eval = {}
|
||||
for evaluation_id in modimpl_results.evaluations_etat:
|
||||
eval_etat = modimpl_results.evaluations_etat[evaluation_id]
|
||||
evaluation = Evaluation.query.get_or_404(evaluation_id)
|
||||
eval_dict = evaluation.to_dict()
|
||||
eval_dict["etat"] = eval_etat.to_dict()
|
||||
|
||||
eval["id"] = evaluation.id
|
||||
eval["description"] = evaluation.description
|
||||
eval["datetime_epreuve"] = (
|
||||
evaluation.jour.isoformat() if evaluation.jour is not None else None
|
||||
)
|
||||
eval["heure_fin"] = evaluation.heure_fin.isoformat()
|
||||
eval["coefficient"] = evaluation.coefficient
|
||||
eval["comptee"] = "oui" if eval_etat.is_complete else "non"
|
||||
eval["inscrits"] = modimpl_results.nb_inscrits_module
|
||||
eval["manquantes"] = len(
|
||||
eval_dict["nb_inscrits"] = modimpl_results.nb_inscrits_module
|
||||
eval_dict["nb_notes_manquantes"] = len(
|
||||
modimpl_results.evals_etudids_sans_note[evaluation.id]
|
||||
)
|
||||
eval["ABS"] = sum(
|
||||
eval_dict["nb_notes_abs"] = sum(
|
||||
modimpl_results.evals_notes[evaluation.id] == scu.NOTES_ABSENCE
|
||||
)
|
||||
eval["ATT"] = eval_etat.nb_attente
|
||||
eval["EXC"] = sum(
|
||||
eval_dict["nb_notes_att"] = eval_etat.nb_attente
|
||||
eval_dict["nb_notes_exc"] = sum(
|
||||
modimpl_results.evals_notes[evaluation.id] == scu.NOTES_NEUTRALISE
|
||||
)
|
||||
|
||||
# Récupération de toutes les notes de l'évaluation
|
||||
notes = models.NotesNotes.query.filter_by(
|
||||
evaluation_id=evaluation.id
|
||||
).all()
|
||||
# eval["notes"] = modimpl_results.get_eval_notes_dict(evaluation_id)
|
||||
|
||||
notes = models.NotesNotes.query.filter_by(evaluation_id=evaluation.id).all()
|
||||
|
||||
date_debut = None
|
||||
date_fin = None
|
||||
@ -599,23 +328,14 @@ def etat_evals(formsemestre_id: int):
|
||||
|
||||
# Récupération de l'id de la note médiane
|
||||
list_id_notes_sorted = [note.id for note in notes_sorted]
|
||||
id_mediane = list_id_notes_sorted[len(list_id_notes_sorted) // 2]
|
||||
date_mediane = notes_sorted[id_mediane].date
|
||||
|
||||
# Ici si la longueur est paire on prend, on prend le +1 car un indice ne peux pas avoir de nombre floatant
|
||||
id_mediane = list_id_notes_sorted[
|
||||
int((len(list_id_notes_sorted)) / 2)
|
||||
]
|
||||
|
||||
for n in notes_sorted:
|
||||
if n.id == id_mediane:
|
||||
date_mediane = n.date
|
||||
|
||||
eval["saisie_notes"] = {
|
||||
eval_dict["saisie_notes"] = {
|
||||
"datetime_debut": date_debut.isoformat()
|
||||
if date_debut is not None
|
||||
else None,
|
||||
"datetime_fin": date_fin.isoformat()
|
||||
if date_fin is not None
|
||||
else None,
|
||||
"datetime_fin": date_fin.isoformat() if date_fin is not None else None,
|
||||
"datetime_mediane": date_mediane.isoformat()
|
||||
if date_mediane is not None
|
||||
else None,
|
||||
@ -623,8 +343,7 @@ def etat_evals(formsemestre_id: int):
|
||||
|
||||
list_eval.append(eval)
|
||||
|
||||
dict_module["evaluations"] = list_eval
|
||||
modules.append(dict_module)
|
||||
ues[ue.acronyme] = modules
|
||||
modimpl_dict["evaluations"] = list_eval
|
||||
result.append(modimpl_dict)
|
||||
|
||||
return jsonify(ues)
|
||||
return jsonify(result)
|
||||
|
@ -1,12 +1,21 @@
|
||||
############################################### Partitions ############################################################
|
||||
##############################################################################
|
||||
# ScoDoc
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
# See LICENSE
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
ScoDoc 9 API : partitions
|
||||
"""
|
||||
from flask import jsonify
|
||||
|
||||
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.scodoc.sco_groups import get_group_members, setGroups, get_partitions_list
|
||||
from app.models import FormSemestre, FormSemestreInscription, Identite
|
||||
from app.models import GroupDescr, Partition
|
||||
from app.models.groups import group_membership
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
|
||||
@ -41,15 +50,8 @@ def partition(formsemestre_id: int):
|
||||
}
|
||||
]
|
||||
"""
|
||||
# # Récupération de toutes les partitions
|
||||
# partitions = models.Partition.query.filter_by(id=formsemestre_id)
|
||||
#
|
||||
# # Mise en forme des données
|
||||
# data = [partition.to_dict() for partition in partitions]
|
||||
|
||||
data = get_partitions_list(formsemestre_id)
|
||||
|
||||
return jsonify(data)
|
||||
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
return jsonify([partition.to_dict() for partition in formsemestre.partitions])
|
||||
|
||||
|
||||
@bp.route("/partition/group/<int:group_id>", methods=["GET"])
|
||||
@ -66,56 +68,30 @@ def etud_in_group(group_id: int, etat=None):
|
||||
Exemple de résultat :
|
||||
[
|
||||
{
|
||||
"etudid": 10,
|
||||
"id": 10,
|
||||
"dept_id": 1,
|
||||
"nom": "BOUTET",
|
||||
"prenom": "Marguerite",
|
||||
"nom_usuel": "",
|
||||
"civilite": "F",
|
||||
"date_naissance": null,
|
||||
"lieu_naissance": null,
|
||||
"dept_naissance": null,
|
||||
"nationalite": null,
|
||||
"statut": null,
|
||||
"boursier": null,
|
||||
"photo_filename": null,
|
||||
"code_nip": "10",
|
||||
"code_ine": "10",
|
||||
"scodoc7_id": null,
|
||||
"email": "MARGUERITE.BOUTET@example.com",
|
||||
"emailperso": null,
|
||||
"domicile": null,
|
||||
"codepostaldomicile": null,
|
||||
"villedomicile": null,
|
||||
"paysdomicile": null,
|
||||
"telephone": null,
|
||||
"telephonemobile": null,
|
||||
"fax": null,
|
||||
"typeadresse": "domicile",
|
||||
"description": null,
|
||||
"group_id": 1,
|
||||
"etat": "I",
|
||||
"civilite_str": "Mme",
|
||||
"nom_disp": "BOUTET",
|
||||
"nomprenom": "Mme Marguerite BOUTET",
|
||||
"ne": "e",
|
||||
"email_default": "MARGUERITE.BOUTET@example.com"
|
||||
'civilite': 'M',
|
||||
'id': 123456,
|
||||
'ine': None,
|
||||
'nip': '987654321',
|
||||
'nom': 'MARTIN',
|
||||
'nom_usuel': null,
|
||||
'prenom': 'JEAN'}
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
# Fonction utilisée : app.scodoc.sco_groups.get_group_members()
|
||||
|
||||
group = GroupDescr.query.get_or_404(group_id)
|
||||
if etat is None:
|
||||
data = get_group_members(group_id)
|
||||
query = group.etuds
|
||||
else:
|
||||
data = get_group_members(group_id, etat)
|
||||
query = (
|
||||
Identite.query.join(FormSemestreInscription)
|
||||
.filter_by(formsemestre_id=group.partition.formsemestre_id, etat=etat)
|
||||
.join(group_membership)
|
||||
.filter_by(group_id=group_id)
|
||||
)
|
||||
|
||||
if len(data) == 0:
|
||||
return error_response(404, message="group_id inconnu")
|
||||
|
||||
return jsonify(data)
|
||||
return jsonify([etud.to_dict_short() for etud in query])
|
||||
|
||||
|
||||
@bp.route(
|
||||
|
@ -1,14 +1,22 @@
|
||||
##############################################################################
|
||||
# ScoDoc
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
# See LICENSE
|
||||
##############################################################################
|
||||
"""ScoDoc 9 API : outils
|
||||
"""
|
||||
|
||||
from sqlalchemy import desc
|
||||
|
||||
from app import models
|
||||
|
||||
from app.api.errors import error_response
|
||||
from app.models import Identite
|
||||
from app.models import Identite, Admission
|
||||
|
||||
|
||||
def get_last_instance_etud_from_etudid_or_nip_or_ine(
|
||||
etudid=None, nip=None, ine=None
|
||||
) -> models.Identite:
|
||||
def get_etud(etudid=None, nip=None, ine=None) -> models.Identite:
|
||||
"""
|
||||
Retourne l'instance de l'etudiant la plus récente en fonction de l'etudid, code nip et code ine rentré en paramètres
|
||||
L'instance d'étudiant la plus récente en fonction de l'etudid,
|
||||
ou du code nip ou code ine.
|
||||
|
||||
etudid : None ou un int etudid
|
||||
nip : None ou un int code_nip
|
||||
@ -17,8 +25,8 @@ def get_last_instance_etud_from_etudid_or_nip_or_ine(
|
||||
Return None si étudiant inexistant.
|
||||
"""
|
||||
if etudid is not None:
|
||||
etud = Identite.query.get(etudid)
|
||||
else:
|
||||
return Identite.query.get(etudid)
|
||||
|
||||
if nip is not None:
|
||||
query = Identite.query.filter_by(code_nip=nip)
|
||||
elif ine is not None:
|
||||
@ -28,15 +36,4 @@ def get_last_instance_etud_from_etudid_or_nip_or_ine(
|
||||
404,
|
||||
message="parametre manquant",
|
||||
)
|
||||
if query.count() > 1: # cas rare d'un étudiant présent dans plusieurs depts
|
||||
etuds = []
|
||||
for e in query:
|
||||
admission = e.admission.first()
|
||||
etuds.append((((admission.annee or 0) if admission else 0), e))
|
||||
etuds.sort()
|
||||
etud = etuds[-1][1]
|
||||
else:
|
||||
etud = query.first()
|
||||
|
||||
return etud
|
||||
|
||||
return query.join(Admission).order_by(desc(Admission.annee)).first()
|
||||
|
@ -33,6 +33,7 @@ Rappel: pour éviter les confusions, on appelera *poids* les coefficients d'une
|
||||
évaluation dans un module, et *coefficients* ceux utilisés pour le calcul de la
|
||||
moyenne générale d'une UE.
|
||||
"""
|
||||
import dataclasses
|
||||
from dataclasses import dataclass
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
@ -54,6 +55,10 @@ class EvaluationEtat:
|
||||
nb_attente: int
|
||||
is_complete: bool
|
||||
|
||||
def to_dict(self):
|
||||
"convert to dict"
|
||||
return dataclasses.asdict(self)
|
||||
|
||||
|
||||
class ModuleImplResults:
|
||||
"""Classe commune à toutes les formations (standard et APC).
|
||||
@ -236,6 +241,16 @@ class ModuleImplResults:
|
||||
self.evals_notes.values > scu.NOTES_ABSENCE, self.evals_notes.values, 0.0
|
||||
) / [e.note_max / 20.0 for e in moduleimpl.evaluations]
|
||||
|
||||
def get_eval_notes_dict(self, evaluation_id: int) -> dict:
|
||||
"""Notes d'une évaulation, brutes, sous forme d'un dict
|
||||
{ etudid : valeur }
|
||||
avec les valeurs float, ou "ABS" ou EXC
|
||||
"""
|
||||
return {
|
||||
etudid: scu.fmt_note(x, keep_numeric=True)
|
||||
for (etudid, x) in self.evals_notes[evaluation_id].items()
|
||||
}
|
||||
|
||||
def get_evaluation_rattrapage(self, moduleimpl: ModuleImpl):
|
||||
"""L'évaluation de rattrapage de ce module, ou None s'il n'en a pas.
|
||||
Rattrapage: la moyenne du module est la meilleure note entre moyenne
|
||||
|
@ -29,15 +29,6 @@ class Absence(db.Model):
|
||||
# XXX TODO: contrainte ajoutée: vérifier suppression du module
|
||||
# (mettre à NULL sans supprimer)
|
||||
|
||||
def __init__(self, id, etudid, jour, estabs, estjust, matin, description):
|
||||
self.id = id
|
||||
self.etudid = etudid
|
||||
self.jour = jour
|
||||
self.estabs = estabs
|
||||
self.estjust = estjust
|
||||
self.matin = matin
|
||||
self.description = description
|
||||
|
||||
def to_dict(self):
|
||||
data = {
|
||||
"id": self.id,
|
||||
|
@ -83,40 +83,6 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
||||
)
|
||||
formations = db.relationship("Formation", backref="referentiel_competence")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id,
|
||||
dept_id,
|
||||
annexe,
|
||||
specialite,
|
||||
specialite_long,
|
||||
type_titre,
|
||||
type_structure,
|
||||
type_departement,
|
||||
version_orebut,
|
||||
_xml_attribs,
|
||||
#scodoc_date_loaded,
|
||||
scodoc_orig_filename,
|
||||
# competences,
|
||||
# parcours,
|
||||
# formations,
|
||||
):
|
||||
self.id = id
|
||||
self.dept_id = dept_id
|
||||
self.annexe = annexe
|
||||
self.specialite = specialite
|
||||
self.specialite_long = specialite_long
|
||||
self.type_titre = type_titre
|
||||
self.type_structure = type_structure
|
||||
self.type_departement = type_departement
|
||||
self.version_orebut = version_orebut
|
||||
self._xml_attribs = _xml_attribs
|
||||
#self.scodoc_date_loaded = scodoc_date_loaded
|
||||
self.scodoc_orig_filename = scodoc_orig_filename
|
||||
# self.competences = competences
|
||||
# self.parcours = parcours
|
||||
# self.formations = formations
|
||||
|
||||
def __repr__(self):
|
||||
return f"<ApcReferentielCompetences {self.id} {self.specialite!r} {self.departement!r}>"
|
||||
|
||||
@ -225,32 +191,6 @@ class ApcCompetence(db.Model, XMLModel):
|
||||
cascade="all, delete-orphan",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id,
|
||||
referentiel_id,
|
||||
id_orebut,
|
||||
titre,
|
||||
titre_long,
|
||||
couleur,
|
||||
numero,
|
||||
_xml_attribs,
|
||||
situations,
|
||||
composantes_essentielles,
|
||||
niveaux,
|
||||
):
|
||||
self.id = id
|
||||
self.referentiel_id = referentiel_id
|
||||
self.id_orebut = id_orebut
|
||||
self.titre = titre
|
||||
self.titre_long = titre_long
|
||||
self.couleur = couleur
|
||||
self.numero = numero
|
||||
self._xml_attribs = _xml_attribs
|
||||
self.situations = situations
|
||||
self.composantes_essentielles = composantes_essentielles
|
||||
self.niveaux = niveaux
|
||||
|
||||
def __repr__(self):
|
||||
return f"<ApcCompetence {self.id} {self.titre!r}>"
|
||||
|
||||
@ -288,12 +228,6 @@ class ApcSituationPro(db.Model, XMLModel):
|
||||
)
|
||||
libelle = db.Column(db.Text(), nullable=False)
|
||||
# aucun attribut (le text devient le libellé)
|
||||
|
||||
def __init__(self, id, competence_id, libelle):
|
||||
self.id = id
|
||||
self.competence_id = competence_id
|
||||
self.libelle = libelle
|
||||
|
||||
def to_dict(self):
|
||||
return {"libelle": self.libelle}
|
||||
|
||||
@ -306,11 +240,6 @@ class ApcComposanteEssentielle(db.Model, XMLModel):
|
||||
)
|
||||
libelle = db.Column(db.Text(), nullable=False)
|
||||
|
||||
def __init__(self, id, competence_id, libelle):
|
||||
self.id = id
|
||||
self.competence_id = competence_id
|
||||
self.libelle = libelle
|
||||
|
||||
def to_dict(self):
|
||||
return {"libelle": self.libelle}
|
||||
|
||||
@ -339,14 +268,6 @@ class ApcNiveau(db.Model, XMLModel):
|
||||
)
|
||||
ues = db.relationship("UniteEns", back_populates="niveau_competence")
|
||||
|
||||
def __init__(self, id, competence_id, libelle, annee, ordre, app_critiques):
|
||||
self.id = id
|
||||
self.competence_id = competence_id
|
||||
self.libelle = libelle
|
||||
self.annee = annee
|
||||
self.ordre = ordre
|
||||
self.app_critiques = app_critiques
|
||||
|
||||
def __repr__(self):
|
||||
return f"""<{self.__class__.__name__} {self.id} ordre={self.ordre!r} annee={
|
||||
self.annee!r} {self.competence!r}>"""
|
||||
@ -452,13 +373,6 @@ class ApcAppCritique(db.Model, XMLModel):
|
||||
query = query.filter(ApcNiveau.competence == competence)
|
||||
return query
|
||||
|
||||
def __init__(self, id, niveau_id, code, libelle, modules):
|
||||
self.id = id
|
||||
self.niveau_id = niveau_id
|
||||
self.code = code
|
||||
self.libelle = libelle
|
||||
self.modules = modules
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {"libelle": self.libelle}
|
||||
|
||||
@ -517,14 +431,6 @@ class ApcParcours(db.Model, XMLModel):
|
||||
cascade="all, delete-orphan",
|
||||
)
|
||||
|
||||
def __init__(self, id, referentiel_id, numero, code, libelle, annes):
|
||||
self.id = id
|
||||
self.referentiel_id = referentiel_id
|
||||
self.numero = numero
|
||||
self.code = code
|
||||
self.libelle = libelle
|
||||
self.annes = annes
|
||||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__name__} {self.id} {self.code!r} ref={self.referentiel}>"
|
||||
|
||||
@ -545,11 +451,6 @@ class ApcAnneeParcours(db.Model, XMLModel):
|
||||
ordre = db.Column(db.Integer)
|
||||
"numéro de l'année: 1, 2, 3"
|
||||
|
||||
def __init__(self, id, parcours_id, ordre):
|
||||
self.id = id
|
||||
self.parcours_id = parcours_id
|
||||
self.ordre = ordre
|
||||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__name__} {self.id} ordre={self.ordre!r} parcours={self.parcours.code!r}>"
|
||||
|
||||
|
@ -654,11 +654,6 @@ class FormSemestreEtape(db.Model):
|
||||
# etape_apo aurait du etre not null, mais oublié
|
||||
etape_apo = db.Column(db.String(APO_CODE_STR_LEN), index=True)
|
||||
|
||||
def __init__(self, id, formsemestre_id, etape_apo):
|
||||
self.id = id
|
||||
self.formsemestre_id = formsemestre_id
|
||||
self.etape_apo = etape_apo
|
||||
|
||||
def __bool__(self):
|
||||
"Etape False if code empty"
|
||||
return self.etape_apo is not None and (len(self.etape_apo) > 0)
|
||||
|
@ -58,12 +58,9 @@ class Partition(db.Model):
|
||||
|
||||
def to_dict(self, with_groups=False) -> dict:
|
||||
"""as a dict, with or without groups"""
|
||||
d = {
|
||||
"id": self.id,
|
||||
"formsemestre_id": self.partition_id,
|
||||
"name": self.partition_name,
|
||||
"numero": self.numero,
|
||||
}
|
||||
d = dict(self.__dict__)
|
||||
d.pop("_sa_instance_state", None)
|
||||
|
||||
if with_groups:
|
||||
d["groups"] = [group.to_dict(with_partition=False) for group in self.groups]
|
||||
return d
|
||||
|
@ -47,24 +47,11 @@ class NotesNotes(db.Model):
|
||||
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
uid = db.Column(db.Integer, db.ForeignKey("user.id"))
|
||||
|
||||
def __init__(self, etudid, evaluation_id, value, comment, date, uid):
|
||||
self.etudid = etudid
|
||||
self.evaluation_id = evaluation_id
|
||||
self.value = value
|
||||
self.comment = comment
|
||||
self.date = date
|
||||
self.uid = uid
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"etudid": self.etudid,
|
||||
"evaluation_id": self.evaluation_id,
|
||||
"value": self.value,
|
||||
"comment": self.comment,
|
||||
"date": self.date,
|
||||
"uid": self.uid,
|
||||
}
|
||||
def to_dict(self) -> dict:
|
||||
"dict"
|
||||
d = dict(self.__dict__)
|
||||
d.pop("_sa_instance_state", None)
|
||||
return d
|
||||
|
||||
|
||||
class NotesNotesLog(db.Model):
|
||||
|
@ -136,7 +136,7 @@ def get_partition(partition_id):
|
||||
return r[0]
|
||||
|
||||
|
||||
def get_partitions_list(formsemestre_id, with_default=True):
|
||||
def get_partitions_list(formsemestre_id, with_default=True) -> list[dict]:
|
||||
"""Liste des partitions pour ce semestre (list of dicts)"""
|
||||
partitions = ndb.SimpleDictFetch(
|
||||
"""SELECT p.id AS partition_id, p.*
|
||||
@ -146,9 +146,9 @@ def get_partitions_list(formsemestre_id, with_default=True):
|
||||
{"formsemestre_id": formsemestre_id},
|
||||
)
|
||||
# Move 'all' at end of list (for menus)
|
||||
R = [p for p in partitions if p["partition_name"] != None]
|
||||
R = [p for p in partitions if p["partition_name"] is not None]
|
||||
if with_default:
|
||||
R += [p for p in partitions if p["partition_name"] == None]
|
||||
R += [p for p in partitions if p["partition_name"] is None]
|
||||
return R
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user