1
0
forked from ScoDoc/ScoDoc

Assiduites : optimisation justification

This commit is contained in:
iziram 2023-07-30 16:34:05 +02:00
parent ead32c8a06
commit cab5a71925
4 changed files with 73 additions and 39 deletions

View File

@ -17,7 +17,14 @@ import app.scodoc.sco_utils as scu
from app.api import api_bp as bp from app.api import api_bp as bp
from app.api import api_web_bp, get_model_api_object, tools from app.api import api_web_bp, get_model_api_object, tools
from app.decorators import permission_required, scodoc from app.decorators import permission_required, scodoc
from app.models import Assiduite, FormSemestre, Identite, ModuleImpl, Scolog from app.models import (
Assiduite,
FormSemestre,
Identite,
ModuleImpl,
Scolog,
Justificatif,
)
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_permissions import Permission from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_utils import json_error from app.scodoc.sco_utils import json_error
@ -47,6 +54,34 @@ def assiduite(assiduite_id: int = None):
return get_model_api_object(Assiduite, assiduite_id, Identite) return get_model_api_object(Assiduite, assiduite_id, Identite)
@bp.route("/assiduite/<int:assiduite_id>/justificatifs")
@api_web_bp.route("/assiduite/<int:assiduite_id>/justificatifs")
@scodoc
@permission_required(Permission.ScoView)
@as_json
def assiduite_justificatifs(assiduite_id: int = None):
"""Retourne la liste des justificatifs qui justifie cette assiduitée
Exemple de résultat:
[
1,
2,
3,
...
]
"""
assi: Assiduite = Assiduite.query.get_or_404(assiduite_id)
justifs: Justificatif = Justificatif.query.filter(
Justificatif.etudid == assi.etudid,
Justificatif.date_debut <= assi.date_debut,
Justificatif.date_fin >= assi.date_fin,
)
return [j.justif_id for j in justifs]
# etudid # etudid
@bp.route("/assiduites/<etudid>/count", defaults={"with_query": False}) @bp.route("/assiduites/<etudid>/count", defaults={"with_query": False})
@api_web_bp.route("/assiduites/<etudid>/count", defaults={"with_query": False}) @api_web_bp.route("/assiduites/<etudid>/count", defaults={"with_query": False})

View File

