Utilise ScoDocModel pour create_justificatif. Ajout get_fichiers.

This commit is contained in:
Emmanuel Viennet 2023-12-22 15:22:57 +01:00
parent 91bca7eed9
commit 0441e6cd64

View File

@ -2,15 +2,24 @@
"""Gestion de l'assiduité (assiduités + justificatifs) """Gestion de l'assiduité (assiduités + justificatifs)
""" """
from datetime import datetime from datetime import datetime
from flask_login import current_user
from flask_sqlalchemy.query import Query from flask_sqlalchemy.query import Query
from app import db, log, g, set_sco_dept from app import db, log, g, set_sco_dept
from app.models import ModuleImpl, Module, Scolog, FormSemestre, FormSemestreInscription from app.models import (
ModuleImpl,
Module,
Scolog,
FormSemestre,
FormSemestreInscription,
ScoDocModel,
)
from app.models.etudiants import Identite from app.models.etudiants import Identite
from app.auth.models import User from app.auth.models import User
from app.scodoc import sco_abs_notification from app.scodoc import sco_abs_notification
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_utils import ( from app.scodoc.sco_utils import (
EtatAssiduite, EtatAssiduite,
EtatJustificatif, EtatJustificatif,
@ -19,7 +28,7 @@ from app.scodoc.sco_utils import (
) )
class Assiduite(db.Model): class Assiduite(ScoDocModel):
""" """
Représente une assiduité: Représente une assiduité:
- une plage horaire lié à un état et un étudiant - une plage horaire lié à un état et un étudiant
@ -136,7 +145,7 @@ class Assiduite(db.Model):
notify_mail=False, notify_mail=False,
) -> "Assiduite": ) -> "Assiduite":
"""Créer une nouvelle assiduité pour l'étudiant. """Créer une nouvelle assiduité pour l'étudiant.
Les datetime doivent être en timzone serveur. Les datetime doivent être en timezone serveur.
Raises ScoValueError en cas de conflit ou erreur. Raises ScoValueError en cas de conflit ou erreur.
""" """
if date_debut.tzinfo is None: if date_debut.tzinfo is None:
@ -301,7 +310,7 @@ class Assiduite(db.Model):
return "Non spécifié" if traduire else None return "Non spécifié" if traduire else None
class Justificatif(db.Model): class Justificatif(ScoDocModel):
""" """
Représente un justificatif: Représente un justificatif:
- une plage horaire lié à un état et un étudiant - une plage horaire lié à un état et un étudiant
@ -356,6 +365,14 @@ class Justificatif(db.Model):
external_data = db.Column(db.JSON, nullable=True) external_data = db.Column(db.JSON, nullable=True)
@classmethod
def get_justificatif(cls, justif_id: int) -> "Justificatif":
"""Justificatif ou 404, cherche uniquement dans le département courant"""
query = Justificatif.query.filter_by(id=justif_id)
if g.scodoc_dept:
query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
return query.first_or_404()
def to_dict(self, format_api: bool = False) -> dict: def to_dict(self, format_api: bool = False) -> dict:
"""transformation de l'objet en dictionnaire sérialisable""" """transformation de l'objet en dictionnaire sérialisable"""
@ -398,10 +415,25 @@ class Justificatif(db.Model):
self.date_fin.strftime("%d/%m/%Y %Hh%M") self.date_fin.strftime("%d/%m/%Y %Hh%M")
}""" }"""
@classmethod
def convert_dict_fields(cls, args: dict) -> dict:
"""Convert fields. Called by ScoDocModel's create_from_dict, edit and from_dict
Raises ScoValueError si paramètres incorrects.
"""
if not isinstance(args["date_debut"], datetime) or not isinstance(
args["date_fin"], datetime
):
raise ScoValueError("type date incorrect")
if args["date_fin"] <= args["date_debut"]:
raise ScoValueError("dates incompatibles")
if args["entry_date"] and not isinstance(args["entry_date"], datetime):
raise ScoValueError("type entry_date incorrect")
return args
@classmethod @classmethod
def create_justificatif( def create_justificatif(
cls, cls,
etud: Identite, etudiant: Identite,
date_debut: datetime, date_debut: datetime,
date_fin: datetime, date_fin: datetime,
etat: EtatJustificatif, etat: EtatJustificatif,
@ -410,24 +442,15 @@ class Justificatif(db.Model):
user_id: int = None, user_id: int = None,
external_data: dict = None, external_data: dict = None,
) -> "Justificatif": ) -> "Justificatif":
"""Créer un nouveau justificatif pour l'étudiant""" """Créer un nouveau justificatif pour l'étudiant.
nouv_justificatif = Justificatif( Raises ScoValueError si paramètres incorrects.
date_debut=date_debut, """
date_fin=date_fin, nouv_justificatif = cls.create_from_dict(locals())
etat=etat,
etudiant=etud,
raison=raison,
entry_date=entry_date,
user_id=user_id,
external_data=external_data,
)
db.session.add(nouv_justificatif)
db.session.commit() db.session.commit()
log(f"create_justificatif: etudid={etud.id} {nouv_justificatif}") log(f"create_justificatif: etudid={etudiant.id} {nouv_justificatif}")
Scolog.logdb( Scolog.logdb(
method="create_justificatif", method="create_justificatif",
etudid=etud.id, etudid=etudiant.id,
msg=f"justificatif: {nouv_justificatif}", msg=f"justificatif: {nouv_justificatif}",
) )
return nouv_justificatif return nouv_justificatif
@ -468,6 +491,25 @@ class Justificatif(db.Model):
True, True,
) )
def get_fichiers(self) -> tuple[list[str], int]:
"""Renvoie la liste des noms de fichiers justicatifs
accessibles par l'utilisateur courant et le nombre total
de fichiers.
(ces fichiers sont dans l'archive associée)
"""
if self.fichier is None:
return [], 0
archive_name: str = self.fichier
archiver: JustificatifArchiver = JustificatifArchiver()
filenames = archiver.list_justificatifs(archive_name, self.etudiant)
accessible_filenames = []
for filename in filenames:
if int(filename[1]) == current_user.id or current_user.has_permission(
Permission.AbsJustifView
):
accessible_filenames.append(filename[0])
return accessible_filenames, len(filenames)
def is_period_conflicting( def is_period_conflicting(
date_debut: datetime, date_debut: datetime,