Skip to content
Snippets Groups Projects
Select Git revision
  • 8c3e7b4ff61e98ea89dc60349a8c9a02c9011e0b
  • master default protected
2 results

validations.py

Blame
  • Forked from Jean-Marie Place / SCODOC_R6A06
    Source project has a limited visibility.
    validations.py 7.77 KiB
    # -*- coding: UTF-8 -*
    
    """Notes, décisions de jury
    """
    
    from app import db
    from app import log
    from app.models import SHORT_STR_LEN
    from app.models import CODE_STR_LEN
    from app.models.events import Scolog
    from app.scodoc import sco_cache
    from app.scodoc import sco_utils as scu
    from app.scodoc.codes_cursus import CODES_UE_VALIDES
    
    
    class ScolarFormSemestreValidation(db.Model):
        """Décisions de jury (sur semestre ou UEs)"""
    
        __tablename__ = "scolar_formsemestre_validation"
        # Assure unicité de la décision:
        __table_args__ = (db.UniqueConstraint("etudid", "formsemestre_id", "ue_id"),)
    
        id = db.Column(db.Integer, primary_key=True)
        formsemestre_validation_id = db.synonym("id")
        etudid = db.Column(
            db.Integer,
            db.ForeignKey("identite.id", ondelete="CASCADE"),
            index=True,
        )
        formsemestre_id = db.Column(
            db.Integer,
            db.ForeignKey("notes_formsemestre.id"),
            index=True,
        )
        ue_id = db.Column(
            db.Integer,
            db.ForeignKey("notes_ue.id"),
            index=True,
        )
        code = db.Column(db.String(CODE_STR_LEN), nullable=False, index=True)
        # NULL pour les UE, True|False pour les semestres:
        assidu = db.Column(db.Boolean)
        event_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
        # NULL sauf si compense un semestre: (pas utilisé pour BUT)
        compense_formsemestre_id = db.Column(
            db.Integer,
            db.ForeignKey("notes_formsemestre.id"),
        )
        moy_ue = db.Column(db.Float)
        # (normalement NULL) indice du semestre, utile seulement pour
        # UE "antérieures" et si la formation définit des UE utilisées
        # dans plusieurs semestres (cas R&T IUTV v2)
        semestre_id = db.Column(db.Integer)
        # Si UE validée dans le cursus d'un autre etablissement
        is_external = db.Column(
            db.Boolean, default=False, server_default="false", index=True
        )
    
        ue = db.relationship("UniteEns", lazy="select", uselist=False)
        etud = db.relationship("Identite", backref="validations")
        formsemestre = db.relationship(
            "FormSemestre", lazy="select", uselist=False, foreign_keys=[formsemestre_id]
        )
    
        def __repr__(self):
            return f"""{self.__class__.__name__}(sem={self.formsemestre_id}, etuid={
                self.etudid}, code={self.code}, ue={self.ue}, moy_ue={self.moy_ue})"""
    
        def __str__(self):
            if self.ue_id:
                # Note: si l'objet vient d'être créé, ue_id peut exister mais pas ue !
                return f"""décision sur UE {self.ue.acronyme if self.ue else self.ue_id
                                            } ({self.ue_id}): {self.code}"""
            return f"""décision sur semestre {self.formsemestre.titre_mois()} du {
                    self.event_date.strftime(scu.DATE_FMT)}"""
    
        def delete(self):
            "Efface cette validation"
            log(f"{self.__class__.__name__}.delete({self})")
            etud = self.etud
            db.session.delete(self)
            db.session.commit()
            sco_cache.invalidate_formsemestre_etud(etud)
    
        def to_dict(self) -> dict:
            "as a dict"
            d = dict(self.__dict__)
            d.pop("_sa_instance_state", None)
            return d
    
        def html(self, detail=False) -> str:
            "Affichage html"
            if self.ue_id is not None:
                moyenne = (
                    f", moyenne {scu.fmt_note(self.moy_ue)}/20 "
                    if self.moy_ue is not None
                    else ""
                )
                link = (
                    self.formsemestre.html_link_status(
                        label=f"{self.formsemestre.titre_formation(with_sem_idx=1)}",
                        title=self.formsemestre.titre_annee(),
                    )
                    if self.formsemestre
                    else "externe/antérieure"
                )
                return f"""Validation
                    {'<span class="redboldtext">externe</span>' if self.is_external else ""}
                    de l'UE <b>{self.ue.acronyme}</b>
                    {('parcours <span class="parcours">'
                      + ", ".join([p.code for p in self.ue.parcours]))
                      + "</span>"
                      if self.ue.parcours else ""}
                    {("émise par " + link)}
                    : <b>{self.code}</b>{moyenne}
                    le {self.event_date.strftime(scu.DATEATIME_FMT)}
                    """
            else:
                return f"""Validation du semestre S{
                    self.formsemestre.semestre_id if self.formsemestre else "?"}
                    {self.formsemestre.html_link_status() if self.formsemestre else ""}
                    : <b>{self.code}</b>
                    le {self.event_date.strftime(scu.DATEATIME_FMT)}
                """
    
        def ects(self) -> float:
            "Les ECTS acquis par cette validation. (0 si ce n'est pas une validation d'UE)"
            return (
                self.ue.ects or 0.0
                if (self.ue is not None) and (self.code in CODES_UE_VALIDES)
                else 0.0
            )
    
    
    class ScolarAutorisationInscription(db.Model):
        """Autorisation d'inscription dans un semestre"""
    
        __tablename__ = "scolar_autorisation_inscription"
        id = db.Column(db.Integer, primary_key=True)
        autorisation_inscription_id = db.synonym("id")
    
        etudid = db.Column(
            db.Integer,
            db.ForeignKey("identite.id", ondelete="CASCADE"),
        )
        formation_code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
        # Indice du semestre où on peut s'inscrire:
        semestre_id = db.Column(db.Integer)
        date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
        origin_formsemestre_id = db.Column(
            db.Integer,
            db.ForeignKey("notes_formsemestre.id"),
        )
        origin_formsemestre = db.relationship("FormSemestre", lazy="select", uselist=False)
    
        def __repr__(self) -> str:
            return f"""{self.__class__.__name__}(id={self.id}, etudid={
                self.etudid}, semestre_id={self.semestre_id})"""
    
        def to_dict(self) -> dict:
            "as a dict"
            d = dict(self.__dict__)
            d.pop("_sa_instance_state", None)
            return d
    
        def html(self) -> str:
            "Affichage html"
            link = (
                self.origin_formsemestre.html_link_status(
                    label=f"{self.origin_formsemestre.titre_formation(with_sem_idx=1)}",
                    title=self.origin_formsemestre.titre_annee(),
                )
                if self.origin_formsemestre
                else "externe/antérieure"
            )
            return f"""Autorisation de passage vers <b>S{self.semestre_id}</b> émise par
                {link}
                le {self.date.strftime(scu.DATEATIME_FMT)}
                """
    
        @classmethod
        def autorise_etud(
            cls,
            etudid: int,
            formation_code: str,
            origin_formsemestre_id: int,
            semestre_id: int,
        ):
            """Ajoute une autorisation"""
            autorisation = cls(
                etudid=etudid,
                formation_code=formation_code,
                origin_formsemestre_id=origin_formsemestre_id,
                semestre_id=semestre_id,
            )
            db.session.add(autorisation)
            Scolog.logdb(
                "autorise_etud", etudid=etudid, msg=f"Passage vers S{semestre_id}: autorisé"
            )
            log(f"ScolarAutorisationInscription: recording {autorisation}")
    
        @classmethod
        def delete_autorisation_etud(
            cls,
            etudid: int,
            origin_formsemestre_id: int,
        ):
            """Efface les autorisations de cet étudiant venant du sem. origine"""
            autorisations = cls.query.filter_by(
                etudid=etudid, origin_formsemestre_id=origin_formsemestre_id
            )
            for autorisation in autorisations:
                db.session.delete(autorisation)
                log(f"ScolarAutorisationInscription: deleting {autorisation}")
                Scolog.logdb(
                    "autorise_etud",
                    etudid=etudid,
                    msg=f"Passage vers S{autorisation.semestre_id}: effacé",
                )
            db.session.flush()