forked from ScoDoc/ScoDoc
corrections REV#Emm + samples API (WIP)
This commit is contained in:
parent
7adc7d824b
commit
f3b1b8a3cb
@ -19,21 +19,22 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
|
|
||||||
from app.models import Identite, Assiduite, FormSemestreInscription, FormSemestre
|
from app.models import Identite, Assiduite, FormSemestre, ModuleImpl
|
||||||
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.sco_assiduites as scass
|
import app.scodoc.sco_assiduites as scass
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/assiduite/<int:assiduiteid>")
|
@bp.route("/assiduite/<int:assiduite_id>")
|
||||||
@api_web_bp.route("/assiduite/<int:assiduiteid>")
|
@api_web_bp.route("/assiduite/<int:assiduite_id>")
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
def assiduite(assiduiteid: int = None):
|
def assiduite(assiduite_id: int = None):
|
||||||
"""Retourne un objet assiduité à partir de son id
|
"""Retourne un objet assiduité à partir de son id
|
||||||
|
|
||||||
Exemple de résultat:
|
Exemple de résultat:
|
||||||
{
|
{
|
||||||
"assiduiteid": 1,
|
"assiduite_id": 1,
|
||||||
"etudid": 2,
|
"etudid": 2,
|
||||||
"moduleimpl_id": 3,
|
"moduleimpl_id": 3,
|
||||||
"date_debut": "2022-10-31T08:00+01:00",
|
"date_debut": "2022-10-31T08:00+01:00",
|
||||||
@ -42,9 +43,11 @@ def assiduite(assiduiteid: int = None):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assiduite = Assiduite.query.get(assiduiteid)
|
query = Assiduite.query.filter_by(id=assiduite_id)
|
||||||
if assiduite is None:
|
# if g.scodoc_dept:
|
||||||
return json_error(404, message="assiduité inexistante")
|
# query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
|
||||||
|
|
||||||
|
assiduite = query.first_or_404()
|
||||||
|
|
||||||
data = assiduite.to_dict()
|
data = assiduite.to_dict()
|
||||||
|
|
||||||
@ -346,13 +349,12 @@ def create_singular(
|
|||||||
|
|
||||||
# cas 4 : moduleimpl_id
|
# cas 4 : moduleimpl_id
|
||||||
|
|
||||||
moduleimpl_id = data.get("moduleimpl_id", None)
|
moduleimpl_id = data.get("moduleimpl_id", False)
|
||||||
if moduleimpl_id is not None:
|
moduleimpl: ModuleImpl = None
|
||||||
try:
|
|
||||||
moduleimpl_id: int = int(moduleimpl_id)
|
if moduleimpl_id is not False:
|
||||||
if moduleimpl_id < 0:
|
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first()
|
||||||
raise Exception
|
if moduleimpl is None:
|
||||||
except:
|
|
||||||
errors.append("param 'moduleimpl_id': invalide")
|
errors.append("param 'moduleimpl_id': invalide")
|
||||||
|
|
||||||
if errors != []:
|
if errors != []:
|
||||||
@ -360,25 +362,23 @@ def create_singular(
|
|||||||
return (404, err)
|
return (404, err)
|
||||||
|
|
||||||
# TOUT EST OK
|
# TOUT EST OK
|
||||||
nouv_assiduite: Assiduite or int = Assiduite.create_assiduite(
|
|
||||||
|
try:
|
||||||
|
nouv_assiduite: Assiduite = Assiduite.create_assiduite(
|
||||||
date_debut=deb,
|
date_debut=deb,
|
||||||
date_fin=fin,
|
date_fin=fin,
|
||||||
etat=etat,
|
etat=etat,
|
||||||
etud=etud,
|
etud=etud,
|
||||||
module=moduleimpl_id,
|
moduleimpl=moduleimpl,
|
||||||
)
|
)
|
||||||
|
|
||||||
if type(nouv_assiduite) is Assiduite:
|
|
||||||
db.session.add(nouv_assiduite)
|
db.session.add(nouv_assiduite)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return (200, {"assiduiteid": nouv_assiduite.assiduiteid})
|
return (200, {"assiduite_id": nouv_assiduite.assiduite_id})
|
||||||
|
except ScoValueError as excp:
|
||||||
return (
|
return (
|
||||||
404,
|
404,
|
||||||
{
|
excp.args[0],
|
||||||
1: "La période sélectionnée est déjà couverte par une autre assiduite",
|
|
||||||
2: "L'étudiant ne participe pas au moduleimpl sélectionné",
|
|
||||||
}.get(nouv_assiduite),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -417,7 +417,7 @@ def delete(batch: bool = False):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
code, msg = delete_singular(
|
code, msg = delete_singular(
|
||||||
request.get_json(force=True).get("assiduiteid", -1), db
|
request.get_json(force=True).get("assiduite_id", -1), db
|
||||||
)
|
)
|
||||||
if code == 404:
|
if code == 404:
|
||||||
return json_error(code, msg)
|
return json_error(code, msg)
|
||||||
@ -434,13 +434,13 @@ def delete_singular(assiduite_id: int, db):
|
|||||||
return (200, "OK")
|
return (200, "OK")
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/assiduite/<int:assiduiteid>/edit", methods=["POST"])
|
@bp.route("/assiduite/<int:assiduite_id>/edit", methods=["POST"])
|
||||||
@api_web_bp.route("/assiduite/<int:assiduiteid>/edit", methods=["POST"])
|
@api_web_bp.route("/assiduite/<int:assiduite_id>/edit", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
# @permission_required(Permission.ScoAssiduiteChange)
|
# @permission_required(Permission.ScoAssiduiteChange)
|
||||||
def edit(assiduiteid: int):
|
def edit(assiduite_id: int):
|
||||||
"""
|
"""
|
||||||
Edition d'une assiduité à partir de son id
|
Edition d'une assiduité à partir de son id
|
||||||
La requête doit avoir un content type "application/json":
|
La requête doit avoir un content type "application/json":
|
||||||
@ -449,7 +449,7 @@ def edit(assiduiteid: int):
|
|||||||
"moduleimpl_id": int
|
"moduleimpl_id": int
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
assiduite: Assiduite = Assiduite.query.filter_by(id=assiduiteid).first_or_404()
|
assiduite: Assiduite = Assiduite.query.filter_by(id=assiduite_id).first_or_404()
|
||||||
errors: List[str] = []
|
errors: List[str] = []
|
||||||
data = request.get_json(force=True)
|
data = request.get_json(force=True)
|
||||||
|
|
||||||
@ -465,18 +465,20 @@ def edit(assiduiteid: int):
|
|||||||
|
|
||||||
# Cas 2 : Moduleimpl_id
|
# Cas 2 : Moduleimpl_id
|
||||||
moduleimpl_id = data.get("moduleimpl_id", False)
|
moduleimpl_id = data.get("moduleimpl_id", False)
|
||||||
|
moduleimpl: ModuleImpl = None
|
||||||
|
|
||||||
if moduleimpl_id is not False:
|
if moduleimpl_id is not False:
|
||||||
try:
|
|
||||||
if moduleimpl_id is not None:
|
if moduleimpl_id is not None:
|
||||||
moduleimpl_id: int = int(moduleimpl_id)
|
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first()
|
||||||
if moduleimpl_id < 0 or not Assiduite.verif_moduleimpl(
|
if moduleimpl is None:
|
||||||
moduleimpl_id, assiduite.etudid
|
errors.append("param 'moduleimpl_id': invalide")
|
||||||
|
else:
|
||||||
|
if not moduleimpl.est_inscrit(
|
||||||
|
Identite.query.filter_by(id=assiduite.etudid).first()
|
||||||
):
|
):
|
||||||
errors.append("param 'moduleimpl_id': etud non inscrit")
|
errors.append("param 'moduleimpl_id': etud non inscrit")
|
||||||
|
else:
|
||||||
assiduite.moduleimpl_id = moduleimpl_id
|
assiduite.moduleimpl_id = moduleimpl_id
|
||||||
except:
|
|
||||||
errors.append("param 'moduleimpl_id': invalide")
|
|
||||||
|
|
||||||
if errors != []:
|
if errors != []:
|
||||||
err: str = ", ".join(errors)
|
err: str = ", ".join(errors)
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
from app import db
|
from app import db
|
||||||
from app.models import ModuleImpl, ModuleImplInscription
|
from app.models import ModuleImpl, ModuleImplInscription
|
||||||
from app.models.etudiants import Identite
|
from app.models.etudiants import Identite
|
||||||
from app.scodoc.sco_utils import EtatAssiduite, localize_datetime, verif_interval
|
from app.scodoc.sco_utils import EtatAssiduite, localize_datetime, is_period_overlapping
|
||||||
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ class Assiduite(db.Model):
|
|||||||
__tablename__ = "assiduites"
|
__tablename__ = "assiduites"
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
assiduiteid = db.synonym("id")
|
assiduite_id = db.synonym("id")
|
||||||
|
|
||||||
date_debut = db.Column(
|
date_debut = db.Column(
|
||||||
db.DateTime(timezone=True), server_default=db.func.now(), nullable=False
|
db.DateTime(timezone=True), server_default=db.func.now(), nullable=False
|
||||||
@ -42,7 +42,7 @@ class Assiduite(db.Model):
|
|||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
data = {
|
data = {
|
||||||
"assiduiteid": self.assiduiteid,
|
"assiduite_id": self.assiduite_id,
|
||||||
"etudid": self.etudid,
|
"etudid": self.etudid,
|
||||||
"moduleimpl_id": self.moduleimpl_id,
|
"moduleimpl_id": self.moduleimpl_id,
|
||||||
"date_debut": self.date_debut,
|
"date_debut": self.date_debut,
|
||||||
@ -58,13 +58,9 @@ class Assiduite(db.Model):
|
|||||||
date_debut: datetime,
|
date_debut: datetime,
|
||||||
date_fin: datetime,
|
date_fin: datetime,
|
||||||
etat: EtatAssiduite,
|
etat: EtatAssiduite,
|
||||||
module: int or None = None,
|
moduleimpl: ModuleImpl = None,
|
||||||
) -> object or int:
|
) -> object or int:
|
||||||
"""Créer une nouvelle assiduité pour l'étudiant
|
"""Créer une nouvelle assiduité pour l'étudiant"""
|
||||||
Documentation des codes d'erreurs renvoyés:
|
|
||||||
1: Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)
|
|
||||||
2: l'ID du module_impl n'existe pas.
|
|
||||||
"""
|
|
||||||
# Vérification de non duplication des périodes
|
# Vérification de non duplication des périodes
|
||||||
assiduites: list[Assiduite] = etud.assiduites.all()
|
assiduites: list[Assiduite] = etud.assiduites.all()
|
||||||
|
|
||||||
@ -73,26 +69,28 @@ class Assiduite(db.Model):
|
|||||||
assiduites = [
|
assiduites = [
|
||||||
ass
|
ass
|
||||||
for ass in assiduites
|
for ass in assiduites
|
||||||
if verif_interval(
|
if is_period_overlapping(
|
||||||
(date_debut, date_fin),
|
(date_debut, date_fin),
|
||||||
(ass.date_debut, ass.date_fin),
|
(ass.date_debut, ass.date_fin),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
if len(assiduites) != 0:
|
if len(assiduites) != 0:
|
||||||
return 1
|
raise ScoValueError(
|
||||||
|
"Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)"
|
||||||
|
)
|
||||||
|
|
||||||
if module is not None:
|
if moduleimpl is not None:
|
||||||
# Vérification de l'existance du module pour l'étudiant
|
# Vérification de l'existence du module pour l'étudiant
|
||||||
if cls.verif_moduleimpl(module, etud):
|
if moduleimpl.est_inscrit(etud):
|
||||||
nouv_assiduite = Assiduite(
|
nouv_assiduite = Assiduite(
|
||||||
date_debut=date_debut,
|
date_debut=date_debut,
|
||||||
date_fin=date_fin,
|
date_fin=date_fin,
|
||||||
etat=etat,
|
etat=etat,
|
||||||
etudiant=etud,
|
etudiant=etud,
|
||||||
moduleimpl_id=module,
|
moduleimpl_id=moduleimpl.id,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return 2
|
raise ScoValueError("L'étudiant n'est pas inscrit au moduleimpl")
|
||||||
else:
|
else:
|
||||||
nouv_assiduite = Assiduite(
|
nouv_assiduite = Assiduite(
|
||||||
date_debut=date_debut,
|
date_debut=date_debut,
|
||||||
@ -103,30 +101,6 @@ class Assiduite(db.Model):
|
|||||||
|
|
||||||
return nouv_assiduite
|
return nouv_assiduite
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def verif_moduleimpl(moduleimpl_id: int, etud: Identite or int) -> bool:
|
|
||||||
"""
|
|
||||||
Vérifie si l'étudiant est bien inscrit au moduleimpl
|
|
||||||
|
|
||||||
Retourne Vrai si c'est le cas, faux sinon
|
|
||||||
"""
|
|
||||||
output = True
|
|
||||||
module: ModuleImpl = ModuleImpl.query.filter_by(
|
|
||||||
moduleimpl_id=moduleimpl_id
|
|
||||||
).first()
|
|
||||||
if module is None:
|
|
||||||
output = False
|
|
||||||
|
|
||||||
if output:
|
|
||||||
search_etudid: int = etud.id if type(etud) == Identite else etud
|
|
||||||
is_module: int = ModuleImplInscription.query.filter_by(
|
|
||||||
etudid=search_etudid, moduleimpl_id=moduleimpl_id
|
|
||||||
).count()
|
|
||||||
|
|
||||||
output = is_module > 0
|
|
||||||
|
|
||||||
return output
|
|
||||||
|
|
||||||
|
|
||||||
class Justificatif(db.Model):
|
class Justificatif(db.Model):
|
||||||
"""
|
"""
|
||||||
@ -138,7 +112,7 @@ class Justificatif(db.Model):
|
|||||||
|
|
||||||
__tablename__ = "justificatifs"
|
__tablename__ = "justificatifs"
|
||||||
|
|
||||||
justifid = db.Column(db.Integer, primary_key=True)
|
justif_id = db.Column(db.Integer, primary_key=True)
|
||||||
|
|
||||||
date_debut = db.Column(
|
date_debut = db.Column(
|
||||||
db.DateTime(timezone=True), server_default=db.func.now(), nullable=False
|
db.DateTime(timezone=True), server_default=db.func.now(), nullable=False
|
||||||
@ -158,11 +132,18 @@ class Justificatif(db.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
raison = db.Column(db.Text())
|
raison = db.Column(db.Text())
|
||||||
fichier = db.Column(db.Integer())
|
|
||||||
|
"""
|
||||||
|
Les documents liés à l'étudiant sont dans
|
||||||
|
<archivedir>/docetuds/<dept_id>/<etudid>/<YYYY-MM-DD-HH-MM-SS>
|
||||||
|
|
||||||
|
d'après sco_archives.py
|
||||||
|
"""
|
||||||
|
fichier = db.Column(db.Date())
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
data = {
|
data = {
|
||||||
"justifid": self.assiduiteid,
|
"justif_id": self.assiduite_id,
|
||||||
"etudid": self.etudid,
|
"etudid": self.etudid,
|
||||||
"date_debut": self.date_debut,
|
"date_debut": self.date_debut,
|
||||||
"date_fin": self.date_fin,
|
"date_fin": self.date_fin,
|
||||||
|
@ -101,6 +101,22 @@ class ModuleImpl(db.Model):
|
|||||||
d.pop("module", None)
|
d.pop("module", None)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def est_inscrit(self, etud: Identite) -> bool:
|
||||||
|
"""
|
||||||
|
Vérifie si l'étudiant est bien inscrit au moduleimpl
|
||||||
|
|
||||||
|
Retourne Vrai si c'est le cas, faux sinon
|
||||||
|
"""
|
||||||
|
|
||||||
|
is_module: int = (
|
||||||
|
ModuleImplInscription.query.filter_by(
|
||||||
|
etudid=etud.id, moduleimpl_id=self.id
|
||||||
|
).count()
|
||||||
|
> 0
|
||||||
|
)
|
||||||
|
|
||||||
|
return is_module
|
||||||
|
|
||||||
|
|
||||||
# Enseignants (chargés de TD ou TP) d'un moduleimpl
|
# Enseignants (chargés de TD ou TP) d'un moduleimpl
|
||||||
notes_modules_enseignants = db.Table(
|
notes_modules_enseignants = db.Table(
|
||||||
|
@ -150,11 +150,11 @@ def is_iso_formated(date: str, convert=False) -> bool or datetime.datetime or No
|
|||||||
|
|
||||||
|
|
||||||
def localize_datetime(date: datetime.datetime or str) -> datetime.datetime:
|
def localize_datetime(date: datetime.datetime or str) -> datetime.datetime:
|
||||||
if type(date) == str:
|
if isinstance(date, str):
|
||||||
date = is_iso_formated(date, convert=True)
|
date = is_iso_formated(date, convert=True)
|
||||||
|
|
||||||
new_date: datetime.datetime = date
|
new_date: datetime.datetime = date
|
||||||
if date.tzinfo == None:
|
if date.tzinfo is None:
|
||||||
from app.models.assiduites import Assiduite
|
from app.models.assiduites import Assiduite
|
||||||
|
|
||||||
first_assiduite = Assiduite.query.first()
|
first_assiduite = Assiduite.query.first()
|
||||||
@ -167,27 +167,30 @@ def localize_datetime(date: datetime.datetime or str) -> datetime.datetime:
|
|||||||
return new_date
|
return new_date
|
||||||
|
|
||||||
|
|
||||||
def verif_interval(
|
def is_period_overlapping(
|
||||||
periode: tuple[datetime.datetime], interval: tuple[datetime.datetime]
|
periode: tuple[datetime.datetime, datetime.datetime],
|
||||||
|
interval: tuple[datetime.datetime, datetime.datetime],
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
Vérifie si une période est comprise dans un interval, chevauche l'interval ou comprend l'interval
|
Vérifie si la période et l'interval s'intersectent
|
||||||
|
|
||||||
Retourne Vrai si c'est le cas, faux sinon
|
Retourne Vrai si c'est le cas, faux sinon
|
||||||
"""
|
"""
|
||||||
p_deb, p_fin = periode
|
p_deb, p_fin = periode
|
||||||
i_deb, i_fin = interval
|
i_deb, i_fin = interval
|
||||||
|
|
||||||
i = intervalmap()
|
# i = intervalmap()
|
||||||
p = intervalmap()
|
# p = intervalmap()
|
||||||
i[:] = 0
|
# i[:] = 0
|
||||||
p[:] = 0
|
# p[:] = 0
|
||||||
i[i_deb:i_fin] = 1
|
# i[i_deb:i_fin] = 1
|
||||||
p[p_deb:p_fin] = 1
|
# p[p_deb:p_fin] = 1
|
||||||
|
|
||||||
res: int = sum((i[p_deb], i[p_fin], p[i_deb], p[i_fin]))
|
# # TOTALK: Vérification des bornes de la période dans l'interval et inversement
|
||||||
|
# res: int = sum((i[p_deb], i[p_fin], p[i_deb], p[i_fin]))
|
||||||
|
|
||||||
return res > 0
|
# return res > 0
|
||||||
|
return p_deb <= i_fin and p_fin >= i_deb
|
||||||
|
|
||||||
|
|
||||||
# Types de modules
|
# Types de modules
|
||||||
|
@ -15,7 +15,7 @@ MODULE = 1
|
|||||||
|
|
||||||
|
|
||||||
ASSIDUITES_FIELDS = {
|
ASSIDUITES_FIELDS = {
|
||||||
"assiduiteid": int,
|
"assiduite_id": int,
|
||||||
"etudid": int,
|
"etudid": int,
|
||||||
"moduleimpl_id": int,
|
"moduleimpl_id": int,
|
||||||
"date_debut": str,
|
"date_debut": str,
|
||||||
@ -23,7 +23,7 @@ ASSIDUITES_FIELDS = {
|
|||||||
"etat": str,
|
"etat": str,
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_FIELD = {"assiduiteid": int}
|
CREATE_FIELD = {"assiduite_id": int}
|
||||||
BATCH_FIELD = {"errors": dict, "success": dict}
|
BATCH_FIELD = {"errors": dict, "success": dict}
|
||||||
|
|
||||||
COUNT_FIELDS = {"compte": int, "journee": int, "demi": int, "heure": float}
|
COUNT_FIELDS = {"compte": int, "journee": int, "demi": int, "heure": float}
|
||||||
@ -86,7 +86,6 @@ def test_route_assiduite(api_headers):
|
|||||||
check_failure_get(
|
check_failure_get(
|
||||||
f"/assiduite/{FAUX}",
|
f"/assiduite/{FAUX}",
|
||||||
api_headers,
|
api_headers,
|
||||||
"assiduité inexistante",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -195,12 +194,12 @@ def test_route_create(api_headers):
|
|||||||
|
|
||||||
res = POST_JSON(f"/assiduite/{ETUDID}/create", data, api_headers)
|
res = POST_JSON(f"/assiduite/{ETUDID}/create", data, api_headers)
|
||||||
check_fields(res, CREATE_FIELD)
|
check_fields(res, CREATE_FIELD)
|
||||||
TO_REMOVE.append(res["assiduiteid"])
|
TO_REMOVE.append(res["assiduite_id"])
|
||||||
|
|
||||||
data2 = create_data("absent", "02", MODULE)
|
data2 = create_data("absent", "02", MODULE)
|
||||||
res = POST_JSON(f"/assiduite/{ETUDID}/create", data2, api_headers)
|
res = POST_JSON(f"/assiduite/{ETUDID}/create", data2, api_headers)
|
||||||
check_fields(res, CREATE_FIELD)
|
check_fields(res, CREATE_FIELD)
|
||||||
TO_REMOVE.append(res["assiduiteid"])
|
TO_REMOVE.append(res["assiduite_id"])
|
||||||
|
|
||||||
# Mauvais fonctionnement
|
# Mauvais fonctionnement
|
||||||
check_failure_post(f"/assiduite/{FAUX}/create", api_headers, data)
|
check_failure_post(f"/assiduite/{FAUX}/create", api_headers, data)
|
||||||
@ -208,13 +207,13 @@ def test_route_create(api_headers):
|
|||||||
f"/assiduite/{ETUDID}/create",
|
f"/assiduite/{ETUDID}/create",
|
||||||
api_headers,
|
api_headers,
|
||||||
data,
|
data,
|
||||||
err="La période sélectionnée est déjà couverte par une autre assiduite",
|
err="Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)",
|
||||||
)
|
)
|
||||||
check_failure_post(
|
check_failure_post(
|
||||||
f"/assiduite/{ETUDID}/create",
|
f"/assiduite/{ETUDID}/create",
|
||||||
api_headers,
|
api_headers,
|
||||||
create_data("absent", "03", FAUX),
|
create_data("absent", "03", FAUX),
|
||||||
err="L'étudiant ne participe pas au moduleimpl sélectionné",
|
err="param 'moduleimpl_id': invalide",
|
||||||
)
|
)
|
||||||
|
|
||||||
# -== Avec batch ==-
|
# -== Avec batch ==-
|
||||||
@ -233,7 +232,7 @@ def test_route_create(api_headers):
|
|||||||
check_fields(res, BATCH_FIELD)
|
check_fields(res, BATCH_FIELD)
|
||||||
for dat in res["success"]:
|
for dat in res["success"]:
|
||||||
check_fields(res["success"][dat], CREATE_FIELD)
|
check_fields(res["success"][dat], CREATE_FIELD)
|
||||||
TO_REMOVE.append(res["success"][dat]["assiduiteid"])
|
TO_REMOVE.append(res["success"][dat]["assiduite_id"])
|
||||||
|
|
||||||
# Mauvais Fonctionnement
|
# Mauvais Fonctionnement
|
||||||
|
|
||||||
@ -252,9 +251,9 @@ def test_route_create(api_headers):
|
|||||||
|
|
||||||
assert (
|
assert (
|
||||||
res["errors"]["0"]
|
res["errors"]["0"]
|
||||||
== "La période sélectionnée est déjà couverte par une autre assiduite"
|
== "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)"
|
||||||
)
|
)
|
||||||
assert res["errors"]["1"] == "L'étudiant ne participe pas au moduleimpl sélectionné"
|
assert res["errors"]["1"] == "param 'moduleimpl_id': invalide"
|
||||||
assert res["errors"]["2"] == "param 'etat': invalide"
|
assert res["errors"]["2"] == "param 'etat': invalide"
|
||||||
assert (
|
assert (
|
||||||
res["errors"]["3"]
|
res["errors"]["3"]
|
||||||
@ -290,7 +289,7 @@ def test_route_delete(api_headers):
|
|||||||
# -== Sans batch ==-
|
# -== Sans batch ==-
|
||||||
|
|
||||||
# Bon fonctionnement
|
# Bon fonctionnement
|
||||||
data = {"assiduiteid": TO_REMOVE[0]}
|
data = {"assiduite_id": TO_REMOVE[0]}
|
||||||
|
|
||||||
res = POST_JSON(f"/assiduite/delete", data, api_headers)
|
res = POST_JSON(f"/assiduite/delete", data, api_headers)
|
||||||
assert res == {"OK": True}
|
assert res == {"OK": True}
|
||||||
@ -299,7 +298,7 @@ def test_route_delete(api_headers):
|
|||||||
check_failure_post(
|
check_failure_post(
|
||||||
f"/assiduite/delete",
|
f"/assiduite/delete",
|
||||||
api_headers,
|
api_headers,
|
||||||
{"assiduiteid": FAUX},
|
{"assiduite_id": FAUX},
|
||||||
err="Assiduite non existante",
|
err="Assiduite non existante",
|
||||||
)
|
)
|
||||||
# -== Avec batch ==-
|
# -== Avec batch ==-
|
||||||
|
@ -1,4 +1,24 @@
|
|||||||
"entry_name";"url";"permission";"method";"content"
|
"entry_name";"url";"permission";"method";"content"
|
||||||
|
"assiduite";"/assiduite/1";"ScoView";"GET";
|
||||||
|
"assiduites";"/assiduites/1";"ScoView";"GET";
|
||||||
|
"assiduites";"/assiduites/1/query?etat=retard";"ScoView";"GET";
|
||||||
|
"assiduites";"/assiduites/1/query?moduleimpl_id=1";"ScoView";"GET";
|
||||||
|
"assiduites_count";"/assiduites/1/count";"ScoView";"GET";
|
||||||
|
"assiduites_count";"/assiduites/1/count/query?etat=retard";"ScoView";"GET";
|
||||||
|
"assiduites_count";"/assiduites/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET";
|
||||||
|
"assiduites_formsemestre";"/assiduites/formsemestre/1";"ScoView";"GET";
|
||||||
|
"assiduites_formsemestre";"/assiduites/formsemestre/1/query?etat=retard";"ScoView";"GET";
|
||||||
|
"assiduites_formsemestre";"/assiduites/formsemestre/1/query?moduleimpl_id=1";"ScoView";"GET";
|
||||||
|
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count";"ScoView";"GET";
|
||||||
|
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=retard";"ScoView";"GET";
|
||||||
|
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET";
|
||||||
|
"assiduite_create";"/assiduite/1/create";"ScoView";"POST";"{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""}"
|
||||||
|
"assiduite_create";"/assiduite/1/create/batch";"ScoView";"POST";"{""batch"":[{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""},{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""retard""},{""date_debut"": ""2022-10-27T11:00"",""date_fin"": ""2022-10-27T13:00"",""etat"": ""present""}]}"
|
||||||
|
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"":""absent""}"
|
||||||
|
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""moduleimpl_id"":2}"
|
||||||
|
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"": ""retard"",""moduleimpl_id"":3}"
|
||||||
|
"assiduite_delete";"/assiduite/delete";"ScoView";"POST";"{""assiduite_id"": 1}"
|
||||||
|
"assiduite_delete";"/assiduite/delete/batch";"ScoView";"POST";"{""batch"":[2,2,3]}"
|
||||||
"departements";"/departements";"ScoView";"GET";
|
"departements";"/departements";"ScoView";"GET";
|
||||||
"departements-ids";"/departements_ids";"ScoView";"GET";
|
"departements-ids";"/departements_ids";"ScoView";"GET";
|
||||||
"departement";"/departement/TAPI";"ScoView";"GET";
|
"departement";"/departement/TAPI";"ScoView";"GET";
|
||||||
|
|
@ -14,7 +14,8 @@ from app import db
|
|||||||
|
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
import app.scodoc.sco_assiduites as scass
|
import app.scodoc.sco_assiduites as scass
|
||||||
from app.models import Assiduite, Identite, FormSemestre
|
from app.models import Assiduite, Identite, FormSemestre, ModuleImpl
|
||||||
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
|
|
||||||
@ -62,29 +63,33 @@ def test_general(test_client):
|
|||||||
|
|
||||||
# Création des modulesimpls (4, 2 par semestre)
|
# Création des modulesimpls (4, 2 par semestre)
|
||||||
|
|
||||||
moduleimpl_id_1_1 = G.create_moduleimpl(
|
moduleimpl_1_1 = G.create_moduleimpl(
|
||||||
module_id=module_id_1,
|
module_id=module_id_1,
|
||||||
formsemestre_id=formsemestre_id_1,
|
formsemestre_id=formsemestre_id_1,
|
||||||
)
|
)
|
||||||
moduleimpl_id_1_2 = G.create_moduleimpl(
|
moduleimpl_1_2 = G.create_moduleimpl(
|
||||||
module_id=module_id_2,
|
module_id=module_id_2,
|
||||||
formsemestre_id=formsemestre_id_1,
|
formsemestre_id=formsemestre_id_1,
|
||||||
)
|
)
|
||||||
|
|
||||||
moduleimpl_id_2_1 = G.create_moduleimpl(
|
moduleimpl_2_1 = G.create_moduleimpl(
|
||||||
module_id=module_id_1,
|
module_id=module_id_1,
|
||||||
formsemestre_id=formsemestre_id_2,
|
formsemestre_id=formsemestre_id_2,
|
||||||
)
|
)
|
||||||
moduleimpl_id_2_2 = G.create_moduleimpl(
|
moduleimpl_2_2 = G.create_moduleimpl(
|
||||||
module_id=module_id_2,
|
module_id=module_id_2,
|
||||||
formsemestre_id=formsemestre_id_2,
|
formsemestre_id=formsemestre_id_2,
|
||||||
)
|
)
|
||||||
|
|
||||||
moduleimpls = [
|
moduleimpls = [
|
||||||
moduleimpl_id_1_1,
|
moduleimpl_1_1,
|
||||||
moduleimpl_id_1_2,
|
moduleimpl_1_2,
|
||||||
moduleimpl_id_2_1,
|
moduleimpl_2_1,
|
||||||
moduleimpl_id_2_2,
|
moduleimpl_2_2,
|
||||||
|
]
|
||||||
|
|
||||||
|
moduleimpls = [
|
||||||
|
ModuleImpl.query.filter_by(id=mi_id).first() for mi_id in moduleimpls
|
||||||
]
|
]
|
||||||
|
|
||||||
# Création des étudiants (3)
|
# Création des étudiants (3)
|
||||||
@ -100,7 +105,12 @@ def test_general(test_client):
|
|||||||
|
|
||||||
assert None not in etuds, "Problème avec la conversion en Identite"
|
assert None not in etuds, "Problème avec la conversion en Identite"
|
||||||
|
|
||||||
ajouter_assiduites(etuds, moduleimpls=moduleimpls)
|
# Etudiant faux
|
||||||
|
|
||||||
|
etud_faux_dict = G.create_etud(code_nip=None, prenom="etudfaux")
|
||||||
|
etud_faux = Identite.query.filter_by(id=etud_faux_dict["id"]).first()
|
||||||
|
|
||||||
|
ajouter_assiduites(etuds, moduleimpls, etud_faux)
|
||||||
verifier_comptage_et_filtrage(
|
verifier_comptage_et_filtrage(
|
||||||
etuds, moduleimpls, (formsemestre_1, formsemestre_2, formsemestre_3)
|
etuds, moduleimpls, (formsemestre_1, formsemestre_2, formsemestre_3)
|
||||||
)
|
)
|
||||||
@ -124,7 +134,7 @@ def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]):
|
|||||||
ass1.etat = scu.EtatAssiduite.RETARD
|
ass1.etat = scu.EtatAssiduite.RETARD
|
||||||
db.session.add(ass1)
|
db.session.add(ass1)
|
||||||
# Modification du moduleimpl
|
# Modification du moduleimpl
|
||||||
ass2.moduleimpl_id = moduleimpls[0]
|
ass2.moduleimpl_id = moduleimpls[0].id
|
||||||
db.session.add(ass2)
|
db.session.add(ass2)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
@ -133,7 +143,7 @@ def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]):
|
|||||||
scass.filter_by_etat(etuds[0].assiduites, "retard").count() == 3
|
scass.filter_by_etat(etuds[0].assiduites, "retard").count() == 3
|
||||||
), "Edition d'assiduité mauvais"
|
), "Edition d'assiduité mauvais"
|
||||||
assert (
|
assert (
|
||||||
scass.filter_by_module_impl(etuds[1].assiduites, moduleimpls[0]).count() == 2
|
scass.filter_by_module_impl(etuds[1].assiduites, moduleimpls[0].id).count() == 2
|
||||||
), "Edition d'assiduité mauvais"
|
), "Edition d'assiduité mauvais"
|
||||||
|
|
||||||
# Supression d'une assiduité
|
# Supression d'une assiduité
|
||||||
@ -144,7 +154,9 @@ def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]):
|
|||||||
assert etuds[2].assiduites.count() == 5, "Supression d'assiduité mauvais"
|
assert etuds[2].assiduites.count() == 5, "Supression d'assiduité mauvais"
|
||||||
|
|
||||||
|
|
||||||
def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]):
|
def ajouter_assiduites(
|
||||||
|
etuds: list[Identite], moduleimpls: list[ModuleImpl], etud_faux: Identite
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Première partie:
|
Première partie:
|
||||||
- Ajoute 6 assiduités à chaque étudiant
|
- Ajoute 6 assiduités à chaque étudiant
|
||||||
@ -160,43 +172,43 @@ def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]):
|
|||||||
"etat": scu.EtatAssiduite.PRESENT,
|
"etat": scu.EtatAssiduite.PRESENT,
|
||||||
"deb": "2022-09-03T08:00+01:00",
|
"deb": "2022-09-03T08:00+01:00",
|
||||||
"fin": "2022-09-03T10:00+01:00",
|
"fin": "2022-09-03T10:00+01:00",
|
||||||
"moduleimpl_id": None,
|
"moduleimpl": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.PRESENT,
|
"etat": scu.EtatAssiduite.PRESENT,
|
||||||
"deb": "2023-01-03T08:00+01:00",
|
"deb": "2023-01-03T08:00+01:00",
|
||||||
"fin": "2023-01-03T10:00+01:00",
|
"fin": "2023-01-03T10:00+01:00",
|
||||||
"moduleimpl_id": moduleimpls[2],
|
"moduleimpl": moduleimpls[2],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.ABSENT,
|
"etat": scu.EtatAssiduite.ABSENT,
|
||||||
"deb": "2022-09-03T10:00:01+01:00",
|
"deb": "2022-09-03T10:00:01+01:00",
|
||||||
"fin": "2022-09-03T11:00+01:00",
|
"fin": "2022-09-03T11:00+01:00",
|
||||||
"moduleimpl_id": moduleimpls[0],
|
"moduleimpl": moduleimpls[0],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.ABSENT,
|
"etat": scu.EtatAssiduite.ABSENT,
|
||||||
"deb": "2022-09-03T14:00:00+01:00",
|
"deb": "2022-09-03T14:00:00+01:00",
|
||||||
"fin": "2022-09-03T15:00+01:00",
|
"fin": "2022-09-03T15:00+01:00",
|
||||||
"moduleimpl_id": moduleimpls[1],
|
"moduleimpl": moduleimpls[1],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.RETARD,
|
"etat": scu.EtatAssiduite.RETARD,
|
||||||
"deb": "2023-01-03T11:00:01+01:00",
|
"deb": "2023-01-03T11:00:01+01:00",
|
||||||
"fin": "2023-01-03T12:00+01:00",
|
"fin": "2023-01-03T12:00+01:00",
|
||||||
"moduleimpl_id": moduleimpls[3],
|
"moduleimpl": moduleimpls[3],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.RETARD,
|
"etat": scu.EtatAssiduite.RETARD,
|
||||||
"deb": "2023-01-04T11:00:01+01:00",
|
"deb": "2023-01-04T11:00:01+01:00",
|
||||||
"fin": "2023-01-04T12:00+01:00",
|
"fin": "2023-01-04T12:00+01:00",
|
||||||
"moduleimpl_id": moduleimpls[3],
|
"moduleimpl": moduleimpls[3],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
assiduites = [
|
assiduites = [
|
||||||
Assiduite.create_assiduite(
|
Assiduite.create_assiduite(
|
||||||
etud, ass["deb"], ass["fin"], ass["etat"], ass["moduleimpl_id"]
|
etud, ass["deb"], ass["fin"], ass["etat"], ass["moduleimpl"]
|
||||||
)
|
)
|
||||||
for ass in obj_assiduites
|
for ass in obj_assiduites
|
||||||
]
|
]
|
||||||
@ -208,32 +220,36 @@ def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]):
|
|||||||
|
|
||||||
# Vérification de la gestion des erreurs
|
# Vérification de la gestion des erreurs
|
||||||
|
|
||||||
test_assiduites = [
|
test_assiduite = {
|
||||||
{
|
|
||||||
"etat": scu.EtatAssiduite.RETARD,
|
"etat": scu.EtatAssiduite.RETARD,
|
||||||
"deb": "2023-01-04T11:00:01+01:00",
|
"deb": "2023-01-04T11:00:01+01:00",
|
||||||
"fin": "2023-01-04T12:00+01:00",
|
"fin": "2023-01-04T12:00+01:00",
|
||||||
"moduleimpl_id": moduleimpls[3],
|
"moduleimpl": moduleimpls[3],
|
||||||
},
|
}
|
||||||
{
|
|
||||||
"etat": scu.EtatAssiduite.RETARD,
|
|
||||||
"deb": "2023-01-05T11:00:01+01:00",
|
|
||||||
"fin": "2023-01-05T12:00+01:00",
|
|
||||||
"moduleimpl_id": 1000,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
assiduites_crees = [
|
try:
|
||||||
Assiduite.create_assiduite(
|
Assiduite.create_assiduite(
|
||||||
etuds[0], ass["deb"], ass["fin"], ass["etat"], ass["moduleimpl_id"]
|
etuds[0],
|
||||||
|
test_assiduite["deb"],
|
||||||
|
test_assiduite["fin"],
|
||||||
|
test_assiduite["etat"],
|
||||||
|
test_assiduite["moduleimpl"],
|
||||||
)
|
)
|
||||||
for ass in test_assiduites
|
except ScoValueError as excp:
|
||||||
]
|
assert (
|
||||||
|
excp.args[0]
|
||||||
assert [ass for ass in assiduites_crees if type(ass) != Assiduite] == [
|
== "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)"
|
||||||
1,
|
)
|
||||||
2,
|
try:
|
||||||
], "La vérification des erreurs ne fonctionne pas"
|
Assiduite.create_assiduite(
|
||||||
|
etud_faux,
|
||||||
|
test_assiduite["deb"],
|
||||||
|
test_assiduite["fin"],
|
||||||
|
test_assiduite["etat"],
|
||||||
|
test_assiduite["moduleimpl"],
|
||||||
|
)
|
||||||
|
except ScoValueError as excp:
|
||||||
|
assert excp.args[0] == "L'étudiant n'est pas inscrit au moduleimpl"
|
||||||
|
|
||||||
|
|
||||||
def verifier_comptage_et_filtrage(
|
def verifier_comptage_et_filtrage(
|
||||||
@ -282,16 +298,16 @@ def verifier_comptage_et_filtrage(
|
|||||||
|
|
||||||
# Module
|
# Module
|
||||||
assert (
|
assert (
|
||||||
scass.filter_by_module_impl(etu3.assiduites, mod11).count() == 1
|
scass.filter_by_module_impl(etu3.assiduites, mod11.id).count() == 1
|
||||||
), "Filtrage par 'Moduleimpl' mauvais"
|
), "Filtrage par 'Moduleimpl' mauvais"
|
||||||
assert (
|
assert (
|
||||||
scass.filter_by_module_impl(etu3.assiduites, mod12).count() == 1
|
scass.filter_by_module_impl(etu3.assiduites, mod12.id).count() == 1
|
||||||
), "Filtrage par 'Moduleimpl' mauvais"
|
), "Filtrage par 'Moduleimpl' mauvais"
|
||||||
assert (
|
assert (
|
||||||
scass.filter_by_module_impl(etu3.assiduites, mod21).count() == 1
|
scass.filter_by_module_impl(etu3.assiduites, mod21.id).count() == 1
|
||||||
), "Filtrage par 'Moduleimpl' mauvais"
|
), "Filtrage par 'Moduleimpl' mauvais"
|
||||||
assert (
|
assert (
|
||||||
scass.filter_by_module_impl(etu3.assiduites, mod22).count() == 2
|
scass.filter_by_module_impl(etu3.assiduites, mod22.id).count() == 2
|
||||||
), "Filtrage par 'Moduleimpl' mauvais"
|
), "Filtrage par 'Moduleimpl' mauvais"
|
||||||
assert (
|
assert (
|
||||||
scass.filter_by_module_impl(etu3.assiduites, None).count() == 1
|
scass.filter_by_module_impl(etu3.assiduites, None).count() == 1
|
||||||
|
@ -383,7 +383,7 @@ def ajouter_assiduites(formsemestre: FormSemestre):
|
|||||||
"""
|
"""
|
||||||
Ajoute des assiduités semi-aléatoires à chaque étudiant du semestre
|
Ajoute des assiduités semi-aléatoires à chaque étudiant du semestre
|
||||||
"""
|
"""
|
||||||
MODS = [moduleimpl.id for moduleimpl in formsemestre.modimpls]
|
MODS = [moduleimpl for moduleimpl in formsemestre.modimpls]
|
||||||
MODS.append(None)
|
MODS.append(None)
|
||||||
from app.scodoc.sco_utils import localize_datetime
|
from app.scodoc.sco_utils import localize_datetime
|
||||||
|
|
||||||
@ -394,11 +394,13 @@ def ajouter_assiduites(formsemestre: FormSemestre):
|
|||||||
|
|
||||||
for i in range(random.randint(1, 5)):
|
for i in range(random.randint(1, 5)):
|
||||||
etat = random.randint(0, 2)
|
etat = random.randint(0, 2)
|
||||||
module = random.choice(MODS)
|
moduleimpl = random.choice(MODS)
|
||||||
deb_date = base_date + datetime.timedelta(days=i)
|
deb_date = base_date + datetime.timedelta(days=i)
|
||||||
fin_date = deb_date + datetime.timedelta(hours=i)
|
fin_date = deb_date + datetime.timedelta(hours=i)
|
||||||
|
|
||||||
code = Assiduite.create_assiduite(etud, deb_date, fin_date, etat, module)
|
code = Assiduite.create_assiduite(
|
||||||
|
etud, deb_date, fin_date, etat, moduleimpl
|
||||||
|
)
|
||||||
|
|
||||||
assert isinstance(
|
assert isinstance(
|
||||||
code, Assiduite
|
code, Assiduite
|
||||||
|
Loading…
Reference in New Issue
Block a user