forked from ScoDoc/DocScoDoc
107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
"""ScoDoc 9 models : Formations
|
|
"""
|
|
|
|
from app import db
|
|
from app.models import SHORT_STR_LEN
|
|
from app.scodoc import notesdb as ndb
|
|
from app.scodoc import sco_utils as scu
|
|
from app.scodoc import sco_codes_parcours
|
|
from app.comp import df_cache
|
|
|
|
|
|
class Formation(db.Model):
|
|
"""Programme pédagogique d'une formation"""
|
|
|
|
__tablename__ = "notes_formations"
|
|
__table_args__ = (db.UniqueConstraint("dept_id", "acronyme", "titre", "version"),)
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
formation_id = db.synonym("id")
|
|
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
|
|
|
|
acronyme = db.Column(db.Text(), nullable=False)
|
|
titre = db.Column(db.Text(), nullable=False)
|
|
titre_officiel = db.Column(db.Text(), nullable=False)
|
|
version = db.Column(db.Integer, default=1, server_default="1")
|
|
formation_code = db.Column(
|
|
db.String(SHORT_STR_LEN),
|
|
server_default=db.text("notes_newid_fcod()"),
|
|
nullable=False,
|
|
)
|
|
# nb: la fonction SQL notes_newid_fcod doit être créée à part
|
|
type_parcours = db.Column(db.Integer, default=0, server_default="0")
|
|
code_specialite = db.Column(db.String(SHORT_STR_LEN))
|
|
|
|
# Optionnel, pour les formations type BUT
|
|
referentiel_competence_id = db.Column(
|
|
db.Integer, db.ForeignKey("apc_referentiel_competences.id")
|
|
)
|
|
ues = db.relationship("UniteEns", backref="formation", lazy="dynamic")
|
|
formsemestres = db.relationship("FormSemestre", lazy="dynamic", backref="formation")
|
|
ues = db.relationship("UniteEns", lazy="dynamic", backref="formation")
|
|
modules = db.relationship("Module", lazy="dynamic", backref="formation")
|
|
|
|
def __repr__(self):
|
|
return f"<{self.__class__.__name__}(id={self.id}, dept_id={self.dept_id}, acronyme='{self.acronyme}')>"
|
|
|
|
def to_dict(self):
|
|
e = dict(self.__dict__)
|
|
e.pop("_sa_instance_state", None)
|
|
# ScoDoc7 output_formators: (backward compat)
|
|
e["formation_id"] = self.id
|
|
return e
|
|
|
|
def get_parcours(self):
|
|
"""get l'instance de TypeParcours de cette formation"""
|
|
return sco_codes_parcours.get_parcours_from_code(self.type_parcours)
|
|
|
|
def is_apc(self):
|
|
"True si formation APC avec SAE (BUT)"
|
|
return self.get_parcours().APC_SAE
|
|
|
|
def get_module_coefs(self, semestre_idx: int = None):
|
|
"""Les coefs des modules vers les UE (accès via cache)"""
|
|
from app.comp import moy_ue
|
|
|
|
if semestre_idx is None:
|
|
key = f"{self.id}"
|
|
else:
|
|
key = f"{self.id}.{semestre_idx}"
|
|
|
|
modules_coefficients = df_cache.ModuleCoefsCache.get(key)
|
|
if modules_coefficients is None:
|
|
modules_coefficients, _, _ = moy_ue.df_load_module_coefs(
|
|
self.id, semestre_idx
|
|
)
|
|
df_cache.ModuleCoefsCache.set(key, modules_coefficients)
|
|
return modules_coefficients
|
|
|
|
def invalidate_module_coefs(self, semestre_idx: int = None):
|
|
"""Invalide les coefficients de modules cachés.
|
|
Si semestre_idx est None, invalide tous les semestres,
|
|
sinon invalide le semestre indiqué et le cache de la formation.
|
|
"""
|
|
if semestre_idx is None:
|
|
keys = {f"{self.id}.{m.semestre_id}" for m in self.modules}
|
|
else:
|
|
keys = f"{self.id}.{semestre_idx}"
|
|
df_cache.ModuleCoefsCache.delete_many(keys | {f"{self.id}"})
|
|
|
|
|
|
class Matiere(db.Model):
|
|
"""Matières: regroupe les modules d'une UE
|
|
La matière a peu d'utilité en dehors de la présentation des modules
|
|
d'une UE.
|
|
"""
|
|
|
|
__tablename__ = "notes_matieres"
|
|
__table_args__ = (db.UniqueConstraint("ue_id", "titre"),)
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
matiere_id = db.synonym("id")
|
|
ue_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"))
|
|
titre = db.Column(db.Text())
|
|
numero = db.Column(db.Integer) # ordre de présentation
|
|
|
|
modules = db.relationship("Module", lazy="dynamic", backref="matiere")
|