1
0
Fork 0

corrections REV#Emm + samples API (WIP)

This commit is contained in:
iziram 2023-01-05 17:47:32 +01:00
parent 7adc7d824b
commit f3b1b8a3cb
8 changed files with 205 additions and 166 deletions

View File

@ -19,21 +19,22 @@ from app.scodoc.sco_permissions import Permission
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_assiduites as scass
@bp.route("/assiduite/<int:assiduiteid>")
@api_web_bp.route("/assiduite/<int:assiduiteid>")
@bp.route("/assiduite/<int:assiduite_id>")
@api_web_bp.route("/assiduite/<int:assiduite_id>")
@scodoc
@permission_required(Permission.ScoView)
def assiduite(assiduiteid: int = None):
def assiduite(assiduite_id: int = None):
"""Retourne un objet assiduité à partir de son id
Exemple de résultat:
{
"assiduiteid": 1,
"assiduite_id": 1,
"etudid": 2,
"moduleimpl_id": 3,
"date_debut": "2022-10-31T08:00+01:00",
@ -42,9 +43,11 @@ def assiduite(assiduiteid: int = None):
}
"""
assiduite = Assiduite.query.get(assiduiteid)
if assiduite is None:
return json_error(404, message="assiduité inexistante")
query = Assiduite.query.filter_by(id=assiduite_id)
# if g.scodoc_dept:
# query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
assiduite = query.first_or_404()
data = assiduite.to_dict()
@ -346,13 +349,12 @@ def create_singular(
# cas 4 : moduleimpl_id
moduleimpl_id = data.get("moduleimpl_id", None)
if moduleimpl_id is not None:
try:
moduleimpl_id: int = int(moduleimpl_id)
if moduleimpl_id < 0:
raise Exception
except:
moduleimpl_id = data.get("moduleimpl_id", False)
moduleimpl: ModuleImpl = None
if moduleimpl_id is not False:
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first()
if moduleimpl is None:
errors.append("param 'moduleimpl_id': invalide")
if errors != []:
@ -360,26 +362,24 @@ def create_singular(
return (404, err)
# TOUT EST OK
nouv_assiduite: Assiduite or int = Assiduite.create_assiduite(
date_debut=deb,
date_fin=fin,
etat=etat,
etud=etud,
module=moduleimpl_id,
)
if type(nouv_assiduite) is Assiduite:
try:
nouv_assiduite: Assiduite = Assiduite.create_assiduite(
date_debut=deb,
date_fin=fin,
etat=etat,
etud=etud,
moduleimpl=moduleimpl,
)
db.session.add(nouv_assiduite)
db.session.commit()
return (200, {"assiduiteid": nouv_assiduite.assiduiteid})
return (
404,
{
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),
)
return (200, {"assiduite_id": nouv_assiduite.assiduite_id})
except ScoValueError as excp:
return (
404,
excp.args[0],
)
@bp.route("/assiduite/delete", methods=["POST"], defaults={"batch": False})
@ -417,7 +417,7 @@ def delete(batch: bool = False):
else:
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:
return json_error(code, msg)
@ -434,13 +434,13 @@ def delete_singular(assiduite_id: int, db):
return (200, "OK")
@bp.route("/assiduite/<int:assiduiteid>/edit", methods=["POST"])
@api_web_bp.route("/assiduite/<int:assiduiteid>/edit", methods=["POST"])
@bp.route("/assiduite/<int:assiduite_id>/edit", methods=["POST"])
@api_web_bp.route("/assiduite/<int:assiduite_id>/edit", methods=["POST"])
@login_required
@scodoc
@permission_required(Permission.ScoView)
# @permission_required(Permission.ScoAssiduiteChange)
def edit(assiduiteid: int):
def edit(assiduite_id: int):
"""
Edition d'une assiduité à partir de son id
La requête doit avoir un content type "application/json":
@ -449,7 +449,7 @@ def edit(assiduiteid: 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] = []
data = request.get_json(force=True)
@ -465,18 +465,20 @@ def edit(assiduiteid: int):
# Cas 2 : Moduleimpl_id
moduleimpl_id = data.get("moduleimpl_id", False)
if moduleimpl_id is not False:
try:
if moduleimpl_id is not None:
moduleimpl_id: int = int(moduleimpl_id)
if moduleimpl_id < 0 or not Assiduite.verif_moduleimpl(
moduleimpl_id, assiduite.etudid
):
errors.append("param 'moduleimpl_id': etud non inscrit")
moduleimpl: ModuleImpl = None
assiduite.moduleimpl_id = moduleimpl_id
except:
if moduleimpl_id is not False:
if moduleimpl_id is not None:
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first()
if moduleimpl is None:
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")
else:
assiduite.moduleimpl_id = moduleimpl_id
if errors != []:
err: str = ", ".join(errors)

View File

@ -4,8 +4,8 @@
from app import db
from app.models import ModuleImpl, ModuleImplInscription
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
@ -19,7 +19,7 @@ class Assiduite(db.Model):
__tablename__ = "assiduites"
id = db.Column(db.Integer, primary_key=True)
assiduiteid = db.synonym("id")
assiduite_id = db.synonym("id")
date_debut = db.Column(
db.DateTime(timezone=True), server_default=db.func.now(), nullable=False
@ -42,7 +42,7 @@ class Assiduite(db.Model):
def to_dict(self) -> dict:
data = {
"assiduiteid": self.assiduiteid,
"assiduite_id": self.assiduite_id,
"etudid": self.etudid,
"moduleimpl_id": self.moduleimpl_id,
"date_debut": self.date_debut,
@ -58,13 +58,9 @@ class Assiduite(db.Model):
date_debut: datetime,
date_fin: datetime,
etat: EtatAssiduite,
module: int or None = None,
moduleimpl: ModuleImpl = None,
) -> object or int:
"""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.
"""
"""Créer une nouvelle assiduité pour l'étudiant"""
# Vérification de non duplication des périodes
assiduites: list[Assiduite] = etud.assiduites.all()
@ -73,26 +69,28 @@ class Assiduite(db.Model):
assiduites = [
ass
for ass in assiduites
if verif_interval(
if is_period_overlapping(
(date_debut, date_fin),
(ass.date_debut, ass.date_fin),
)
]
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:
# Vérification de l'existance du module pour l'étudiant
if cls.verif_moduleimpl(module, etud):
if moduleimpl is not None:
# Vérification de l'existence du module pour l'étudiant
if moduleimpl.est_inscrit(etud):
nouv_assiduite = Assiduite(
date_debut=date_debut,
date_fin=date_fin,
etat=etat,
etudiant=etud,
moduleimpl_id=module,
moduleimpl_id=moduleimpl.id,
)
else:
return 2
raise ScoValueError("L'étudiant n'est pas inscrit au moduleimpl")
else:
nouv_assiduite = Assiduite(
date_debut=date_debut,
@ -103,30 +101,6 @@ class Assiduite(db.Model):
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):
"""
@ -138,7 +112,7 @@ class Justificatif(db.Model):
__tablename__ = "justificatifs"
justifid = db.Column(db.Integer, primary_key=True)
justif_id = db.Column(db.Integer, primary_key=True)
date_debut = db.Column(
db.DateTime(timezone=True), server_default=db.func.now(), nullable=False
@ -158,11 +132,18 @@ class Justificatif(db.Model):
)
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:
data = {
"justifid": self.assiduiteid,
"justif_id": self.assiduite_id,
"etudid": self.etudid,
"date_debut": self.date_debut,
"date_fin": self.date_fin,

View File

@ -101,6 +101,22 @@ class ModuleImpl(db.Model):
d.pop("module", None)
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
notes_modules_enseignants = db.Table(

View File

@ -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:
if type(date) == str:
if isinstance(date, str):
date = is_iso_formated(date, convert=True)
new_date: datetime.datetime = date
if date.tzinfo == None:
if date.tzinfo is None:
from app.models.assiduites import Assiduite
first_assiduite = Assiduite.query.first()
@ -167,27 +167,30 @@ def localize_datetime(date: datetime.datetime or str) -> datetime.datetime:
return new_date
def verif_interval(
periode: tuple[datetime.datetime], interval: tuple[datetime.datetime]
def is_period_overlapping(
periode: tuple[datetime.datetime, datetime.datetime],
interval: tuple[datetime.datetime, datetime.datetime],
) -> 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
"""
p_deb, p_fin = periode
i_deb, i_fin = interval
i = intervalmap()
p = intervalmap()
i[:] = 0
p[:] = 0
i[i_deb:i_fin] = 1
p[p_deb:p_fin] = 1
# i = intervalmap()
# p = intervalmap()
# i[:] = 0
# p[:] = 0
# i[i_deb:i_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

View File

@ -15,7 +15,7 @@ MODULE = 1
ASSIDUITES_FIELDS = {
"assiduiteid": int,
"assiduite_id": int,
"etudid": int,
"moduleimpl_id": int,
"date_debut": str,
@ -23,7 +23,7 @@ ASSIDUITES_FIELDS = {
"etat": str,
}
CREATE_FIELD = {"assiduiteid": int}
CREATE_FIELD = {"assiduite_id": int}
BATCH_FIELD = {"errors": dict, "success": dict}
COUNT_FIELDS = {"compte": int, "journee": int, "demi": int, "heure": float}
@ -86,7 +86,6 @@ def test_route_assiduite(api_headers):
check_failure_get(
f"/assiduite/{FAUX}",
api_headers,
"assiduité inexistante",
)
@ -195,12 +194,12 @@ def test_route_create(api_headers):
res = POST_JSON(f"/assiduite/{ETUDID}/create", data, api_headers)
check_fields(res, CREATE_FIELD)
TO_REMOVE.append(res["assiduiteid"])
TO_REMOVE.append(res["assiduite_id"])
data2 = create_data("absent", "02", MODULE)
res = POST_JSON(f"/assiduite/{ETUDID}/create", data2, api_headers)
check_fields(res, CREATE_FIELD)
TO_REMOVE.append(res["assiduiteid"])
TO_REMOVE.append(res["assiduite_id"])
# Mauvais fonctionnement
check_failure_post(f"/assiduite/{FAUX}/create", api_headers, data)
@ -208,13 +207,13 @@ def test_route_create(api_headers):
f"/assiduite/{ETUDID}/create",
api_headers,
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(
f"/assiduite/{ETUDID}/create",
api_headers,
create_data("absent", "03", FAUX),
err="L'étudiant ne participe pas au moduleimpl sélectionné",
err="param 'moduleimpl_id': invalide",
)
# -== Avec batch ==-
@ -233,7 +232,7 @@ def test_route_create(api_headers):
check_fields(res, BATCH_FIELD)
for dat in res["success"]:
check_fields(res["success"][dat], CREATE_FIELD)
TO_REMOVE.append(res["success"][dat]["assiduiteid"])
TO_REMOVE.append(res["success"][dat]["assiduite_id"])
# Mauvais Fonctionnement
@ -252,9 +251,9 @@ def test_route_create(api_headers):
assert (
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"]["3"]
@ -290,7 +289,7 @@ def test_route_delete(api_headers):
# -== Sans batch ==-
# Bon fonctionnement
data = {"assiduiteid": TO_REMOVE[0]}
data = {"assiduite_id": TO_REMOVE[0]}
res = POST_JSON(f"/assiduite/delete", data, api_headers)
assert res == {"OK": True}
@ -299,7 +298,7 @@ def test_route_delete(api_headers):
check_failure_post(
f"/assiduite/delete",
api_headers,
{"assiduiteid": FAUX},
{"assiduite_id": FAUX},
err="Assiduite non existante",
)
# -== Avec batch ==-

View File

@ -1,4 +1,24 @@
"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-ids";"/departements_ids";"ScoView";"GET";
"departement";"/departement/TAPI";"ScoView";"GET";

1 entry_name url permission method content
2 assiduite /assiduite/1 ScoView GET
3 assiduites /assiduites/1 ScoView GET
4 assiduites /assiduites/1/query?etat=retard ScoView GET
5 assiduites /assiduites/1/query?moduleimpl_id=1 ScoView GET
6 assiduites_count /assiduites/1/count ScoView GET
7 assiduites_count /assiduites/1/count/query?etat=retard ScoView GET
8 assiduites_count /assiduites/1/count/query?etat=present,retard&metric=compte,heure ScoView GET
9 assiduites_formsemestre /assiduites/formsemestre/1 ScoView GET
10 assiduites_formsemestre /assiduites/formsemestre/1/query?etat=retard ScoView GET
11 assiduites_formsemestre /assiduites/formsemestre/1/query?moduleimpl_id=1 ScoView GET
12 assiduites_formsemestre_count /assiduites/formsemestre/1/count ScoView GET
13 assiduites_formsemestre_count /assiduites/formsemestre/1/count/query?etat=retard ScoView GET
14 assiduites_formsemestre_count /assiduites/formsemestre/1/count/query?etat=present,retard&metric=compte,heure ScoView GET
15 assiduite_create /assiduite/1/create ScoView POST {"date_debut": "2022-10-27T08:00","date_fin": "2022-10-27T10:00","etat": "absent"}
16 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"}]}
17 assiduite_edit /assiduite/1/edit ScoView POST {"etat":"absent"}
18 assiduite_edit /assiduite/1/edit ScoView POST {"moduleimpl_id":2}
19 assiduite_edit /assiduite/1/edit ScoView POST {"etat": "retard","moduleimpl_id":3}
20 assiduite_delete /assiduite/delete ScoView POST {"assiduite_id": 1}
21 assiduite_delete /assiduite/delete/batch ScoView POST {"batch":[2,2,3]}
22 departements /departements ScoView GET
23 departements-ids /departements_ids ScoView GET
24 departement /departement/TAPI ScoView GET

View File

@ -14,7 +14,8 @@ from app import db
from app.scodoc import sco_formsemestre
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
@ -62,29 +63,33 @@ def test_general(test_client):
# 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,
formsemestre_id=formsemestre_id_1,
)
moduleimpl_id_1_2 = G.create_moduleimpl(
moduleimpl_1_2 = G.create_moduleimpl(
module_id=module_id_2,
formsemestre_id=formsemestre_id_1,
)
moduleimpl_id_2_1 = G.create_moduleimpl(
moduleimpl_2_1 = G.create_moduleimpl(
module_id=module_id_1,
formsemestre_id=formsemestre_id_2,
)
moduleimpl_id_2_2 = G.create_moduleimpl(
moduleimpl_2_2 = G.create_moduleimpl(
module_id=module_id_2,
formsemestre_id=formsemestre_id_2,
)
moduleimpls = [
moduleimpl_id_1_1,
moduleimpl_id_1_2,
moduleimpl_id_2_1,
moduleimpl_id_2_2,
moduleimpl_1_1,
moduleimpl_1_2,
moduleimpl_2_1,
moduleimpl_2_2,
]
moduleimpls = [
ModuleImpl.query.filter_by(id=mi_id).first() for mi_id in moduleimpls
]
# 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"
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(
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
db.session.add(ass1)
# Modification du moduleimpl
ass2.moduleimpl_id = moduleimpls[0]
ass2.moduleimpl_id = moduleimpls[0].id
db.session.add(ass2)
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
), "Edition d'assiduité mauvais"
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"
# 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"
def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]):
def ajouter_assiduites(
etuds: list[Identite], moduleimpls: list[ModuleImpl], etud_faux: Identite
):
"""
Première partie:
- Ajoute 6 assiduités à chaque étudiant
@ -160,43 +172,43 @@ def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]):
"etat": scu.EtatAssiduite.PRESENT,
"deb": "2022-09-03T08:00+01:00",
"fin": "2022-09-03T10:00+01:00",
"moduleimpl_id": None,
"moduleimpl": None,
},
{
"etat": scu.EtatAssiduite.PRESENT,
"deb": "2023-01-03T08:00+01:00",
"fin": "2023-01-03T10:00+01:00",
"moduleimpl_id": moduleimpls[2],
"moduleimpl": moduleimpls[2],
},
{
"etat": scu.EtatAssiduite.ABSENT,
"deb": "2022-09-03T10:00:01+01:00",
"fin": "2022-09-03T11:00+01:00",
"moduleimpl_id": moduleimpls[0],
"moduleimpl": moduleimpls[0],
},
{
"etat": scu.EtatAssiduite.ABSENT,
"deb": "2022-09-03T14:00:00+01:00",
"fin": "2022-09-03T15:00+01:00",
"moduleimpl_id": moduleimpls[1],
"moduleimpl": moduleimpls[1],
},
{
"etat": scu.EtatAssiduite.RETARD,
"deb": "2023-01-03T11:00:01+01:00",
"fin": "2023-01-03T12:00+01:00",
"moduleimpl_id": moduleimpls[3],
"moduleimpl": moduleimpls[3],
},
{
"etat": scu.EtatAssiduite.RETARD,
"deb": "2023-01-04T11:00:01+01:00",
"fin": "2023-01-04T12:00+01:00",
"moduleimpl_id": moduleimpls[3],
"moduleimpl": moduleimpls[3],
},
]
assiduites = [
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
]
@ -208,32 +220,36 @@ def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]):
# Vérification de la gestion des erreurs
test_assiduites = [
{
"etat": scu.EtatAssiduite.RETARD,
"deb": "2023-01-04T11:00:01+01:00",
"fin": "2023-01-04T12:00+01:00",
"moduleimpl_id": moduleimpls[3],
},
{
"etat": scu.EtatAssiduite.RETARD,
"deb": "2023-01-05T11:00:01+01:00",
"fin": "2023-01-05T12:00+01:00",
"moduleimpl_id": 1000,
},
]
test_assiduite = {
"etat": scu.EtatAssiduite.RETARD,
"deb": "2023-01-04T11:00:01+01:00",
"fin": "2023-01-04T12:00+01:00",
"moduleimpl": moduleimpls[3],
}
assiduites_crees = [
try:
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
]
assert [ass for ass in assiduites_crees if type(ass) != Assiduite] == [
1,
2,
], "La vérification des erreurs ne fonctionne pas"
except ScoValueError as excp:
assert (
excp.args[0]
== "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)"
)
try:
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(
@ -282,16 +298,16 @@ def verifier_comptage_et_filtrage(
# Module
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"
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"
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"
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"
assert (
scass.filter_by_module_impl(etu3.assiduites, None).count() == 1

View File

@ -383,7 +383,7 @@ def ajouter_assiduites(formsemestre: FormSemestre):
"""
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)
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)):
etat = random.randint(0, 2)
module = random.choice(MODS)
moduleimpl = random.choice(MODS)
deb_date = base_date + datetime.timedelta(days=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(
code, Assiduite