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
|
|
|
|
2024-10-29 19:18:36 +01:00
|
|
|
from app import db, models
|
2021-08-13 00:34:58 +02:00
|
|
|
from app.models import SHORT_STR_LEN
|
2022-12-03 11:36:01 +01:00
|
|
|
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
|
|
|
|
2024-10-29 19:18:36 +01: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)
|
2022-01-05 16:06:56 +01:00
|
|
|
acronym = db.Column(
|
2022-08-04 16:10:11 +02:00
|
|
|
db.String(SHORT_STR_LEN), nullable=False, index=True, unique=True
|
2022-01-05 16:06:56 +01:00
|
|
|
) # 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")
|
2023-10-15 14:42:03 +02:00
|
|
|
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.
|
|
|
|
|
2021-11-12 22:17:46 +01:00
|
|
|
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")
|
2022-07-10 12:08:22 +02:00
|
|
|
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()
|
2024-10-29 19:18:36 +01:00
|
|
|
return cls.get_or_404(dept_id)
|
2024-07-24 17:34:30 +02:00
|
|
|
|
2022-12-03 11:36:01 +01: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,
|
|
|
|
}
|
2022-12-03 11:36:01 +01:00
|
|
|
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
|
2021-12-23 16:03:30 +01:00
|
|
|
|
|
|
|
|
2022-01-04 20:03:38 +01:00
|
|
|
def create_dept(acronym: str, visible=True) -> Departement:
|
2021-12-23 16:03:30 +01:00
|
|
|
"Create new departement"
|
2023-03-20 12:17:28 +01:00
|
|
|
if Departement.invalid_dept_acronym(acronym):
|
|
|
|
raise ScoValueError("acronyme departement invalide")
|
2022-02-18 22:19:23 +01:00
|
|
|
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)
|
2021-12-23 16:03:30 +01:00
|
|
|
p1 = ScoPreference(name="DeptName", value=acronym, departement=departement)
|
|
|
|
db.session.add(p1)
|
|
|
|
db.session.add(departement)
|
|
|
|
db.session.commit()
|
|
|
|
return departement
|