"""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 "".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", ), )