forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user