module assiduites & justificatifs : révisions

module assiduites : révisions 

module assiduites/justificatifs : révisions 
This commit is contained in:
iziram 2023-02-03 16:17:39 +01:00
parent 4d72fec42d
commit 61d4186ad3
8 changed files with 51 additions and 40 deletions

View File

@ -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,

View File

@ -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})

View File

@ -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})

View File

@ -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)"

View File

@ -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)

View File

@ -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:

View File

@ -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"""

View File

@ -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"""