forked from ScoDoc/ScoDoc
Jury BUT: modification validation année: unqiue sur ref. comp.
This commit is contained in:
commit
61b46db4dd
@ -284,15 +284,11 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
# ---- Décision année et autorisation
|
# ---- Décision année et autorisation
|
||||||
self.autorisations_recorded = False
|
self.autorisations_recorded = False
|
||||||
"vrai si on a enregistré l'autorisation de passage"
|
"vrai si on a enregistré l'autorisation de passage"
|
||||||
self.validation = (
|
self.validation = ApcValidationAnnee.query.filter_by(
|
||||||
ApcValidationAnnee.query.filter_by(
|
etudid=self.etud.id,
|
||||||
etudid=self.etud.id,
|
ordre=self.annee_but,
|
||||||
ordre=self.annee_but,
|
referentiel_competence_id=self.formsemestre.formation.referentiel_competence_id,
|
||||||
)
|
).first()
|
||||||
.join(Formation)
|
|
||||||
.filter_by(formation_code=self.formsemestre.formation.formation_code)
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
"Validation actuellement enregistrée pour cette année BUT"
|
"Validation actuellement enregistrée pour cette année BUT"
|
||||||
self.code_valide = self.validation.code if self.validation is not None else None
|
self.code_valide = self.validation.code if self.validation is not None else None
|
||||||
"Le code jury annuel enregistré, ou None"
|
"Le code jury annuel enregistré, ou None"
|
||||||
@ -689,13 +685,13 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
self.validation = ApcValidationAnnee(
|
self.validation = ApcValidationAnnee(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
formsemestre=self.formsemestre_impair,
|
formsemestre=self.formsemestre_impair,
|
||||||
formation_id=self.formsemestre.formation_id,
|
referentiel_competence_id=self.formsemestre.formation.referentiel_competence_id,
|
||||||
ordre=self.annee_but,
|
ordre=self.annee_but,
|
||||||
annee_scolaire=self.annee_scolaire(),
|
annee_scolaire=self.annee_scolaire(),
|
||||||
code=code,
|
code=code,
|
||||||
)
|
)
|
||||||
else: # Update validation année BUT
|
else: # Update validation année BUT
|
||||||
self.validation.etud = self.etud
|
assert self.validation.etudid == self.etud.id
|
||||||
self.validation.formsemestre = self.formsemestre_impair
|
self.validation.formsemestre = self.formsemestre_impair
|
||||||
self.validation.formation_id = self.formsemestre.formation_id
|
self.validation.formation_id = self.formsemestre.formation_id
|
||||||
self.validation.ordre = self.annee_but
|
self.validation.ordre = self.annee_but
|
||||||
@ -852,13 +848,10 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
|
|
||||||
# Efface les validations concernant l'année BUT
|
# Efface les validations concernant l'année BUT
|
||||||
# de ce semestre
|
# de ce semestre
|
||||||
validations = (
|
validations = ApcValidationAnnee.query.filter_by(
|
||||||
ApcValidationAnnee.query.filter_by(
|
etudid=self.etud.id,
|
||||||
etudid=self.etud.id,
|
ordre=self.annee_but,
|
||||||
ordre=self.annee_but,
|
referentiel_competence_id=self.formsemestre.formation.referentiel_competence_id,
|
||||||
)
|
|
||||||
.join(Formation)
|
|
||||||
.filter_by(formation_code=self.formsemestre.formation.formation_code)
|
|
||||||
)
|
)
|
||||||
for validation in validations:
|
for validation in validations:
|
||||||
db.session.delete(validation)
|
db.session.delete(validation)
|
||||||
@ -1287,15 +1280,11 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
if annee_inferieure < 1:
|
if annee_inferieure < 1:
|
||||||
return
|
return
|
||||||
# Garde-fou: Année déjà validée ?
|
# Garde-fou: Année déjà validée ?
|
||||||
validations_annee: ApcValidationAnnee = (
|
validations_annee: ApcValidationAnnee = ApcValidationAnnee.query.filter_by(
|
||||||
ApcValidationAnnee.query.filter_by(
|
etudid=self.etud.id,
|
||||||
etudid=self.etud.id,
|
ordre=annee_inferieure,
|
||||||
ordre=annee_inferieure,
|
referentiel_competence_id=self.deca.formsemestre.formation.referentiel_competence_id,
|
||||||
)
|
).all()
|
||||||
.join(Formation)
|
|
||||||
.filter_by(formation_code=self.deca.formsemestre.formation.formation_code)
|
|
||||||
.all()
|
|
||||||
)
|
|
||||||
if len(validations_annee) > 1:
|
if len(validations_annee) > 1:
|
||||||
log(
|
log(
|
||||||
f"warning: {len(validations_annee)} validations d'année\n{validations_annee}"
|
f"warning: {len(validations_annee)} validations d'année\n{validations_annee}"
|
||||||
@ -1332,8 +1321,8 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
validation_annee = ApcValidationAnnee(
|
validation_annee = ApcValidationAnnee(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
ordre=annee_inferieure,
|
ordre=annee_inferieure,
|
||||||
|
referentiel_competence_id=self.deca.formsemestre.formation.referentiel_competence_id,
|
||||||
code=sco_codes.ADSUP,
|
code=sco_codes.ADSUP,
|
||||||
formation_id=self.deca.formsemestre.formation_id,
|
|
||||||
# met cette validation sur l'année scolaire actuelle, pas la précédente
|
# met cette validation sur l'année scolaire actuelle, pas la précédente
|
||||||
annee_scolaire=self.deca.formsemestre.annee_scolaire(),
|
annee_scolaire=self.deca.formsemestre.annee_scolaire(),
|
||||||
)
|
)
|
||||||
@ -1575,16 +1564,11 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
|
|
||||||
# def est_annee_validee(self, ordre: int) -> bool:
|
# def est_annee_validee(self, ordre: int) -> bool:
|
||||||
# """Vrai si l'année BUT ordre est validée"""
|
# """Vrai si l'année BUT ordre est validée"""
|
||||||
# # On cherche les validations d'annee avec le même
|
|
||||||
# # code formation que nous.
|
|
||||||
# return (
|
# return (
|
||||||
# ApcValidationAnnee.query.filter_by(
|
# ApcValidationAnnee.query.filter_by(
|
||||||
# etudid=self.etud.id,
|
# etudid=self.etud.id,
|
||||||
# ordre=ordre,
|
# ordre=ordre,
|
||||||
# )
|
# referentiel_competence_id=self.formsemestre.formation.referentiel_competence_id
|
||||||
# .join(Formation)
|
|
||||||
# .filter(
|
|
||||||
# Formation.formation_code == self.formsemestre.formation.formation_code
|
|
||||||
# )
|
# )
|
||||||
# .count()
|
# .count()
|
||||||
# > 0
|
# > 0
|
||||||
|
@ -231,12 +231,11 @@ def erase_decisions_annee_formation(
|
|||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
# Année BUT
|
# Année BUT
|
||||||
validations += (
|
validations += ApcValidationAnnee.query.filter_by(
|
||||||
ApcValidationAnnee.query.filter_by(etudid=etud.id, ordre=annee)
|
etudid=etud.id,
|
||||||
.join(Formation)
|
ordre=annee,
|
||||||
.filter_by(formation_code=formation.formation_code)
|
referentiel_competence_id=formation.referentiel_competence_id,
|
||||||
.all()
|
).all()
|
||||||
)
|
|
||||||
# Autorisations vers les semestres suivants ceux de l'année:
|
# Autorisations vers les semestres suivants ceux de l'année:
|
||||||
validations += (
|
validations += (
|
||||||
ScolarAutorisationInscription.query.filter_by(
|
ScolarAutorisationInscription.query.filter_by(
|
||||||
|
@ -337,17 +337,15 @@ class ResultatsSemestreBUT(NotesTableCompat):
|
|||||||
if self.validations_annee:
|
if self.validations_annee:
|
||||||
return self.validations_annee
|
return self.validations_annee
|
||||||
annee_but = (self.formsemestre.semestre_id + 1) // 2
|
annee_but = (self.formsemestre.semestre_id + 1) // 2
|
||||||
validations = (
|
validations = ApcValidationAnnee.query.filter_by(
|
||||||
ApcValidationAnnee.query.filter_by(ordre=annee_but)
|
ordre=annee_but,
|
||||||
.join(Formation)
|
referentiel_competence_id=self.formsemestre.formation.referentiel_competence_id,
|
||||||
.filter_by(formation_code=self.formsemestre.formation.formation_code)
|
).join(
|
||||||
.join(
|
FormSemestreInscription,
|
||||||
FormSemestreInscription,
|
db.and_(
|
||||||
db.and_(
|
FormSemestreInscription.etudid == ApcValidationAnnee.etudid,
|
||||||
FormSemestreInscription.etudid == ApcValidationAnnee.etudid,
|
FormSemestreInscription.formsemestre_id == self.formsemestre.id,
|
||||||
FormSemestreInscription.formsemestre_id == self.formsemestre.id,
|
),
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
validation_by_etud = {}
|
validation_by_etud = {}
|
||||||
for validation in validations:
|
for validation in validations:
|
||||||
|
@ -94,6 +94,11 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
|||||||
backref="referentiel_competence",
|
backref="referentiel_competence",
|
||||||
order_by="Formation.acronyme, Formation.version",
|
order_by="Formation.acronyme, Formation.version",
|
||||||
)
|
)
|
||||||
|
validations_annee = db.relationship(
|
||||||
|
"ApcValidationAnnee",
|
||||||
|
backref="referentiel_competence",
|
||||||
|
lazy="dynamic",
|
||||||
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<ApcReferentielCompetences {self.id} {self.specialite!r} {self.departement!r}>"
|
return f"<ApcReferentielCompetences {self.id} {self.specialite!r} {self.departement!r}>"
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
"""Décisions de jury (validations) des RCUE et années du BUT
|
"""Décisions de jury (validations) des RCUE et années du BUT
|
||||||
"""
|
"""
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app.models import CODE_STR_LEN
|
from app.models import CODE_STR_LEN
|
||||||
@ -106,71 +104,14 @@ class ApcValidationRCUE(db.Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# unused
|
|
||||||
# def find_rcues(
|
|
||||||
# formsemestre: FormSemestre, ue: UniteEns, etud: Identite, inscription_etat: str
|
|
||||||
# ) -> list[RegroupementCoherentUE]:
|
|
||||||
# """Les RCUE (niveau de compétence) à considérer pour cet étudiant dans
|
|
||||||
# ce semestre pour cette UE.
|
|
||||||
|
|
||||||
# Cherche les UEs du même niveau de compétence auxquelles l'étudiant est inscrit.
|
|
||||||
# En cas de redoublement, il peut y en avoir plusieurs, donc plusieurs RCUEs.
|
|
||||||
|
|
||||||
# Résultat: la liste peut être vide.
|
|
||||||
# """
|
|
||||||
# if (ue.niveau_competence is None) or (ue.semestre_idx is None):
|
|
||||||
# return []
|
|
||||||
|
|
||||||
# if ue.semestre_idx % 2: # S1, S3, S5
|
|
||||||
# other_semestre_idx = ue.semestre_idx + 1
|
|
||||||
# else:
|
|
||||||
# other_semestre_idx = ue.semestre_idx - 1
|
|
||||||
|
|
||||||
# cursor = db.session.execute(
|
|
||||||
# text(
|
|
||||||
# """SELECT
|
|
||||||
# ue.id, formsemestre.id
|
|
||||||
# FROM
|
|
||||||
# notes_ue ue,
|
|
||||||
# notes_formsemestre_inscription inscr,
|
|
||||||
# notes_formsemestre formsemestre
|
|
||||||
|
|
||||||
# WHERE
|
|
||||||
# inscr.etudid = :etudid
|
|
||||||
# AND inscr.formsemestre_id = formsemestre.id
|
|
||||||
|
|
||||||
# AND formsemestre.semestre_id = :other_semestre_idx
|
|
||||||
# AND ue.formation_id = formsemestre.formation_id
|
|
||||||
# AND ue.niveau_competence_id = :ue_niveau_competence_id
|
|
||||||
# AND ue.semestre_idx = :other_semestre_idx
|
|
||||||
# """
|
|
||||||
# ),
|
|
||||||
# {
|
|
||||||
# "etudid": etud.id,
|
|
||||||
# "other_semestre_idx": other_semestre_idx,
|
|
||||||
# "ue_niveau_competence_id": ue.niveau_competence_id,
|
|
||||||
# },
|
|
||||||
# )
|
|
||||||
# rcues = []
|
|
||||||
# for ue_id, formsemestre_id in cursor:
|
|
||||||
# other_ue = UniteEns.query.get(ue_id)
|
|
||||||
# other_formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
|
||||||
# rcues.append(
|
|
||||||
# RegroupementCoherentUE(
|
|
||||||
# etud, formsemestre, ue, other_formsemestre, other_ue, inscription_etat
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# # safety check: 1 seul niveau de comp. concerné:
|
|
||||||
# assert len({rcue.ue_1.niveau_competence_id for rcue in rcues}) == 1
|
|
||||||
# return rcues
|
|
||||||
|
|
||||||
|
|
||||||
class ApcValidationAnnee(db.Model):
|
class ApcValidationAnnee(db.Model):
|
||||||
"""Validation des années du BUT"""
|
"""Validation des années du BUT"""
|
||||||
|
|
||||||
__tablename__ = "apc_validation_annee"
|
__tablename__ = "apc_validation_annee"
|
||||||
# Assure unicité de la décision:
|
# Assure unicité de la décision:
|
||||||
__table_args__ = (db.UniqueConstraint("etudid", "annee_scolaire", "ordre"),)
|
__table_args__ = (
|
||||||
|
db.UniqueConstraint("etudid", "ordre", "referentiel_competence_id"),
|
||||||
|
)
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
@ -184,10 +125,8 @@ class ApcValidationAnnee(db.Model):
|
|||||||
db.Integer, db.ForeignKey("notes_formsemestre.id"), nullable=True
|
db.Integer, db.ForeignKey("notes_formsemestre.id"), nullable=True
|
||||||
)
|
)
|
||||||
"le semestre origine, normalement l'IMPAIR (le 1er) de l'année"
|
"le semestre origine, normalement l'IMPAIR (le 1er) de l'année"
|
||||||
formation_id = db.Column(
|
referentiel_competence_id = db.Column(
|
||||||
db.Integer,
|
db.Integer, db.ForeignKey("apc_referentiel_competences.id"), nullable=False
|
||||||
db.ForeignKey("notes_formations.id"),
|
|
||||||
nullable=False,
|
|
||||||
)
|
)
|
||||||
annee_scolaire = db.Column(db.Integer, nullable=False) # eg 2021
|
annee_scolaire = db.Column(db.Integer, nullable=False) # eg 2021
|
||||||
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||||
@ -207,17 +146,22 @@ class ApcValidationAnnee(db.Model):
|
|||||||
"dict pour bulletins"
|
"dict pour bulletins"
|
||||||
return {
|
return {
|
||||||
"annee_scolaire": self.annee_scolaire,
|
"annee_scolaire": self.annee_scolaire,
|
||||||
"date": self.date.isoformat(),
|
"date": self.date.isoformat() if self.date else "",
|
||||||
"code": self.code,
|
"code": self.code,
|
||||||
"ordre": self.ordre,
|
"ordre": self.ordre,
|
||||||
}
|
}
|
||||||
|
|
||||||
def html(self) -> str:
|
def html(self) -> str:
|
||||||
"Affichage html"
|
"Affichage html"
|
||||||
|
date_str = (
|
||||||
|
f"""le {self.date.strftime("%d/%m/%Y")} à {self.date.strftime("%Hh%M")}"""
|
||||||
|
if self.date
|
||||||
|
else "(sans date)"
|
||||||
|
)
|
||||||
return f"""Validation <b>année BUT{self.ordre}</b> émise par
|
return f"""Validation <b>année BUT{self.ordre}</b> émise par
|
||||||
{self.formsemestre.html_link_status() if self.formsemestre else "-"}
|
{self.formsemestre.html_link_status() if self.formsemestre else "-"}
|
||||||
: <b>{self.code}</b>
|
: <b>{self.code}</b>
|
||||||
le {self.date.strftime("%d/%m/%Y")} à {self.date.strftime("%Hh%M")}
|
{date_str}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@ -259,15 +203,11 @@ def dict_decision_jury(etud: Identite, formsemestre: FormSemestre) -> dict:
|
|||||||
decisions["descr_decisions_rcue"] = ""
|
decisions["descr_decisions_rcue"] = ""
|
||||||
decisions["descr_decisions_niveaux"] = ""
|
decisions["descr_decisions_niveaux"] = ""
|
||||||
# --- Année: prend la validation pour l'année scolaire de ce semestre
|
# --- Année: prend la validation pour l'année scolaire de ce semestre
|
||||||
validation = (
|
validation = ApcValidationAnnee.query.filter_by(
|
||||||
ApcValidationAnnee.query.filter_by(
|
etudid=etud.id,
|
||||||
etudid=etud.id,
|
annee_scolaire=formsemestre.annee_scolaire(),
|
||||||
annee_scolaire=formsemestre.annee_scolaire(),
|
referentiel_competence_id=formsemestre.formation.referentiel_competence_id,
|
||||||
)
|
).first()
|
||||||
.join(Formation)
|
|
||||||
.filter(Formation.formation_code == formsemestre.formation.formation_code)
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
if validation:
|
if validation:
|
||||||
decisions["decision_annee"] = validation.to_dict_bul()
|
decisions["decision_annee"] = validation.to_dict_bul()
|
||||||
else:
|
else:
|
||||||
|
@ -867,15 +867,12 @@ class FormSemestre(db.Model):
|
|||||||
.order_by(UniteEns.numero)
|
.order_by(UniteEns.numero)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
vals_annee = ( # issues de ce formsemestre seulement
|
vals_annee = ( # issues de cette année scolaire seulement
|
||||||
ApcValidationAnnee.query.filter_by(
|
ApcValidationAnnee.query.filter_by(
|
||||||
etudid=etudid,
|
etudid=etudid,
|
||||||
annee_scolaire=self.annee_scolaire(),
|
annee_scolaire=self.annee_scolaire(),
|
||||||
)
|
referentiel_competence_id=self.formation.referentiel_competence_id,
|
||||||
.join(ApcValidationAnnee.formsemestre)
|
).all()
|
||||||
.join(FormSemestre.formation)
|
|
||||||
.filter(Formation.formation_code == self.formation.formation_code)
|
|
||||||
.all()
|
|
||||||
)
|
)
|
||||||
H = []
|
H = []
|
||||||
for vals in (vals_sem, vals_ues, vals_rcues, vals_annee):
|
for vals in (vals_sem, vals_ues, vals_rcues, vals_annee):
|
||||||
|
@ -491,15 +491,11 @@ class ApoEtud(dict):
|
|||||||
# ne trouve pas de semestre impair
|
# ne trouve pas de semestre impair
|
||||||
self.validation_annee_but = None
|
self.validation_annee_but = None
|
||||||
return
|
return
|
||||||
self.validation_annee_but: ApcValidationAnnee = (
|
self.validation_annee_but: ApcValidationAnnee = ApcValidationAnnee.query.filter_by(
|
||||||
ApcValidationAnnee.query.filter_by(
|
formsemestre_id=formsemestre.id,
|
||||||
formsemestre_id=formsemestre.id,
|
etudid=self.etud["etudid"],
|
||||||
etudid=self.etud["etudid"],
|
referentiel_competence_id=self.cur_res.formsemestre.formation.referentiel_competence_id,
|
||||||
formation_id=self.cur_sem[
|
).first()
|
||||||
"formation_id"
|
|
||||||
], # XXX utiliser formation_code
|
|
||||||
).first()
|
|
||||||
)
|
|
||||||
self.is_nar = (
|
self.is_nar = (
|
||||||
self.validation_annee_but and self.validation_annee_but.code == NAR
|
self.validation_annee_but and self.validation_annee_but.code == NAR
|
||||||
)
|
)
|
||||||
|
112
migrations/versions/829683efddc4_change_apcvalidationannee.py
Normal file
112
migrations/versions/829683efddc4_change_apcvalidationannee.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
"""Change ApcValidationAnnee
|
||||||
|
|
||||||
|
Revision ID: 829683efddc4
|
||||||
|
Revises: c701224fa255
|
||||||
|
Create Date: 2023-06-28 09:47:16.591028
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.orm import sessionmaker # added by ev
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "829683efddc4"
|
||||||
|
down_revision = "c701224fa255"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
Session = sessionmaker()
|
||||||
|
|
||||||
|
|
||||||
|
# Voir https://stackoverflow.com/questions/24082542/check-if-a-table-column-exists-in-the-database-using-sqlalchemy-and-alembic
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
|
def column_exists(table_name, column_name):
|
||||||
|
bind = op.get_context().bind
|
||||||
|
insp = inspect(bind)
|
||||||
|
columns = insp.get_columns(table_name)
|
||||||
|
return any(c["name"] == column_name for c in columns)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
if column_exists("apc_validation_annee", "referentiel_competence_id"):
|
||||||
|
return # utile durant developpement
|
||||||
|
# Enleve la contrainte erronée
|
||||||
|
with op.batch_alter_table("apc_validation_annee", schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint(
|
||||||
|
"apc_validation_annee_etudid_annee_scolaire_ordre_key", type_="unique"
|
||||||
|
)
|
||||||
|
# Ajoute colonne referentiel, nullable pour l'instant
|
||||||
|
batch_op.add_column(
|
||||||
|
sa.Column("referentiel_competence_id", sa.Integer(), nullable=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Affecte le referentiel des anciennes validations
|
||||||
|
bind = op.get_bind()
|
||||||
|
session = Session(bind=bind)
|
||||||
|
session.execute(
|
||||||
|
sa.text(
|
||||||
|
"""
|
||||||
|
UPDATE apc_validation_annee AS a
|
||||||
|
SET referentiel_competence_id = (
|
||||||
|
SELECT f.referentiel_competence_id
|
||||||
|
FROM notes_formations f
|
||||||
|
WHERE f.id = a.formation_id
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# En principe, on n'a pas pu entrer de validation sur des formations sans referentiel
|
||||||
|
# par prudence, on les supprime avant d'ajouter la contrainte
|
||||||
|
session.execute(
|
||||||
|
sa.text(
|
||||||
|
"DELETE FROM apc_validation_annee WHERE referentiel_competence_id is NULL"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
op.alter_column(
|
||||||
|
"apc_validation_annee",
|
||||||
|
"referentiel_competence_id",
|
||||||
|
nullable=False,
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"apc_validation_annee_refcomp_fkey",
|
||||||
|
"apc_validation_annee",
|
||||||
|
"apc_referentiel_competences",
|
||||||
|
["referentiel_competence_id"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
# Efface les validations d'année dupliquées
|
||||||
|
# (garde le premier code dans l'ordre alphabétique... mieux que rien)
|
||||||
|
session.execute(
|
||||||
|
sa.text(
|
||||||
|
"""
|
||||||
|
DELETE FROM apc_validation_annee t1
|
||||||
|
WHERE EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM apc_validation_annee t2
|
||||||
|
WHERE t1.etudid = t2.etudid
|
||||||
|
AND t1.referentiel_competence_id = t2.referentiel_competence_id
|
||||||
|
AND t1.ordre = t2.ordre
|
||||||
|
AND t1.code > t2.code
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Et ajoute la contrainte unicité de décision année par étudiant/ref. comp.:
|
||||||
|
op.create_unique_constraint(
|
||||||
|
"apc_validation_annee_etudid_ordre_refcomp_key",
|
||||||
|
"apc_validation_annee",
|
||||||
|
["etudid", "ordre", "referentiel_competence_id"],
|
||||||
|
)
|
||||||
|
op.drop_column("apc_validation_annee", "formation_id")
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# Se contente de ré-ajouter la colonne formation_id sans re-générer son contenu
|
||||||
|
with op.batch_alter_table("apc_validation_annee", schema=None) as batch_op:
|
||||||
|
# batch_op.drop_constraint(
|
||||||
|
# "apc_validation_annee_etudid_ordre_refcomp_key", type_="unique"
|
||||||
|
# )
|
||||||
|
# batch_op.drop_column("referentiel_competence_id")
|
||||||
|
batch_op.add_column(sa.Column("formation_id", sa.Integer(), nullable=True))
|
Loading…
Reference in New Issue
Block a user