Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into dev93
This commit is contained in:
commit
91544aa254
@ -14,8 +14,8 @@ from app.scodoc.sco_permissions import Permission
|
||||
|
||||
|
||||
@bp.route("/absences/etudid/<int:etudid>", methods=["GET"])
|
||||
@bp.route("/absences/nip/<int:nip>", methods=["GET"])
|
||||
@bp.route("/absences/ine/<int:ine>", methods=["GET"])
|
||||
@bp.route("/absences/nip/<string:nip>", methods=["GET"])
|
||||
@bp.route("/absences/ine/<string:ine>", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def absences(etudid: int = None, nip: int = None, ine: int = None):
|
||||
|
@ -55,8 +55,8 @@ def etudiants_courant(long=False):
|
||||
|
||||
|
||||
@bp.route("/etudiant/etudid/<int:etudid>", methods=["GET"])
|
||||
@bp.route("/etudiant/nip/<int:nip>", methods=["GET"])
|
||||
@bp.route("/etudiant/ine/<int:ine>", methods=["GET"])
|
||||
@bp.route("/etudiant/nip/<string:nip>", methods=["GET"])
|
||||
@bp.route("/etudiant/ine/<string:ine>", methods=["GET"])
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def etudiant(etudid: int = None, nip: int = None, ine: int = None):
|
||||
@ -109,8 +109,8 @@ def etudiant(etudid: int = None, nip: int = None, ine: int = None):
|
||||
|
||||
|
||||
@bp.route("/etudiant/etudid/<int:etudid>/formsemestres")
|
||||
@bp.route("/etudiant/nip/<int:nip>/formsemestres")
|
||||
@bp.route("/etudiant/ine/<int:ine>/formsemestres")
|
||||
@bp.route("/etudiant/nip/<string:nip>/formsemestres")
|
||||
@bp.route("/etudiant/ine/<string:ine>/formsemestres")
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None):
|
||||
@ -175,12 +175,12 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None)
|
||||
defaults={"version": "long"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||
"/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||
methods=["GET"],
|
||||
defaults={"version": "long"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||
"/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||
methods=["GET"],
|
||||
defaults={"version": "long"},
|
||||
)
|
||||
@ -190,12 +190,12 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None)
|
||||
defaults={"version": "short"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin/short",
|
||||
"/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/bulletin/short",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short"},
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin/short",
|
||||
"/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/bulletin/short",
|
||||
methods=["GET"],
|
||||
defaults={"version": "short"},
|
||||
)
|
||||
@ -408,10 +408,12 @@ def etudiant_bulletin_semestre(
|
||||
methods=["GET"],
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/groups", methods=["GET"]
|
||||
"/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/groups",
|
||||
methods=["GET"],
|
||||
)
|
||||
@bp.route(
|
||||
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/groups", methods=["GET"]
|
||||
"/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/groups",
|
||||
methods=["GET"],
|
||||
)
|
||||
@token_auth.login_required
|
||||
@token_permission_required(Permission.APIView)
|
||||
|
@ -413,8 +413,15 @@ def formsemestre_get_etud_groupnames(formsemestre_id, attr="group_name"):
|
||||
return R
|
||||
|
||||
|
||||
def etud_add_group_infos(etud, formsemestre_id, sep=" "):
|
||||
"""Add informations on partitions and group memberships to etud (a dict with an etudid)"""
|
||||
def etud_add_group_infos(etud, formsemestre_id, sep=" ", only_to_show=False):
|
||||
"""Add informations on partitions and group memberships to etud
|
||||
(a dict with an etudid)
|
||||
If only_to_show, restrict to partions such that show_in_lists is True.
|
||||
|
||||
etud['partitions'] = { partition_id : group + partition_name }
|
||||
etud['groupes'] = "TDB, Gr2, TPB1"
|
||||
etud['partitionsgroupes'] = "Groupes TD:TDB, Groupes TP:Gr2 (...)"
|
||||
"""
|
||||
etud[
|
||||
"partitions"
|
||||
] = collections.OrderedDict() # partition_id : group + partition_name
|
||||
@ -423,11 +430,14 @@ def etud_add_group_infos(etud, formsemestre_id, sep=" "):
|
||||
return etud
|
||||
|
||||
infos = ndb.SimpleDictFetch(
|
||||
"""SELECT p.partition_name, g.*, g.id AS group_id
|
||||
"""SELECT p.partition_name, p.show_in_lists, g.*, g.id AS group_id
|
||||
FROM group_descr g, partition p, group_membership gm WHERE gm.etudid=%(etudid)s
|
||||
and gm.group_id = g.id
|
||||
and g.partition_id = p.id
|
||||
and p.formsemestre_id = %(formsemestre_id)s
|
||||
"""
|
||||
+ (" and (p.show_in_lists is True) " if only_to_show else "")
|
||||
+ """
|
||||
ORDER BY p.numero
|
||||
""",
|
||||
{"etudid": etud["etudid"], "formsemestre_id": formsemestre_id},
|
||||
|
@ -153,14 +153,14 @@ def ficheEtud(etudid=None):
|
||||
try: # pour les bookmarks avec d'anciens ids...
|
||||
etudid = int(etudid)
|
||||
except ValueError:
|
||||
raise ScoValueError("id invalide !")
|
||||
raise ScoValueError("id invalide !") from ValueError
|
||||
# la sidebar est differente s'il y a ou pas un etudid
|
||||
# voir html_sidebar.sidebar()
|
||||
g.etudid = etudid
|
||||
args = make_etud_args(etudid=etudid)
|
||||
etuds = sco_etud.etudident_list(cnx, args)
|
||||
if not etuds:
|
||||
log("ficheEtud: etudid=%s request.args=%s" % (etudid, request.args))
|
||||
log(f"ficheEtud: etudid={etudid!r} request.args={request.args!r}")
|
||||
raise ScoValueError("Etudiant inexistant !")
|
||||
etud = etuds[0]
|
||||
etudid = etud["etudid"]
|
||||
@ -173,7 +173,7 @@ def ficheEtud(etudid=None):
|
||||
if info["lieu_naissance"]:
|
||||
info["info_naissance"] += " à " + info["lieu_naissance"]
|
||||
if info["dept_naissance"]:
|
||||
info["info_naissance"] += " (%s)" % info["dept_naissance"]
|
||||
info["info_naissance"] += f" ({info['dept_naissance']})"
|
||||
info["etudfoto"] = sco_photos.etud_photo_html(etud)
|
||||
if (
|
||||
(not info["domicile"])
|
||||
@ -205,7 +205,7 @@ def ficheEtud(etudid=None):
|
||||
)
|
||||
else:
|
||||
info["emaillink"] = "<em>(pas d'adresse e-mail)</em>"
|
||||
# champs dependant des permissions
|
||||
# Champ dépendant des permissions:
|
||||
if authuser.has_permission(Permission.ScoEtudChangeAdr):
|
||||
info["modifadresse"] = (
|
||||
'<a class="stdlink" href="formChangeCoordonnees?etudid=%s">modifier adresse</a>'
|
||||
@ -216,9 +216,10 @@ def ficheEtud(etudid=None):
|
||||
|
||||
# Groupes:
|
||||
sco_groups.etud_add_group_infos(
|
||||
info, info["cursem"]["formsemestre_id"] if info["cursem"] else None
|
||||
info,
|
||||
info["cursem"]["formsemestre_id"] if info["cursem"] else None,
|
||||
only_to_show=True,
|
||||
)
|
||||
|
||||
# Parcours de l'étudiant
|
||||
if info["sems"]:
|
||||
info["last_formsemestre_id"] = info["sems"][0]["formsemestre_id"]
|
||||
@ -235,15 +236,28 @@ def ficheEtud(etudid=None):
|
||||
)
|
||||
grlink = '<span class="fontred">%s</span>' % descr["situation"]
|
||||
else:
|
||||
group = sco_groups.get_etud_main_group(etudid, sem["formsemestre_id"])
|
||||
if group["partition_name"]:
|
||||
gr_name = group["group_name"]
|
||||
else:
|
||||
gr_name = "tous"
|
||||
grlink = (
|
||||
'<a class="discretelink" href="groups_view?group_ids=%s" title="Liste du groupe">groupe %s</a>'
|
||||
% (group["group_id"], gr_name)
|
||||
e = {"etudid": etudid}
|
||||
sco_groups.etud_add_group_infos(
|
||||
e,
|
||||
sem["formsemestre_id"],
|
||||
only_to_show=True,
|
||||
)
|
||||
|
||||
grlinks = []
|
||||
for partition in e["partitions"].values():
|
||||
if partition["partition_name"]:
|
||||
gr_name = partition["group_name"]
|
||||
else:
|
||||
gr_name = "tous"
|
||||
|
||||
grlinks.append(
|
||||
f"""<a class="discretelink" href="{
|
||||
url_for('scolar.groups_view',
|
||||
scodoc_dept=g.scodoc_dept, group_ids=partition['group_id'])
|
||||
}" title="Liste du groupe {gr_name}">{gr_name}</a>
|
||||
"""
|
||||
)
|
||||
grlink = ", ".join(grlinks)
|
||||
# infos ajoutées au semestre dans le parcours (groupe, menu)
|
||||
menu = _menuScolarite(authuser, sem, etudid)
|
||||
if menu:
|
||||
@ -296,17 +310,18 @@ def ficheEtud(etudid=None):
|
||||
if not sco_permissions_check.can_suppress_annotation(a["id"]):
|
||||
a["dellink"] = ""
|
||||
else:
|
||||
a[
|
||||
"dellink"
|
||||
] = '<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>' % (
|
||||
etudid,
|
||||
a["id"],
|
||||
scu.icontag(
|
||||
"delete_img",
|
||||
border="0",
|
||||
alt="suppress",
|
||||
title="Supprimer cette annotation",
|
||||
),
|
||||
a["dellink"] = (
|
||||
'<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>'
|
||||
% (
|
||||
etudid,
|
||||
a["id"],
|
||||
scu.icontag(
|
||||
"delete_img",
|
||||
border="0",
|
||||
alt="suppress",
|
||||
title="Supprimer cette annotation",
|
||||
),
|
||||
)
|
||||
)
|
||||
author = sco_users.user_info(a["author"])
|
||||
alist.append(
|
||||
@ -422,9 +437,11 @@ def ficheEtud(etudid=None):
|
||||
|
||||
#
|
||||
if info["groupes"].strip():
|
||||
info["groupes_row"] = (
|
||||
'<tr><td class="fichetitre2">Groupe :</td><td>%(groupes)s</td></tr>' % info
|
||||
)
|
||||
info[
|
||||
"groupes_row"
|
||||
] = f"""<tr>
|
||||
<td class="fichetitre2">Groupes :</td><td>{info['groupes']}</td>
|
||||
</tr>"""
|
||||
else:
|
||||
info["groupes_row"] = ""
|
||||
info["menus_etud"] = menus_etud(etudid)
|
||||
|
@ -84,12 +84,15 @@ def formsemestre_recapcomplet(
|
||||
selected_etudid: etudid sélectionné (pour scroller au bon endroit)
|
||||
"""
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
|
||||
file_formats = {"csv", "json", "xls", "xlsx", "xlsall", "xml"}
|
||||
supported_formats = file_formats | {"html"}
|
||||
if tabformat not in supported_formats:
|
||||
raise ScoValueError(f"Format non supporté: {tabformat}")
|
||||
is_file = tabformat in file_formats
|
||||
modejury = int(modejury)
|
||||
|
||||
xml_with_decisions = int(xml_with_decisions)
|
||||
force_publishing = int(force_publishing)
|
||||
is_file = tabformat in {"csv", "json", "xls", "xlsx", "xlsall", "xml"}
|
||||
|
||||
data = _do_formsemestre_recapcomplet(
|
||||
formsemestre_id,
|
||||
format=tabformat,
|
||||
@ -128,6 +131,7 @@ def formsemestre_recapcomplet(
|
||||
for (format, label) in (
|
||||
("html", "Tableau"),
|
||||
("evals", "Avec toutes les évaluations"),
|
||||
("xlsx", "Excel non formatté"),
|
||||
("xml", "Bulletins XML (obsolète)"),
|
||||
("json", "Bulletins JSON"),
|
||||
):
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.2.17"
|
||||
SCOVERSION = "9.2.18"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Test Logos
|
||||
"""Test API: accès aux étudiants
|
||||
|
||||
Utilisation :
|
||||
créer les variables d'environnement: (indiquer les valeurs
|
||||
@ -58,7 +58,7 @@ def test_etudiants_courant(api_headers):
|
||||
|
||||
def test_etudiant(api_headers):
|
||||
"""
|
||||
Route:
|
||||
Routes: /etudiant/etudid, /etudiant/nip, /etudiant/ine
|
||||
"""
|
||||
|
||||
######### Test etudid #########
|
||||
@ -87,7 +87,7 @@ def test_etudiant(api_headers):
|
||||
######### Test code ine #########
|
||||
|
||||
r = requests.get(
|
||||
API_URL + "/etudiant/ine/1",
|
||||
API_URL + "/etudiant/ine/INE1",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
@ -97,6 +97,39 @@ def test_etudiant(api_headers):
|
||||
fields_ok = verify_fields(etud, ETUD_FIELDS)
|
||||
assert fields_ok is True
|
||||
|
||||
# Vérifie le requetage des 3 1er étudiants
|
||||
for etudid in (1, 2, 3):
|
||||
r = requests.get(
|
||||
f"{API_URL }/etudiant/etudid/{etudid}",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
etud = r.json()
|
||||
nip = etud["code_nip"]
|
||||
ine = etud["code_ine"]
|
||||
assert isinstance(etud["id"], int)
|
||||
assert isinstance(nip, str)
|
||||
assert isinstance(ine, str)
|
||||
r = requests.get(
|
||||
f"{API_URL }/etudiant/nip/{nip}",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
etud_nip = r.json()
|
||||
# On doit avoir obtenue le même étudiant
|
||||
assert etud_nip == etud
|
||||
r = requests.get(
|
||||
f"{API_URL }/etudiant/ine/{ine}",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
etud_ine = r.json()
|
||||
# On doit avoir obtenue le même étudiant
|
||||
assert etud_ine == etud
|
||||
|
||||
|
||||
def test_etudiant_formsemestres(api_headers):
|
||||
"""
|
||||
@ -132,7 +165,7 @@ def test_etudiant_formsemestres(api_headers):
|
||||
|
||||
######### Test code ine #########
|
||||
r = requests.get(
|
||||
API_URL + "/etudiant/ine/1/formsemestres",
|
||||
API_URL + "/etudiant/ine/INE1/formsemestres",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
@ -172,7 +205,7 @@ def test_etudiant_bulletin_semestre(api_headers):
|
||||
|
||||
######### Test code ine #########
|
||||
r = requests.get(
|
||||
API_URL + "/etudiant/ine/1/formsemestre/1/bulletin",
|
||||
API_URL + "/etudiant/ine/INE1/formsemestre/1/bulletin",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
@ -235,7 +268,7 @@ def test_etudiant_groups(api_headers):
|
||||
|
||||
######### Test code ine #########
|
||||
r = requests.get(
|
||||
API_URL + "/etudiant/ine/1/formsemestre/1/groups",
|
||||
API_URL + "/etudiant/ine/INE1/formsemestre/1/groups",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Test Logos
|
||||
"""Test API Jurys XXX TODO A ECRIRE
|
||||
|
||||
Utilisation :
|
||||
créer les variables d'environnement: (indiquer les valeurs
|
||||
@ -77,30 +77,30 @@ def test_set_decision_jury(api_headers):
|
||||
assert r.status_code == 200
|
||||
|
||||
|
||||
def test_annule_decision_jury(api_headers):
|
||||
"""
|
||||
Route:
|
||||
"""
|
||||
r = requests.get(
|
||||
SCODOC_URL
|
||||
+ "/ScoDoc/api/jury/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
# def test_annule_decision_jury(api_headers):
|
||||
# """
|
||||
# Route:
|
||||
# """
|
||||
# r = requests.get(
|
||||
# SCODOC_URL
|
||||
# + "/ScoDoc/api/jury/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||
# headers=api_headers,
|
||||
# verify=CHECK_CERTIFICATE,
|
||||
# )
|
||||
# assert r.status_code == 200
|
||||
|
||||
r = requests.get(
|
||||
SCODOC_URL
|
||||
+ "/ScoDoc/api/jury/nip/<int:nip>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
# r = requests.get(
|
||||
# SCODOC_URL
|
||||
# + "/ScoDoc/api/jury/nip/<int:nip>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||
# headers=api_headers,
|
||||
# verify=CHECK_CERTIFICATE,
|
||||
# )
|
||||
# assert r.status_code == 200
|
||||
|
||||
r = requests.get(
|
||||
SCODOC_URL
|
||||
+ "/ScoDoc/api/jury/ine/<int:ine>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
# r = requests.get(
|
||||
# SCODOC_URL
|
||||
# + "/ScoDoc/api/jury/ine/<int:ine>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||
# headers=api_headers,
|
||||
# verify=CHECK_CERTIFICATE,
|
||||
# )
|
||||
# assert r.status_code == 200
|
||||
|
@ -28,7 +28,7 @@ import sys
|
||||
|
||||
from app.auth.models import Role, User
|
||||
from app import models
|
||||
from app.models import Departement, Formation, FormSemestre
|
||||
from app.models import Departement, Formation, FormSemestre, Identite
|
||||
from app import db
|
||||
from app.scodoc import (
|
||||
sco_cache,
|
||||
@ -95,15 +95,18 @@ def create_users(dept: Departement) -> tuple:
|
||||
return user, other
|
||||
|
||||
|
||||
def create_fake_etud(dept: Departement) -> models.Identite:
|
||||
"""Créé un faux étudiant et l'insère dans la base"""
|
||||
def create_fake_etud(dept: Departement) -> Identite:
|
||||
"""Créé un faux étudiant et l'insère dans la base."""
|
||||
civilite = random.choice(("M", "F", "X"))
|
||||
nom, prenom = nomprenom(civilite)
|
||||
etud = models.Identite(civilite=civilite, nom=nom, prenom=prenom, dept_id=dept.id)
|
||||
etud: Identite = Identite(
|
||||
civilite=civilite, nom=nom, prenom=prenom, dept_id=dept.id
|
||||
)
|
||||
db.session.add(etud)
|
||||
db.session.commit()
|
||||
etud.code_nip = etud.id
|
||||
etud.code_ine = etud.id
|
||||
# créé un étudiant sur deux avec un NIP et INE alphanumérique
|
||||
etud.code_nip = f"{etud.id}" if (etud.id % 2) else f"NIP{etud.id}"
|
||||
etud.code_ine = f"INE{etud.id}" if (etud.id % 2) else f"{etud.id}"
|
||||
db.session.add(etud)
|
||||
db.session.commit()
|
||||
adresse = models.Adresse(
|
||||
|
Loading…
Reference in New Issue
Block a user