@ -19,7 +19,9 @@ from app.api import api_web_bp
from app.api import get_model_api_object, tools from app.api import get_model_api_object, tools
from app.decorators import permission_required, scodoc from app.decorators import permission_required, scodoc
from app.models import Identite, Justificatif, Departement from app.models import Identite, Justificatif, Departement
from app.models.assiduites import compute_assiduites_justified from app.models.assiduites import (
compute_assiduites_justified,
)
from app.scodoc.sco_archives_justificatifs import JustificatifArchiver from app.scodoc.sco_archives_justificatifs import JustificatifArchiver
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_permissions import Permission from app.scodoc.sco_permissions import Permission
@ -197,14 +199,16 @@ def justif_create(etudid: int = None, nip=None, ine=None):
errors: list = [] errors: list = []
success: list = [] success: list = []
justifs: list = []
for i, data in enumerate(create_list): for i, data in enumerate(create_list):
code, obj = _create_singular(data, etud) code, obj, justi = _create_singular(data, etud)
if code == 404: if code == 404:
errors.append({"indice": i, "message": obj}) errors.append({"indice": i, "message": obj})
else: else:
success.append({"indice": i, "message": obj}) success.append({"indice": i, "message": obj})
justifs.append(justi)
scass.simple_invalidate_cache(data, etud.id) scass.simple_invalidate_cache(data, etud.id)
compute_assiduites_justified(Justificatif.query.filter_by(etudid=etudid), True) compute_assiduites_justified(etudid, justifs, True)
return {"errors": errors, "success": success} return {"errors": errors, "success": success}
@ -246,7 +250,7 @@ def _create_singular(
if errors: if errors:
err: str = ", ".join(errors) err: str = ", ".join(errors)
return (404, err) return (404, err, None)
# TOUT EST OK # TOUT EST OK
@ -269,6 +273,7 @@ def _create_singular(
"justif_id": nouv_justificatif.id, "justif_id": nouv_justificatif.id,
"couverture": scass.justifies(nouv_justificatif), "couverture": scass.justifies(nouv_justificatif),
}, },
nouv_justificatif,
) )
except ScoValueError as excp: except ScoValueError as excp:
return ( return (
@ -358,7 +363,8 @@ def justif_edit(justif_id: int):
"couverture": { "couverture": {
"avant": avant_ids, "avant": avant_ids,
"après": compute_assiduites_justified( "après": compute_assiduites_justified(
Justificatif.query.filter_by(etudid=justificatif_unique.etudid), justificatif_unique.etudid,
[justificatif_unique],
True, True,
), ),
} }
@ -420,13 +426,11 @@ def _delete_singular(justif_id: int, database):
archiver.delete_justificatif(justificatif_unique.etudid, archive_name) archiver.delete_justificatif(justificatif_unique.etudid, archive_name)
except ValueError: except ValueError:
pass pass
database.session.delete(justificatif_unique)
compute_assiduites_justified( compute_assiduites_justified(
Justificatif.query.filter_by(etudid=justificatif_unique.etudid), True justificatif_unique.etudid, [justificatif_unique], True
) )
scass.simple_invalidate_cache(justificatif_unique.to_dict()) scass.simple_invalidate_cache(justificatif_unique.to_dict())
database.session.delete(justificatif_unique)
return (200, "OK") return (200, "OK")

View File

@ -308,38 +308,36 @@ def is_period_conflicting(
def compute_assiduites_justified( def compute_assiduites_justified(
justificatifs: Justificatif = Justificatif, reset: bool = False etudid: int, justificatifs: list[Justificatif] = None, reset: bool = False
) -> list[int]: ) -> list[int]:
"""Calcule et modifie les champs "est_just" de chaque assiduité lié à l'étud
retourne la liste des assiduite_id justifiées
Si reset alors : met à false toutes les assiduités non justifiées par les justificatifs donnés
""" """
compute_assiduites_justified_faster
list_assiduites_id: set[int] = set() Args:
for justi in justificatifs: etudid (int): l'identifiant de l'étudiant
assiduites: Assiduite = ( justificatifs (list[Justificatif]): La liste des justificatifs qui seront utilisés
Assiduite.query.join(Justificatif, Justificatif.etudid == Assiduite.etudid) reset (bool, optional): remet à false les assiduites non justifiés. Defaults to False.
.filter(justi.etat == EtatJustificatif.VALIDE)
.filter( Returns:
Assiduite.date_debut < justi.date_fin, list[int]: la liste des assiduités qui ont été justifiées.
Assiduite.date_fin > justi.date_debut, """
) if justificatifs is None:
) justificatifs: Justificatif = Justificatif.query.filter_by(etudid=etudid).all()
assiduites: Assiduite = Assiduite.query.filter_by(etudid=etudid)
assiduites_justifiees: list[int] = []
for assi in assiduites: for assi in assiduites:
if any(
assi.date_debut >= j.date_debut and assi.date_fin <= j.date_fin
for j in justificatifs
):
assi.est_just = True assi.est_just = True
list_assiduites_id.add(assi.id) assiduites_justifiees.append(assi.assiduite_id)
db.session.add(assi) db.session.add(assi)
elif reset:
if reset:
un_justified: Assiduite = Assiduite.query.filter(
Assiduite.id.not_in(list_assiduites_id)
).join(Justificatif, Justificatif.etudid == Assiduite.etudid)
for assi in un_justified:
assi.est_just = False assi.est_just = False
db.session.add(assi) db.session.add(assi)
db.session.commit() db.session.commit()
return list(list_assiduites_id) return assiduites_justifiees

View File

@ -21,9 +21,6 @@ from app.models import (
from app.models.config import ScoDocSiteConfig from app.models.config import ScoDocSiteConfig
from app.models.assiduites import (
compute_assiduites_justified,
)
from app.profiler import Profiler from app.profiler import Profiler
from app.scodoc.sco_utils import ( from app.scodoc.sco_utils import (
EtatAssiduite, EtatAssiduite,