module assiduites & justificatifs : révisions ✅
module assiduites : révisions ✅ module assiduites/justificatifs : révisions ✅
This commit is contained in:
parent
4d72fec42d
commit
61d4186ad3
@ -2,7 +2,8 @@
|
||||
"""
|
||||
|
||||
from flask import Blueprint
|
||||
from flask import request
|
||||
from flask import request, g, jsonify
|
||||
from app import db
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc.sco_exceptions import ScoException
|
||||
|
||||
@ -31,6 +32,22 @@ def requested_format(default_format="json", allowed_formats=None):
|
||||
return None
|
||||
|
||||
|
||||
def get_model_api_object(model_cls: db.Model, model_id: int, join_cls: db.Model = None):
|
||||
"""
|
||||
Retourne une réponse contenant la représentation api de l'objet "Model[model_id]"
|
||||
|
||||
Filtrage du département en fonction d'une classe de jointure (eg: Identite, Formsemstre) -> join_cls
|
||||
|
||||
exemple d'utilisation : fonction "justificatif()" -> app/api/justificatifs.py
|
||||
"""
|
||||
query = model_cls.query.filter_by(id=model_id)
|
||||
if g.scodoc_dept and join_cls is not None:
|
||||
query = query.join(join_cls).filter_by(dept_id=g.scodoc_dept_id)
|
||||
unique: model_cls = query.first_or_404()
|
||||
|
||||
return jsonify(unique.to_dict(format_api=True))
|
||||
|
||||
|
||||
from app.api import tokens
|
||||
from app.api import (
|
||||
absences,
|
||||
@ -42,7 +59,7 @@ from app.api import (
|
||||
formations,
|
||||
formsemestres,
|
||||
jury,
|
||||
justificatif,
|
||||
justificatifs,
|
||||
logos,
|
||||
partitions,
|
||||
users,
|
||||
|
@ -14,6 +14,7 @@ import app.scodoc.sco_utils as scu
|
||||
from app import db
|
||||
from app.api import api_bp as bp
|
||||
from app.api import api_web_bp
|
||||
from app.api import get_model_api_object
|
||||
from app.decorators import permission_required, scodoc
|
||||
from app.models import Assiduite, FormSemestre, Identite, ModuleImpl
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
@ -40,7 +41,7 @@ def assiduite(assiduite_id: int = None):
|
||||
}
|
||||
"""
|
||||
|
||||
return scu.get_model_api_object(Assiduite, assiduite_id)
|
||||
return get_model_api_object(Assiduite, assiduite_id, Identite)
|
||||
|
||||
|
||||
@bp.route("/assiduites/<int:etudid>/count", defaults={"with_query": False})
|
||||
|
@ -15,6 +15,7 @@ import app.scodoc.sco_utils as scu
|
||||
from app import db
|
||||
from app.api import api_bp as bp
|
||||
from app.api import api_web_bp
|
||||
from app.api import get_model_api_object
|
||||
from app.decorators import permission_required, scodoc
|
||||
from app.models import Identite, Justificatif
|
||||
from app.models.assiduites import is_period_conflicting
|
||||
@ -56,7 +57,7 @@ def justificatif(justif_id: int = None):
|
||||
|
||||
"""
|
||||
|
||||
return scu.get_model_api_object(Justificatif, justif_id)
|
||||
return get_model_api_object(Justificatif, justif_id, Identite)
|
||||
|
||||
|
||||
@bp.route("/justificatifs/<int:etudid>", defaults={"with_query": False})
|
@ -55,7 +55,7 @@ class Assiduite(db.Model):
|
||||
etat = self.etat
|
||||
|
||||
if format_api:
|
||||
etat = EtatJustificatif.inverse().get(self.etat).name
|
||||
etat = EtatAssiduite.inverse().get(self.etat).name
|
||||
data = {
|
||||
"assiduite_id": self.assiduite_id,
|
||||
"etudid": self.etudid,
|
||||
@ -82,7 +82,6 @@ class Assiduite(db.Model):
|
||||
# Vérification de non duplication des périodes
|
||||
assiduites: list[Assiduite] = etud.assiduites.all()
|
||||
|
||||
assiduites: list[Justificatif] = etud.assiduites.all()
|
||||
if is_period_conflicting(date_debut, date_fin, assiduites):
|
||||
raise ScoValueError(
|
||||
"Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)"
|
||||
|
@ -1026,7 +1026,7 @@ def get_abs_count(etudid, sem):
|
||||
"""
|
||||
return get_abs_count_in_interval(etudid, sem["date_debut_iso"], sem["date_fin_iso"])
|
||||
|
||||
|
||||
# TODO: relier avec module assiduites
|
||||
def get_abs_count_in_interval(etudid, date_debut_iso, date_fin_iso):
|
||||
"""Les comptes d'absences de cet étudiant entre ces deux dates, incluses:
|
||||
tuple (nb abs, nb abs justifiées)
|
||||
|
@ -44,10 +44,10 @@ def get_assiduites_stats(
|
||||
def get_count(assiduites: Assiduite) -> dict[str, int or float]:
|
||||
|
||||
output: dict[str, int or float] = {}
|
||||
output["compte"] = assiduites.count()
|
||||
output["heure"] = 0.0
|
||||
output["journee"] = 0
|
||||
output["demi"] = 0
|
||||
compte: int = assiduites.count()
|
||||
heure: float = 0.0
|
||||
journee: int = 0
|
||||
demi: int = 0
|
||||
|
||||
all_assiduites: list[Assiduite] = assiduites.order_by(Assiduite.date_debut).all()
|
||||
|
||||
@ -62,22 +62,22 @@ def get_count(assiduites: Assiduite) -> dict[str, int or float]:
|
||||
|
||||
for ass in all_assiduites:
|
||||
delta: timedelta = ass.date_fin - ass.date_debut
|
||||
output["heure"] += delta.total_seconds() / 3600
|
||||
heure += delta.total_seconds() / 3600
|
||||
|
||||
ass_time: str = time_check(ass.date_debut)
|
||||
|
||||
if current_day != ass.date_debut.date():
|
||||
current_day = ass.date_debut.date()
|
||||
current_time = ass_time
|
||||
output["demi"] += 1
|
||||
output["journee"] += 1
|
||||
demi += 1
|
||||
journee += 1
|
||||
|
||||
if current_time != ass_time:
|
||||
current_time = ass_time
|
||||
output["demi"] += 1
|
||||
demi += 1
|
||||
|
||||
output["heure"] = round(output["heure"], 2)
|
||||
return output
|
||||
heure = round(heure, 2)
|
||||
return {"compte": compte, "journee": journee, "heure": heure, "demi": demi}
|
||||
|
||||
|
||||
def filter_assiduites_by_etat(assiduites: Assiduite, etat: str) -> Assiduite:
|
||||
|
@ -88,17 +88,6 @@ ETATS_INSCRIPTION = {
|
||||
}
|
||||
|
||||
|
||||
def get_model_api_object(model_cls: db.Model, model_id: int):
|
||||
from app.models import Identite
|
||||
|
||||
query = model_cls.query.filter_by(id=model_id)
|
||||
if g.scodoc_dept:
|
||||
query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
|
||||
unique: model_cls = query.first_or_404()
|
||||
|
||||
return jsonify(unique.to_dict(format_api=True))
|
||||
|
||||
|
||||
class BiDirectionalEnum(Enum):
|
||||
"""Permet la recherche inverse d'un enum
|
||||
Condition : les clés et les valeurs doivent être uniques
|
||||
@ -134,18 +123,6 @@ class EtatAssiduite(int, BiDirectionalEnum):
|
||||
ABSENT = 2
|
||||
|
||||
|
||||
ETAT_ASSIDUITE_NAME = {
|
||||
EtatAssiduite.PRESENT: "present",
|
||||
EtatAssiduite.RETARD: "retard",
|
||||
EtatAssiduite.ABSENT: "absent",
|
||||
}
|
||||
ETATS_ASSIDUITE = {
|
||||
"present": EtatAssiduite.PRESENT,
|
||||
"retard": EtatAssiduite.RETARD,
|
||||
"absent": EtatAssiduite.ABSENT,
|
||||
}
|
||||
|
||||
|
||||
class EtatJustificatif(int, BiDirectionalEnum):
|
||||
"""Code des états des justificatifs"""
|
||||
|
||||
|
@ -19,6 +19,22 @@ from app.scodoc.sco_exceptions import ScoValueError
|
||||
import app.scodoc.sco_utils as scu
|
||||
|
||||
|
||||
class BiInt(int, scu.BiDirectionalEnum):
|
||||
A = 1
|
||||
B = 2
|
||||
|
||||
|
||||
def test_bi_directional_enum(test_client):
|
||||
"""Test le bon fonctionnement de la classe BiDirectionalEnum"""
|
||||
|
||||
assert BiInt.get("A") == BiInt.get("a") == BiInt.A == 1
|
||||
assert BiInt.get("B") == BiInt.get("b") == BiInt.B == 2
|
||||
assert BiInt.get("blabla") is None
|
||||
assert BiInt.get("blabla", -1) == -1
|
||||
assert isinstance(BiInt.inverse(), dict)
|
||||
assert BiInt.inverse()[1] == BiInt.A and BiInt.inverse()[2] == BiInt.B
|
||||
|
||||
|
||||
def test_general(test_client):
|
||||
"""tests général du modèle assiduite"""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user