ScoDoc/app/models/departements.py

115 lines
4.2 KiB
Python
Raw Permalink Normal View History

2021-08-13 00:34:58 +02:00
# -*- coding: UTF-8 -*
2021-08-25 23:51:07 +02:00
"""ScoDoc models : departements
2021-08-13 00:34:58 +02:00
"""
2023-03-20 12:17:28 +01:00
import re
2021-08-13 00:34:58 +02:00
from app import db, models
2021-08-13 00:34:58 +02:00
from app.models import SHORT_STR_LEN
from app.models.preferences import ScoPreference
2022-08-04 16:10:11 +02:00
from app.scodoc.sco_exceptions import ScoValueError
2021-08-13 00:34:58 +02:00
2023-03-20 12:17:28 +01:00
VALID_DEPT_EXP = re.compile(r"^[\w@\\\-\.]+$")
2021-08-13 00:34:58 +02:00
class Departement(models.ScoDocModel):
2021-08-13 00:34:58 +02:00
"""Un département ScoDoc"""
id = db.Column(db.Integer, primary_key=True)
acronym = db.Column(
2022-08-04 16:10:11 +02:00
db.String(SHORT_STR_LEN), nullable=False, index=True, unique=True
) # ne change jamais, voir la pref. DeptName
description = db.Column(db.Text()) # pas utilisé par ScoDoc : voir DeptFullName
2021-08-13 00:34:58 +02:00
date_creation = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
visible = db.Column(
db.Boolean(), nullable=False, default=True, server_default="true"
) # sur page d'accueil
2021-12-23 19:28:25 +01:00
# entreprises = db.relationship("Entreprise", lazy="dynamic", backref="departement")
etudiants = db.relationship(
"Identite",
back_populates="departement",
cascade="all,delete-orphan",
lazy="dynamic",
)
# This means if a Departement is deleted, all related Identite instances are also
# deleted (all,delete). The orphan part means that if an Identite instance becomes
# detached from its parent Departement (for example, by setting my_identite.departement = None),
# it will be deleted.
formations = db.relationship("Formation", lazy="dynamic", backref="departement")
2021-08-13 00:34:58 +02:00
formsemestres = db.relationship(
"FormSemestre", lazy="dynamic", backref="departement"
)
preferences = db.relationship(
"ScoPreference", lazy="dynamic", backref="departement"
)
semsets = db.relationship("NotesSemSet", lazy="dynamic", backref="departement")
referentiels = db.relationship(
"ApcReferentielCompetences", lazy="dynamic", backref="departement"
)
2021-08-13 00:34:58 +02:00
def __repr__(self):
2021-09-27 13:43:11 +02:00
return f"<{self.__class__.__name__}(id={self.id}, acronym='{self.acronym}')>"
2021-09-09 12:49:23 +02:00
2024-07-24 17:34:30 +02:00
@classmethod
def get_departement(cls, dept_ident: str | int) -> "Departement":
"Le département, par id ou acronyme. Erreur 404 si pas trouvé."
try:
dept_id = int(dept_ident)
except ValueError:
dept_id = None
if dept_id is None:
return cls.query.filter_by(acronym=dept_ident).first_or_404()
return cls.get_or_404(dept_id)
2024-07-24 17:34:30 +02:00
def to_dict(self, with_dept_name=True, with_dept_preferences=False):
2021-09-09 12:49:23 +02:00
data = {
"id": self.id,
"acronym": self.acronym,
"description": self.description,
"visible": self.visible,
"date_creation": self.date_creation,
}
if with_dept_name:
pref = ScoPreference.query.filter_by(
dept_id=self.id, name="DeptName"
).first()
data["dept_name"] = pref.value if pref else None
# Ceci n'est pas encore utilisé, mais pourrait être publié
# par l'API après nettoyage des préférences.
if with_dept_preferences:
data["preferences"] = {
p.name: p.value for p in ScoPreference.query.filter_by(dept_id=self.id)
}
2021-09-09 12:49:23 +02:00
return data
2021-12-22 00:35:58 +01:00
2023-03-20 12:17:28 +01:00
@classmethod
def invalid_dept_acronym(cls, dept_acronym: str) -> bool:
"Check that dept_acronym is invalid"
return (
not dept_acronym
or (len(dept_acronym) >= SHORT_STR_LEN)
or not VALID_DEPT_EXP.match(dept_acronym)
)
2021-12-22 00:35:58 +01:00
@classmethod
def from_acronym(cls, acronym):
dept = cls.query.filter_by(acronym=acronym).first_or_404()
return dept
2022-01-04 20:03:38 +01:00
def create_dept(acronym: str, visible=True) -> Departement:
"Create new departement"
2023-03-20 12:17:28 +01:00
if Departement.invalid_dept_acronym(acronym):
raise ScoValueError("acronyme departement invalide")
existing = Departement.query.filter_by(acronym=acronym).count()
if existing:
2022-08-04 16:10:11 +02:00
raise ScoValueError(f"acronyme {acronym} déjà existant")
2022-01-04 20:03:38 +01:00
departement = Departement(acronym=acronym, visible=visible)
p1 = ScoPreference(name="DeptName", value=acronym, departement=departement)
db.session.add(p1)
db.session.add(departement)
db.session.commit()
return departement