forked from ScoDoc/ScoDoc
146 lines
5.2 KiB
Python
146 lines
5.2 KiB
Python
# -*- coding: UTF-8 -*
|
|
|
|
"""Décisions de jury (validations) des RCUE et années du BUT
|
|
"""
|
|
|
|
from sqlalchemy.sql import text
|
|
|
|
from app import db
|
|
from app.models import CODE_STR_LEN
|
|
from app.models.but_refcomp import ApcNiveau
|
|
from app.models.ues import UniteEns
|
|
from app.models.formsemestre import FormSemestre
|
|
|
|
|
|
class ApcValidationRCUE(db.Model):
|
|
"""Validation des niveaux de compétences
|
|
|
|
aka "regroupements cohérents d'UE" dans le jargon BUT.
|
|
|
|
"""
|
|
|
|
__tablename__ = "apc_validation_rcue"
|
|
# Assure unicité de la décision:
|
|
__table_args__ = (
|
|
db.UniqueConstraint("etudid", "formsemestre_id", "ue1_id", "ue2_id"),
|
|
)
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
etudid = db.Column(
|
|
db.Integer,
|
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
|
index=True,
|
|
nullable=False,
|
|
)
|
|
formsemestre_id = db.Column(
|
|
db.Integer, db.ForeignKey("notes_formsemestre.id"), index=True, nullable=True
|
|
)
|
|
# Les deux UE associées à ce niveau:
|
|
ue1_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
|
|
ue2_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
|
|
# optionnel, le parcours dans lequel se trouve la compétence:
|
|
parcours_id = db.Column(db.Integer, db.ForeignKey("apc_parcours.id"), nullable=True)
|
|
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
|
code = db.Column(db.String(CODE_STR_LEN), nullable=False, index=True)
|
|
|
|
etud = db.relationship("Identite", backref="apc_validations_rcues")
|
|
formsemestre = db.relationship("FormSemestre", backref="apc_validations_rcues")
|
|
ue1 = db.relationship("UniteEns", foreign_keys=ue1_id)
|
|
ue2 = db.relationship("UniteEns", foreign_keys=ue2_id)
|
|
parcour = db.relationship("ApcParcours")
|
|
|
|
def __repr__(self):
|
|
return f"<{self.__class__.__name__} {self.id} {self.etud} {self.ue1}/{self.ue2}:{self.code!r}>"
|
|
|
|
def niveau(self) -> ApcNiveau:
|
|
"""Le niveau de compétence associé à cet RCUE."""
|
|
# Par convention, il est donné par la seconde UE
|
|
return self.ue2.niveau_competence
|
|
|
|
|
|
def get_other_ue_rcue(ue: UniteEns, etudid: int) -> tuple[UniteEns, FormSemestre]:
|
|
"""L'autre UE du RCUE (niveau de compétence) pour cet étudiant.
|
|
|
|
Cherche une UE du même niveau de compétence, à laquelle l'étudiant soit inscrit.
|
|
Résultat: le couple (UE, FormSemestre), ou (None, None) si pas trouvée.
|
|
"""
|
|
if (ue.niveau_competence is None) or (ue.semestre_idx is None):
|
|
return None, None
|
|
|
|
if ue.semestre_idx % 2:
|
|
other_semestre_idx = ue.semestre_idx + 1
|
|
else:
|
|
other_semestre_idx = ue.semestre_idx - 1
|
|
|
|
cursor = db.session.execute(
|
|
text(
|
|
"""SELECT
|
|
ue.id, sem.id
|
|
FROM
|
|
notes_ue ue,
|
|
notes_formsemestre_inscription inscr,
|
|
notes_formsemestre sem
|
|
|
|
WHERE
|
|
inscr.etudid = :etudid
|
|
AND inscr.formsemestre_id = sem.id
|
|
|
|
AND sem.semestre_id = :other_semestre_idx
|
|
AND ue.formation_id = sem.formation_id
|
|
AND ue.niveau_competence_id = :ue_niveau_competence_id
|
|
AND ue.semestre_idx = :other_semestre_idx
|
|
"""
|
|
),
|
|
{
|
|
"etudid": etudid,
|
|
"other_semestre_idx": other_semestre_idx,
|
|
"ue_niveau_competence_id": ue.niveau_competence_id,
|
|
},
|
|
)
|
|
r = cursor.fetchone()
|
|
if r is None:
|
|
return None, None
|
|
|
|
return UniteEns.query.get(r[0]), FormSemestre.query.get(r[1])
|
|
|
|
# q = UniteEns.query.filter(
|
|
# FormSemestreInscription.etudid == etudid,
|
|
# FormSemestreInscription.formsemestre_id == FormSemestre.id,
|
|
# FormSemestre.formation_id == UniteEns.formation_id,
|
|
# FormSemestre.semestre_id == UniteEns.semestre_idx,
|
|
# UniteEns.niveau_competence_id == ue.niveau_competence_id,
|
|
# UniteEns.semestre_idx != ue.semestre_idx,
|
|
# )
|
|
# if q.count() > 1:
|
|
# log("Warning: get_other_ue_rcue: {q.count()} candidates UE")
|
|
# return q.first()
|
|
|
|
|
|
class ApcValidationAnnee(db.Model):
|
|
"""Validation des années du BUT"""
|
|
|
|
__tablename__ = "apc_validation_annee"
|
|
# Assure unicité de la décision:
|
|
__table_args__ = (db.UniqueConstraint("etudid", "annee_scolaire"),)
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
etudid = db.Column(
|
|
db.Integer,
|
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
|
index=True,
|
|
nullable=False,
|
|
)
|
|
ordre = db.Column(db.Integer, nullable=False)
|
|
"numéro de l'année: 1, 2, 3"
|
|
formsemestre_id = db.Column(
|
|
db.Integer, db.ForeignKey("notes_formsemestre.id"), nullable=True
|
|
)
|
|
annee_scolaire = db.Column(db.Integer, nullable=False) # 2021
|
|
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
|
code = db.Column(db.String(CODE_STR_LEN), nullable=False, index=True)
|
|
|
|
etud = db.relationship("Identite", backref="apc_validations_annees")
|
|
formsemestre = db.relationship("FormSemestre", backref="apc_validations_annees")
|
|
|
|
def __repr__(self):
|
|
return f"<{self.__class__.__name__} {self.id} {self.etud} BUT{self.ordre}:{self.code!r}>"
|