ScoDoc/app/models/but_refcomp.py

223 lines
6.6 KiB
Python

"""ScoDoc 9 models : Référentiel Compétence BUT 2021
"""
from enum import unique
from typing import Any
from app import db
from app.scodoc.sco_utils import ModuleType
class XMLModel:
_xml_attribs = {} # to be overloaded
id = "_"
@classmethod
def attr_from_xml(cls, args: dict) -> dict:
"""dict with attributes imported from Orébut XML
and renamed for our models.
The mapping is specified by the _xml_attribs
attribute in each model class.
"""
return {cls._xml_attribs.get(k, k): v for (k, v) in args.items()}
def __repr__(self):
return f'<{self.__class__.__name__} {self.id} "{self.titre if hasattr(self, "titre") else ""}">'
class ApcReferentielCompetences(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
specialite = db.Column(db.Text())
specialite_long = db.Column(db.Text())
type_titre = db.Column(db.Text())
_xml_attribs = { # xml_attrib : attribute
"type": "type_titre",
}
competences = db.relationship(
"ApcCompetence",
backref="referentiel",
lazy="dynamic",
cascade="all, delete-orphan",
)
parcours = db.relationship(
"ApcParcours",
backref="referentiel",
lazy="dynamic",
cascade="all, delete-orphan",
)
def to_dict(self):
"""Représentation complète du ref. de comp.
comme un dict.
"""
class ApcCompetence(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
referentiel_id = db.Column(
db.Integer, db.ForeignKey("apc_referentiel_competences.id"), nullable=False
)
titre = db.Column(db.Text(), nullable=False)
titre_long = db.Column(db.Text())
couleur = db.Column(db.Text())
numero = db.Column(db.Integer) # ordre de présentation
couleur = db.Column(db.Text())
_xml_attribs = { # xml_attrib : attribute
"name": "titre",
"libelle_long": "titre_long",
}
situations = db.relationship(
"ApcSituationPro",
backref="competence",
lazy="dynamic",
cascade="all, delete-orphan",
)
composantes_essentielles = db.relationship(
"ApcComposanteEssentielle",
backref="competence",
lazy="dynamic",
cascade="all, delete-orphan",
)
niveaux = db.relationship(
"ApcNiveau",
backref="competence",
lazy="dynamic",
cascade="all, delete-orphan",
)
class ApcSituationPro(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
competence_id = db.Column(
db.Integer, db.ForeignKey("apc_competence.id"), nullable=False
)
libelle = db.Column(db.Text(), nullable=False)
# aucun attribut (le text devient le libellé)
class ApcComposanteEssentielle(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
competence_id = db.Column(
db.Integer, db.ForeignKey("apc_competence.id"), nullable=False
)
libelle = db.Column(db.Text(), nullable=False)
class ApcNiveau(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
competence_id = db.Column(
db.Integer, db.ForeignKey("apc_competence.id"), nullable=False
)
libelle = db.Column(db.Text(), nullable=False)
annee = db.Column(db.Text(), nullable=False) # "BUT2"
# L'ordre est l'année d'apparition de ce niveau
ordre = db.Column(db.Integer, nullable=False) # 1, 2, 3
app_critiques = db.relationship(
"ApcAppCritique",
backref="niveau",
lazy="dynamic",
cascade="all, delete-orphan",
)
class ApcAppCritique(db.Model, XMLModel):
"Apprentissage Critique BUT"
id = db.Column(db.Integer, primary_key=True)
niveau_id = db.Column(db.Integer, db.ForeignKey("apc_niveau.id"), nullable=False)
code = db.Column(db.Text(), nullable=False)
libelle = db.Column(db.Text())
modules = db.relationship(
"Module",
secondary="apc_modules_acs",
lazy="dynamic",
backref=db.backref("app_critiques", lazy="dynamic"),
)
def to_dict(self):
result = dict(self.__dict__)
result.pop("_sa_instance_state", None)
return result
def get_label(self):
return self.code + " - " + self.titre
def __repr__(self):
return "<AC {}>".format(self.code)
def get_saes(self):
"""Liste des SAE associées"""
return [m for m in self.modules if m.module_type == ModuleType.SAE]
ApcModulesACs = db.Table(
"apc_modules_acs",
db.Column("module_id", db.ForeignKey("notes_modules.id")),
db.Column("app_crit_id", db.ForeignKey("apc_app_critique.id")),
)
class ApcParcours(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
referentiel_id = db.Column(
db.Integer, db.ForeignKey("apc_referentiel_competences.id"), nullable=False
)
numero = db.Column(db.Integer) # ordre de présentation
code = db.Column(db.Text(), nullable=False)
libelle = db.Column(db.Text(), nullable=False)
annees = db.relationship(
"ApcAnneeParcours",
backref="parcours",
lazy="dynamic",
cascade="all, delete-orphan",
)
class ApcAnneeParcours(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
parcours_id = db.Column(
db.Integer, db.ForeignKey("apc_parcours.id"), nullable=False
)
numero = db.Column(db.Integer) # ordre de présentation
# L'attribut s'appelle "ordre" dans le XML Orébut
_xml_attribs = { # xml_attrib : attribute
"ordre": "numero",
}
class ApcParcoursNiveauCompetence(db.Model):
"""Association entre année de parcours et compétence.
Le "niveau" de la compétence est donné ici
(convention Orébut)
"""
competence_id = db.Column(
db.Integer,
db.ForeignKey("apc_competence.id", ondelete="CASCADE"),
primary_key=True,
)
annee_parcours_id = db.Column(
db.Integer,
db.ForeignKey("apc_annee_parcours.id", ondelete="CASCADE"),
primary_key=True,
)
niveau = db.Column(db.Integer, nullable=False) # 1, 2, 3
competence = db.relationship(
ApcCompetence,
backref=db.backref(
"annee_parcours",
passive_deletes=True,
cascade="save-update, merge, delete, delete-orphan",
),
)
annee_parcours = db.relationship(
ApcAnneeParcours,
backref=db.backref(
"competences",
passive_deletes=True,
cascade="save-update, merge, delete, delete-orphan",
),
)