# -*- coding: UTF-8 -* """Gestion de l'assiduité (assiduités + justificatifs) """ from datetime import datetime from app import db from app.models import ModuleImpl from app.models.etudiants import Identite from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_utils import ( EtatAssiduite, EtatJustificatif, is_period_overlapping, localize_datetime, ) class Assiduite(db.Model): """ Représente une assiduité: - une plage horaire lié à un état et un étudiant - un module si spécifiée - une description si spécifiée """ __tablename__ = "assiduites" id = db.Column(db.Integer, primary_key=True) assiduite_id = db.synonym("id") date_debut = db.Column( db.DateTime(timezone=True), server_default=db.func.now(), nullable=False ) date_fin = db.Column( db.DateTime(timezone=True), server_default=db.func.now(), nullable=False ) moduleimpl_id = db.Column( db.Integer, db.ForeignKey("notes_moduleimpl.id", ondelete="SET NULL"), ) etudid = db.Column( db.Integer, db.ForeignKey("identite.id", ondelete="CASCADE"), index=True, nullable=False, ) etat = db.Column(db.Integer, nullable=False) desc = db.Column(db.Text) entry_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) def to_dict(self) -> dict: data = { "assiduite_id": self.assiduite_id, "etudid": self.etudid, "moduleimpl_id": self.moduleimpl_id, "date_debut": self.date_debut, "date_fin": self.date_fin, "etat": self.etat, "desc": self.desc, "entry_date": self.entry_date, } return data @classmethod def create_assiduite( cls, etud: Identite, date_debut: datetime, date_fin: datetime, etat: EtatAssiduite, moduleimpl: ModuleImpl = None, description: str = None, ) -> object or int: """Créer une nouvelle assiduité pour l'étudiant""" # Vérification de non duplication des périodes assiduites: list[Assiduite] = etud.assiduites.all() date_debut = localize_datetime(date_debut) date_fin = localize_datetime(date_fin) assiduites = [ ass for ass in assiduites if is_period_overlapping( (date_debut, date_fin), (ass.date_debut, ass.date_fin), ) ] if len(assiduites) != 0: raise ScoValueError( "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)" ) if moduleimpl is not None: # Vérification de l'existence du module pour l'étudiant if moduleimpl.est_inscrit(etud): nouv_assiduite = Assiduite( date_debut=date_debut, date_fin=date_fin, etat=etat, etudiant=etud, moduleimpl_id=moduleimpl.id, desc=description, ) else: raise ScoValueError("L'étudiant n'est pas inscrit au moduleimpl") else: nouv_assiduite = Assiduite( date_debut=date_debut, date_fin=date_fin, etat=etat, etudiant=etud, desc=description, ) return nouv_assiduite class Justificatif(db.Model): """ Représente un justificatif: - une plage horaire lié à un état et un étudiant - une raison si spécifiée - un fichier si spécifié """ __tablename__ = "justificatifs" id = db.Column(db.Integer, primary_key=True) justif_id = db.synonym("id") date_debut = db.Column( db.DateTime(timezone=True), server_default=db.func.now(), nullable=False ) date_fin = db.Column( db.DateTime(timezone=True), server_default=db.func.now(), nullable=False ) etudid = db.Column( db.Integer, db.ForeignKey("identite.id", ondelete="CASCADE"), index=True, nullable=False, ) etat = db.Column( db.Integer, nullable=False, ) entry_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) raison = db.Column(db.Text()) # Archive_id -> sco_archives_justificatifs.py fichier = db.Column(db.Text()) def to_dict(self) -> dict: data = { "justif_id": self.justif_id, "etudid": self.etudid, "date_debut": self.date_debut, "date_fin": self.date_fin, "etat": self.etat, "raison": self.raison, "fichier": self.fichier, "entry_date": self.entry_date, } return data @classmethod def create_justificatif( cls, etud: Identite, date_debut: datetime, date_fin: datetime, etat: EtatJustificatif, raison: str = None, ) -> object or int: """Créer un nouveau justificatif pour l'étudiant""" # Vérification de non duplication des périodes justificatifs: list[Justificatif] = etud.justificatifs.all() date_debut = localize_datetime(date_debut) date_fin = localize_datetime(date_fin) justificatifs = [ just for just in justificatifs if is_period_overlapping( (date_debut, date_fin), (just.date_debut, just.date_fin), ) ] if len(justificatifs) != 0: raise ScoValueError( "Duplication des justificatifs (la période rentrée rentre en conflit avec un justificatif enregistré)" ) nouv_assiduite = Justificatif( date_debut=date_debut, date_fin=date_fin, etat=etat, etudiant=etud, raison=raison, ) return nouv_assiduite