forked from ScoDoc/ScoDoc
BUT: jury: validation des niveaux inférieurs. WIP
This commit is contained in:
parent
73023b7806
commit
e46ae76399
@ -104,7 +104,7 @@ class EtudCursusBUT:
|
|||||||
self.parcour: ApcParcours = self.inscriptions[-1].parcour
|
self.parcour: ApcParcours = self.inscriptions[-1].parcour
|
||||||
"Le parcours à valider: celui du DERNIER semestre suivi (peut être None)"
|
"Le parcours à valider: celui du DERNIER semestre suivi (peut être None)"
|
||||||
self.niveaux_by_annee = {}
|
self.niveaux_by_annee = {}
|
||||||
"{ annee : liste des niveaux à valider }"
|
"{ annee:int : liste des niveaux à valider }"
|
||||||
self.niveaux: dict[int, ApcNiveau] = {}
|
self.niveaux: dict[int, ApcNiveau] = {}
|
||||||
"cache les niveaux"
|
"cache les niveaux"
|
||||||
for annee in (1, 2, 3):
|
for annee in (1, 2, 3):
|
||||||
@ -118,21 +118,6 @@ class EtudCursusBUT:
|
|||||||
self.niveaux.update(
|
self.niveaux.update(
|
||||||
{niveau.id: niveau for niveau in self.niveaux_by_annee[annee]}
|
{niveau.id: niveau for niveau in self.niveaux_by_annee[annee]}
|
||||||
)
|
)
|
||||||
# Probablement inutile:
|
|
||||||
# # Cherche les validations de jury enregistrées pour chaque niveau
|
|
||||||
# self.validations_by_niveau = collections.defaultdict(lambda: [])
|
|
||||||
# " { niveau_id : [ ApcValidationRCUE ] }"
|
|
||||||
# for validation_rcue in ApcValidationRCUE.query.filter_by(etud=etud):
|
|
||||||
# self.validations_by_niveau[validation_rcue.niveau().id].append(
|
|
||||||
# validation_rcue
|
|
||||||
# )
|
|
||||||
# self.validation_by_niveau = {
|
|
||||||
# niveau_id: sorted(
|
|
||||||
# validations, key=lambda v: sco_codes.BUT_CODES_ORDERED[v.code]
|
|
||||||
# )[0]
|
|
||||||
# for niveau_id, validations in self.validations_by_niveau.items()
|
|
||||||
# }
|
|
||||||
# "{ niveau_id : meilleure validation pour ce niveau }"
|
|
||||||
|
|
||||||
self.validation_par_competence_et_annee = {}
|
self.validation_par_competence_et_annee = {}
|
||||||
"""{ competence_id : { 'BUT1' : validation_rcue (la "meilleure"), ... } }"""
|
"""{ competence_id : { 'BUT1' : validation_rcue (la "meilleure"), ... } }"""
|
||||||
@ -146,7 +131,7 @@ class EtudCursusBUT:
|
|||||||
# prend la "meilleure" validation
|
# prend la "meilleure" validation
|
||||||
if (not previous_validation) or (
|
if (not previous_validation) or (
|
||||||
sco_codes.BUT_CODES_ORDERED[validation_rcue.code]
|
sco_codes.BUT_CODES_ORDERED[validation_rcue.code]
|
||||||
> sco_codes.BUT_CODES_ORDERED[previous_validation["code"]]
|
> sco_codes.BUT_CODES_ORDERED[previous_validation.code]
|
||||||
):
|
):
|
||||||
self.validation_par_competence_et_annee[niveau.competence.id][
|
self.validation_par_competence_et_annee[niveau.competence.id][
|
||||||
niveau.annee
|
niveau.annee
|
||||||
@ -206,6 +191,23 @@ class EtudCursusBUT:
|
|||||||
)
|
)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def load_validation_by_niveau(self) -> dict[int, list[ApcValidationRCUE]]:
|
||||||
|
"""Cherche les validations de jury enregistrées pour chaque niveau
|
||||||
|
Résultat: { niveau_id : [ ApcValidationRCUE ] }
|
||||||
|
meilleure validation pour ce niveau
|
||||||
|
"""
|
||||||
|
validations_by_niveau = collections.defaultdict(lambda: [])
|
||||||
|
for validation_rcue in ApcValidationRCUE.query.filter_by(etud=self.etud):
|
||||||
|
validations_by_niveau[validation_rcue.niveau().id].append(validation_rcue)
|
||||||
|
validation_by_niveau = {
|
||||||
|
niveau_id: sorted(
|
||||||
|
validations, key=lambda v: sco_codes.BUT_CODES_ORDERED[v.code]
|
||||||
|
)[0]
|
||||||
|
for niveau_id, validations in validations_by_niveau.items()
|
||||||
|
if validations
|
||||||
|
}
|
||||||
|
return validation_by_niveau
|
||||||
|
|
||||||
|
|
||||||
class FormSemestreCursusBUT:
|
class FormSemestreCursusBUT:
|
||||||
"""L'état des étudiants d'un formsemestre dans leur cursus BUT
|
"""L'état des étudiants d'un formsemestre dans leur cursus BUT
|
||||||
|
@ -58,6 +58,7 @@ DecisionsProposeesUE: décisions de jury sur une UE du BUT
|
|||||||
DecisionsProposeesRCUE appelera .set_compensable()
|
DecisionsProposeesRCUE appelera .set_compensable()
|
||||||
si on a la possibilité de la compenser dans le RCUE.
|
si on a la possibilité de la compenser dans le RCUE.
|
||||||
"""
|
"""
|
||||||
|
from datetime import datetime
|
||||||
import html
|
import html
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
import re
|
import re
|
||||||
@ -68,6 +69,7 @@ from flask import flash, g, url_for
|
|||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app import log
|
from app import log
|
||||||
|
from app.but.cursus_but import EtudCursusBUT
|
||||||
from app.comp.res_but import ResultatsSemestreBUT
|
from app.comp.res_but import ResultatsSemestreBUT
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
|
|
||||||
@ -92,6 +94,7 @@ from app.models.validations import ScolarFormSemestreValidation
|
|||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import codes_cursus as sco_codes
|
from app.scodoc import codes_cursus as sco_codes
|
||||||
from app.scodoc.codes_cursus import (
|
from app.scodoc.codes_cursus import (
|
||||||
|
code_rcue_validant,
|
||||||
BUT_CODES_ORDERED,
|
BUT_CODES_ORDERED,
|
||||||
CODES_RCUE_VALIDES,
|
CODES_RCUE_VALIDES,
|
||||||
CODES_UE_CAPITALISANTS,
|
CODES_UE_CAPITALISANTS,
|
||||||
@ -275,6 +278,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
if self.formsemestre_impair is not None:
|
if self.formsemestre_impair is not None:
|
||||||
self.validation = ApcValidationAnnee.query.filter_by(
|
self.validation = ApcValidationAnnee.query.filter_by(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
|
formation_id=self.formsemestre.formation_id,
|
||||||
formsemestre_id=formsemestre_impair.id,
|
formsemestre_id=formsemestre_impair.id,
|
||||||
ordre=self.annee_but,
|
ordre=self.annee_but,
|
||||||
).first()
|
).first()
|
||||||
@ -755,6 +759,7 @@ 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,
|
||||||
ordre=self.annee_but,
|
ordre=self.annee_but,
|
||||||
annee_scolaire=self.annee_scolaire(),
|
annee_scolaire=self.annee_scolaire(),
|
||||||
code=code,
|
code=code,
|
||||||
@ -900,6 +905,9 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
)
|
)
|
||||||
validations = ApcValidationAnnee.query.filter_by(
|
validations = ApcValidationAnnee.query.filter_by(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
|
# XXX efface les validations émise depuis ce semestre
|
||||||
|
# et pas toutes celles concernant cette l'année...
|
||||||
|
# (utiliser formation_id pour changer cette politique)
|
||||||
formsemestre_id=self.formsemestre_impair.id,
|
formsemestre_id=self.formsemestre_impair.id,
|
||||||
ordre=self.annee_but,
|
ordre=self.annee_but,
|
||||||
)
|
)
|
||||||
@ -1035,6 +1043,9 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
):
|
):
|
||||||
super().__init__(etud=dec_prop_annee.etud)
|
super().__init__(etud=dec_prop_annee.etud)
|
||||||
self.deca = dec_prop_annee
|
self.deca = dec_prop_annee
|
||||||
|
self.referentiel_competence_id = (
|
||||||
|
self.deca.formsemestre.formation.referentiel_competence_id
|
||||||
|
)
|
||||||
self.rcue = rcue
|
self.rcue = rcue
|
||||||
if rcue is None: # RCUE non dispo, eg un seul semestre
|
if rcue is None: # RCUE non dispo, eg un seul semestre
|
||||||
self.codes = []
|
self.codes = []
|
||||||
@ -1139,7 +1150,8 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
dec_ue.record(sco_codes.ADJR)
|
dec_ue.record(sco_codes.ADJR)
|
||||||
|
|
||||||
# Valide les niveaux inférieurs de la compétence (code ADSUP)
|
# Valide les niveaux inférieurs de la compétence (code ADSUP)
|
||||||
# TODO
|
if code in CODES_RCUE_VALIDES:
|
||||||
|
self.valide_niveau_inferieur()
|
||||||
|
|
||||||
if self.rcue.formsemestre_1 is not None:
|
if self.rcue.formsemestre_1 is not None:
|
||||||
sco_cache.invalidate_formsemestre(
|
sco_cache.invalidate_formsemestre(
|
||||||
@ -1177,6 +1189,189 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
return f"{niveau_titre}-{ordre}"
|
return f"{niveau_titre}-{ordre}"
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def valide_niveau_inferieur(self) -> None:
|
||||||
|
"""Appelé juste après la validation d'un RCUE.
|
||||||
|
*La validation des deux UE du niveau d’une compétence emporte la validation de
|
||||||
|
l’ensemble des UEs du niveau inférieur de cette même compétence.*
|
||||||
|
"""
|
||||||
|
if not self.rcue or not self.rcue.ue_1 or not self.rcue.ue_1.niveau_competence:
|
||||||
|
return
|
||||||
|
competence: ApcCompetence = self.rcue.ue_1.niveau_competence.competence
|
||||||
|
ordre_inferieur = self.rcue.ue_1.niveau_competence.ordre - 1
|
||||||
|
if ordre_inferieur < 1:
|
||||||
|
return # pas de niveau inferieur
|
||||||
|
|
||||||
|
# --- Si le RCUE inférieur est déjà validé, ne fait rien
|
||||||
|
validations_rcue = (
|
||||||
|
ApcValidationRCUE.query.filter_by(etudid=self.etud.id)
|
||||||
|
.join(UniteEns, UniteEns.id == ApcValidationRCUE.ue1_id)
|
||||||
|
.join(ApcNiveau)
|
||||||
|
.filter_by(ordre=ordre_inferieur)
|
||||||
|
.join(ApcCompetence)
|
||||||
|
.filter_by(id=competence.id)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
if [v for v in validations_rcue if code_rcue_validant(v.code)]:
|
||||||
|
return # déjà validé
|
||||||
|
|
||||||
|
# --- Validations des UEs
|
||||||
|
ues, ue1, ue2 = self._get_ues_inferieures(competence, ordre_inferieur)
|
||||||
|
# Pour chaque UE inférieure non validée, valide:
|
||||||
|
for ue in ues:
|
||||||
|
validations_ue = ScolarFormSemestreValidation.query.filter_by(
|
||||||
|
etudid=self.etud.id, ue_id=ue.id
|
||||||
|
).all()
|
||||||
|
if [
|
||||||
|
validation
|
||||||
|
for validation in validations_ue
|
||||||
|
if sco_codes.code_ue_validant(validation.code)
|
||||||
|
]:
|
||||||
|
continue # on a déjà une validation
|
||||||
|
# aucune validation validante
|
||||||
|
validation_ue = validations_ue[0] if validations_ue else None
|
||||||
|
if validation_ue:
|
||||||
|
# Modifie validation existante
|
||||||
|
validation_ue.code = sco_codes.ADSUP
|
||||||
|
validation_ue.event_date = datetime.now()
|
||||||
|
if validation_ue.formsemestre_id is not None:
|
||||||
|
sco_cache.invalidate_formsemestre(
|
||||||
|
formsemestre_id=validation_ue.formsemestre_id
|
||||||
|
)
|
||||||
|
log(f"updating {validation_ue}")
|
||||||
|
else:
|
||||||
|
# Ajoute une validation,
|
||||||
|
# pas de formsemestre ni de note car pas une capitalisation
|
||||||
|
validation_ue = ScolarFormSemestreValidation(
|
||||||
|
etudid=self.etud.id,
|
||||||
|
code=sco_codes.ADSUP,
|
||||||
|
ue_id=ue.id,
|
||||||
|
is_external=True, # pas rattachée à un formsemestre
|
||||||
|
)
|
||||||
|
log(f"recording {validation_ue}")
|
||||||
|
db.session.add(validation_ue)
|
||||||
|
|
||||||
|
# Valide le RCUE inférieur
|
||||||
|
if validations_rcue:
|
||||||
|
# Met à jour validation existante
|
||||||
|
validation_rcue = validations_rcue[0]
|
||||||
|
validation_rcue.code = sco_codes.ADSUP
|
||||||
|
validation_rcue.date = datetime.now()
|
||||||
|
log(f"updating {validation_rcue}")
|
||||||
|
if validation_rcue.formsemestre_id is not None:
|
||||||
|
sco_cache.invalidate_formsemestre(
|
||||||
|
formsemestre_id=validation_rcue.formsemestre_id
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Crée nouvelle validation
|
||||||
|
validation_rcue = ApcValidationRCUE(
|
||||||
|
etudid=self.etud.id, ue1_id=ue1.id, ue2_id=ue2.id, code=sco_codes.ADSUP
|
||||||
|
)
|
||||||
|
log(f"recording {validation_rcue}")
|
||||||
|
db.session.add(validation_rcue)
|
||||||
|
db.session.commit()
|
||||||
|
self.valide_annee_inferieure()
|
||||||
|
|
||||||
|
def valide_annee_inferieure(self) -> None:
|
||||||
|
"""Si tous les RCUEs de l'année inférieure sont validés, la valide"""
|
||||||
|
# Indice de l'année inférieure:
|
||||||
|
annee_courante = self.rcue.ue_1.niveau_competence.annee # "BUT2"
|
||||||
|
if not re.match(r"^BUT\d$", annee_courante):
|
||||||
|
log("Warning: valide_annee_inferieure invalid annee_courante")
|
||||||
|
return
|
||||||
|
annee_inferieure = int(annee_courante[3]) - 1
|
||||||
|
if annee_inferieure < 1:
|
||||||
|
return
|
||||||
|
# Garde-fou: Année déjà validée ?
|
||||||
|
validations_annee: ApcValidationAnnee = ApcValidationAnnee.query.filter_by(
|
||||||
|
etudid=self.etud.id,
|
||||||
|
ordre=annee_inferieure,
|
||||||
|
formation_id=self.rcue.formsemestre_1.formation_id,
|
||||||
|
).all()
|
||||||
|
if len(validations_annee) > 1:
|
||||||
|
log(
|
||||||
|
f"warning: {len(validations_annee)} validations d'année\n{validations_annee}"
|
||||||
|
)
|
||||||
|
if [
|
||||||
|
validation_annee
|
||||||
|
for validation_annee in validations_annee
|
||||||
|
if sco_codes.code_annee_validant(validation_annee.code)
|
||||||
|
]:
|
||||||
|
return # déja valide
|
||||||
|
validation_annee = validations_annee[0] if validations_annee else None
|
||||||
|
# Liste des niveaux à valider:
|
||||||
|
# ici on sort l'artillerie lourde
|
||||||
|
cursus: EtudCursusBUT = EtudCursusBUT(
|
||||||
|
self.etud, self.rcue.formsemestre_1.formation
|
||||||
|
)
|
||||||
|
niveaux_a_valider = cursus.niveaux_by_annee[annee_inferieure]
|
||||||
|
# Pour chaque niveau, cherche validation RCUE
|
||||||
|
validations_by_niveau = cursus.load_validation_by_niveau()
|
||||||
|
ok = True
|
||||||
|
for niveau in niveaux_a_valider:
|
||||||
|
validation_niveau: ApcValidationRCUE = validations_by_niveau.get(niveau.id)
|
||||||
|
if not validation_niveau or not sco_codes.code_rcue_validant(
|
||||||
|
validation_niveau.code
|
||||||
|
):
|
||||||
|
ok = False
|
||||||
|
|
||||||
|
# Si tous OK, émet validation année
|
||||||
|
if validation_annee: # Modifie la validation antérieure (non validante)
|
||||||
|
validation_annee.code = sco_codes.ADSUP
|
||||||
|
validation_annee.date = datetime.now()
|
||||||
|
log(f"updating {validation_annee}")
|
||||||
|
else:
|
||||||
|
validation_annee = ApcValidationAnnee(
|
||||||
|
etudid=self.etud.id,
|
||||||
|
ordre=annee_inferieure,
|
||||||
|
code=sco_codes.ADSUP,
|
||||||
|
formation_id=self.rcue.formsemestre_1.formation_id,
|
||||||
|
# met cette validation sur l'année scolaire actuelle, pas la précédente (??)
|
||||||
|
annee_scolaire=self.rcue.formsemestre_1.annee_scolaire(),
|
||||||
|
)
|
||||||
|
log(f"recording {validation_annee}")
|
||||||
|
db.session.add(validation_annee)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
def _get_ues_inferieures(
|
||||||
|
self, competence: ApcCompetence, ordre_inferieur: int
|
||||||
|
) -> tuple[list[UniteEns], UniteEns, UniteEns]:
|
||||||
|
"""Les UEs de cette formation associées au niveau de compétence inférieur ?
|
||||||
|
Note: on ne cherche que dans la formation courante, pas les UEs de
|
||||||
|
même code d'autres formations.
|
||||||
|
"""
|
||||||
|
formation: Formation = self.rcue.formsemestre_1.formation
|
||||||
|
ues: list[UniteEns] = (
|
||||||
|
UniteEns.query.filter_by(formation_id=formation.id)
|
||||||
|
.filter(UniteEns.semestre_idx != None)
|
||||||
|
.join(ApcNiveau)
|
||||||
|
.filter_by(ordre=ordre_inferieur)
|
||||||
|
.join(ApcCompetence)
|
||||||
|
.filter_by(id=competence.id)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
log(f"valide_niveau_inferieur: {competence} UEs inférieures: {ues}")
|
||||||
|
if len(ues) != 2: # on n'a pas 2 UE associées au niveau inférieur !
|
||||||
|
flash(
|
||||||
|
"Impossible de valider le niveau de compétence inférieur: pas 2 UEs associées'",
|
||||||
|
"warning",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
ues_impaires = [ue for ue in ues if ue.semestre_idx % 2]
|
||||||
|
if len(ues_impaires) != 1:
|
||||||
|
flash(
|
||||||
|
"Impossible de valider le niveau de compétence inférieur: pas d'UE impaire associée"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
ue1 = ues_impaires[0]
|
||||||
|
ues_paires = [ue for ue in ues if not ue.semestre_idx % 2]
|
||||||
|
if len(ues_paires) != 1:
|
||||||
|
flash(
|
||||||
|
"Impossible de valider le niveau de compétence inférieur: pas d'UE paire associée"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
ue2 = ues_paires[0]
|
||||||
|
return ues, ue1, ue2
|
||||||
|
|
||||||
|
|
||||||
class DecisionsProposeesUE(DecisionsProposees):
|
class DecisionsProposeesUE(DecisionsProposees):
|
||||||
"""Décisions de jury sur une UE du BUT
|
"""Décisions de jury sur une UE du BUT
|
||||||
@ -1383,23 +1578,29 @@ class BUTCursusEtud: # WIP TODO
|
|||||||
for competence in self.competences_du_parcours()
|
for competence in self.competences_du_parcours()
|
||||||
)
|
)
|
||||||
|
|
||||||
def est_diplome(self) -> bool:
|
def est_annee_validee(self, ordre: int) -> bool:
|
||||||
"""Vrai si BUT déjà validé"""
|
"""Vrai si l'année BUT ordre est validée"""
|
||||||
# vrai si la troisième année est validée
|
# On cherche les validations d'annee avec le même
|
||||||
# On cherche les validations de 3ieme annee (ordre=3) avec le même référentiel
|
# code formation que nous.
|
||||||
# de formation que nous.
|
|
||||||
return (
|
return (
|
||||||
ApcValidationAnnee.query.filter_by(etudid=self.etud.id, ordre=3)
|
ApcValidationAnnee.query.filter_by(
|
||||||
.join(FormSemestre, FormSemestre.id == ApcValidationAnnee.formsemestre_id)
|
etudid=self.etud.id,
|
||||||
.join(Formation, FormSemestre.formation_id == Formation.id)
|
ordre=ordre,
|
||||||
|
formation_id=self.formsemestre.formation_id,
|
||||||
|
)
|
||||||
|
.join(Formation)
|
||||||
.filter(
|
.filter(
|
||||||
Formation.referentiel_competence_id
|
Formation.formation_code == self.formsemestre.formation.formation_code
|
||||||
== self.formsemestre.formation.referentiel_competence_id
|
|
||||||
)
|
)
|
||||||
.count()
|
.count()
|
||||||
> 0
|
> 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def est_diplome(self) -> bool:
|
||||||
|
"""Vrai si BUT déjà validé"""
|
||||||
|
# vrai si la troisième année est validée
|
||||||
|
return self.est_annee_validee(3)
|
||||||
|
|
||||||
def competences_du_parcours(self) -> list[ApcCompetence]:
|
def competences_du_parcours(self) -> list[ApcCompetence]:
|
||||||
"""Construit liste des compétences du parcours, qui doivent être
|
"""Construit liste des compétences du parcours, qui doivent être
|
||||||
validées pour obtenir le diplôme.
|
validées pour obtenir le diplôme.
|
||||||
|
@ -307,9 +307,10 @@ class ResultatsSemestreBUT(NotesTableCompat):
|
|||||||
return ues_ids
|
return ues_ids
|
||||||
|
|
||||||
def etud_has_decision(self, etudid) -> bool:
|
def etud_has_decision(self, etudid) -> bool:
|
||||||
"""True s'il y a une décision de jury pour cet étudiant émanant de ce formsemestre.
|
"""True s'il y a une décision (quelconque) de jury
|
||||||
|
émanant de ce formsemestre pour cet étudiant.
|
||||||
prend aussi en compte les autorisations de passage.
|
prend aussi en compte les autorisations de passage.
|
||||||
Sous-classée en BUT pour les RCUEs et années.
|
Ici sous-classée (BUT) pour les RCUEs et années.
|
||||||
"""
|
"""
|
||||||
return bool(
|
return bool(
|
||||||
super().etud_has_decision(etudid)
|
super().etud_has_decision(etudid)
|
||||||
|
@ -320,7 +320,12 @@ class ApcValidationAnnee(db.Model):
|
|||||||
db.Integer, db.ForeignKey("notes_formsemestre.id"), nullable=True
|
db.Integer, db.ForeignKey("notes_formsemestre.id"), nullable=True
|
||||||
)
|
)
|
||||||
"le semestre IMPAIR (le 1er) de l'année"
|
"le semestre IMPAIR (le 1er) de l'année"
|
||||||
annee_scolaire = db.Column(db.Integer, nullable=False) # 2021
|
formation_id = db.Column(
|
||||||
|
db.Integer,
|
||||||
|
db.ForeignKey("notes_formations.id"),
|
||||||
|
nullable=False,
|
||||||
|
)
|
||||||
|
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())
|
||||||
code = db.Column(db.String(CODE_STR_LEN), nullable=False, index=True)
|
code = db.Column(db.String(CODE_STR_LEN), nullable=False, index=True)
|
||||||
|
|
||||||
@ -348,7 +353,7 @@ def dict_decision_jury(etud: Identite, formsemestre: FormSemestre) -> dict:
|
|||||||
"""
|
"""
|
||||||
Un dict avec les décisions de jury BUT enregistrées:
|
Un dict avec les décisions de jury BUT enregistrées:
|
||||||
- decision_rcue : list[dict]
|
- decision_rcue : list[dict]
|
||||||
- decision_annee : dict
|
- decision_annee : dict (décision issue de ce semestre seulement (à confirmer ?))
|
||||||
Ne reprend pas les décisions d'UE, non spécifiques au BUT.
|
Ne reprend pas les décisions d'UE, non spécifiques au BUT.
|
||||||
"""
|
"""
|
||||||
decisions = {}
|
decisions = {}
|
||||||
@ -383,8 +388,7 @@ def dict_decision_jury(etud: Identite, formsemestre: FormSemestre) -> dict:
|
|||||||
etudid=etud.id,
|
etudid=etud.id,
|
||||||
annee_scolaire=formsemestre.annee_scolaire(),
|
annee_scolaire=formsemestre.annee_scolaire(),
|
||||||
)
|
)
|
||||||
.join(ApcValidationAnnee.formsemestre)
|
.join(Formation)
|
||||||
.join(FormSemestre.formation)
|
|
||||||
.filter(Formation.formation_code == formsemestre.formation.formation_code)
|
.filter(Formation.formation_code == formsemestre.formation.formation_code)
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
|
@ -859,7 +859,7 @@ class FormSemestre(db.Model):
|
|||||||
.order_by(UniteEns.numero)
|
.order_by(UniteEns.numero)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
vals_annee = (
|
vals_annee = ( # issues de ce formsemestre seulement
|
||||||
ApcValidationAnnee.query.filter_by(
|
ApcValidationAnnee.query.filter_by(
|
||||||
etudid=etudid,
|
etudid=etudid,
|
||||||
annee_scolaire=self.annee_scolaire(),
|
annee_scolaire=self.annee_scolaire(),
|
||||||
|
@ -122,6 +122,7 @@ ABAN = "ABAN"
|
|||||||
ABL = "ABL"
|
ABL = "ABL"
|
||||||
ADM = "ADM" # moyenne gen., barres UE, assiduité: sem. validé
|
ADM = "ADM" # moyenne gen., barres UE, assiduité: sem. validé
|
||||||
ADC = "ADC" # admis par compensation (eg moy(S1, S2) > 10)
|
ADC = "ADC" # admis par compensation (eg moy(S1, S2) > 10)
|
||||||
|
ADSUP = "ADSUP" # BUT: UE ou RCUE validé par niveau supérieur
|
||||||
ADJ = "ADJ" # admis par le jury
|
ADJ = "ADJ" # admis par le jury
|
||||||
ADJR = "ADJR" # UE admise car son RCUE est ADJ
|
ADJR = "ADJR" # UE admise car son RCUE est ADJ
|
||||||
ATT = "ATT" #
|
ATT = "ATT" #
|
||||||
@ -162,6 +163,7 @@ CODES_EXPL = {
|
|||||||
ADJ: "Validé par le Jury",
|
ADJ: "Validé par le Jury",
|
||||||
ADJR: "UE validée car son RCUE est validé ADJ par le jury",
|
ADJR: "UE validée car son RCUE est validé ADJ par le jury",
|
||||||
ADM: "Validé",
|
ADM: "Validé",
|
||||||
|
ADSUP: "UE ou RCUE validé car le niveau supérieur est validé",
|
||||||
AJ: "Ajourné (ou UE/BC de BUT en attente pour problème de moyenne)",
|
AJ: "Ajourné (ou UE/BC de BUT en attente pour problème de moyenne)",
|
||||||
ATB: "Décision en attente d'un autre semestre (au moins une UE sous la barre)",
|
ATB: "Décision en attente d'un autre semestre (au moins une UE sous la barre)",
|
||||||
ATJ: "Décision en attente d'un autre semestre (assiduité insuffisante)",
|
ATJ: "Décision en attente d'un autre semestre (assiduité insuffisante)",
|
||||||
@ -195,17 +197,18 @@ CODES_SEM_ATTENTES = {ATT, ATB, ATJ} # semestre en attente
|
|||||||
CODES_SEM_REO = {NAR} # reorientation
|
CODES_SEM_REO = {NAR} # reorientation
|
||||||
|
|
||||||
CODES_UE_VALIDES_DE_DROIT = {ADM, CMP} # validation "de droit"
|
CODES_UE_VALIDES_DE_DROIT = {ADM, CMP} # validation "de droit"
|
||||||
CODES_UE_VALIDES = CODES_UE_VALIDES_DE_DROIT | {ADJ, ADJR}
|
CODES_UE_VALIDES = CODES_UE_VALIDES_DE_DROIT | {ADJ, ADJR, ADSUP}
|
||||||
"UE validée"
|
"UE validée"
|
||||||
CODES_UE_CAPITALISANTS = {ADM}
|
CODES_UE_CAPITALISANTS = {ADM}
|
||||||
"UE capitalisée"
|
"UE capitalisée"
|
||||||
|
|
||||||
CODES_RCUE_VALIDES_DE_DROIT = {ADM, CMP}
|
CODES_RCUE_VALIDES_DE_DROIT = {ADM, CMP}
|
||||||
CODES_RCUE_VALIDES = CODES_RCUE_VALIDES_DE_DROIT | {ADJ}
|
CODES_RCUE_VALIDES = CODES_RCUE_VALIDES_DE_DROIT | {ADJ, ADSUP}
|
||||||
"Niveau RCUE validé"
|
"Niveau RCUE validé"
|
||||||
|
|
||||||
# Pour le BUT:
|
# Pour le BUT:
|
||||||
CODES_ANNEE_BUT_VALIDES_DE_DROIT = {ADM, PASD}
|
CODES_ANNEE_BUT_VALIDES_DE_DROIT = {ADM} # PASD était ici mais retiré en juin 23
|
||||||
|
CODES_ANNEE_BUT_VALIDES = {ADM, ADSUP}
|
||||||
CODES_ANNEE_ARRET = {DEF, DEM, ABAN, ABL}
|
CODES_ANNEE_ARRET = {DEF, DEM, ABAN, ABL}
|
||||||
BUT_BARRE_UE8 = 8.0 - NOTES_TOLERANCE
|
BUT_BARRE_UE8 = 8.0 - NOTES_TOLERANCE
|
||||||
BUT_BARRE_UE = BUT_BARRE_RCUE = 10.0 - NOTES_TOLERANCE
|
BUT_BARRE_UE = BUT_BARRE_RCUE = 10.0 - NOTES_TOLERANCE
|
||||||
@ -229,6 +232,7 @@ BUT_CODES_ORDERED = {
|
|||||||
PASD: 50,
|
PASD: 50,
|
||||||
PAS1NCI: 60,
|
PAS1NCI: 60,
|
||||||
ADJR: 90,
|
ADJR: 90,
|
||||||
|
ADSUP: 90,
|
||||||
ADJ: 100,
|
ADJ: 100,
|
||||||
ADM: 100,
|
ADM: 100,
|
||||||
}
|
}
|
||||||
@ -249,6 +253,16 @@ def code_ue_validant(code: str) -> bool:
|
|||||||
return code in CODES_UE_VALIDES
|
return code in CODES_UE_VALIDES
|
||||||
|
|
||||||
|
|
||||||
|
def code_rcue_validant(code: str) -> bool:
|
||||||
|
"Vrai si ce code d'RCUE est validant"
|
||||||
|
return code in CODES_RCUE_VALIDES
|
||||||
|
|
||||||
|
|
||||||
|
def code_annee_validant(code: str) -> bool:
|
||||||
|
"Vrai si code d'année BUT validant"
|
||||||
|
return code in CODES_ANNEE_BUT_VALIDES
|
||||||
|
|
||||||
|
|
||||||
DEVENIR_EXPL = {
|
DEVENIR_EXPL = {
|
||||||
NEXT: "Passage au semestre suivant",
|
NEXT: "Passage au semestre suivant",
|
||||||
REDOANNEE: "Redoublement année",
|
REDOANNEE: "Redoublement année",
|
||||||
|
@ -473,7 +473,10 @@ class ApoEtud(dict):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _but_load_validation_annuelle(self):
|
def _but_load_validation_annuelle(self):
|
||||||
"charge la validation de jury BUT annuelle"
|
"""charge la validation de jury BUT annuelle.
|
||||||
|
Ici impose qu'elle soit issue d'un semestre de l'année en cours
|
||||||
|
(pas forcément nécessaire, voir selon les retours des équipes ?)
|
||||||
|
"""
|
||||||
# le semestre impair de l'année scolaire
|
# le semestre impair de l'année scolaire
|
||||||
if self.cur_res.formsemestre.semestre_id % 2:
|
if self.cur_res.formsemestre.semestre_id % 2:
|
||||||
formsemestre = self.cur_res.formsemestre
|
formsemestre = self.cur_res.formsemestre
|
||||||
@ -490,7 +493,9 @@ class ApoEtud(dict):
|
|||||||
return
|
return
|
||||||
self.validation_annee_but: ApcValidationAnnee = (
|
self.validation_annee_but: ApcValidationAnnee = (
|
||||||
ApcValidationAnnee.query.filter_by(
|
ApcValidationAnnee.query.filter_by(
|
||||||
formsemestre_id=formsemestre.id, etudid=self.etud["etudid"]
|
formsemestre_id=formsemestre.id,
|
||||||
|
etudid=self.etud["etudid"],
|
||||||
|
formation_id=self.cur_sem["formation_id"],
|
||||||
).first()
|
).first()
|
||||||
)
|
)
|
||||||
self.is_nar = (
|
self.is_nar = (
|
||||||
|
@ -66,6 +66,7 @@ from app.scodoc import sco_photos
|
|||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_pv_dict
|
from app.scodoc import sco_pv_dict
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------
|
||||||
def formsemestre_validation_etud_form(
|
def formsemestre_validation_etud_form(
|
||||||
formsemestre_id=None, # required
|
formsemestre_id=None, # required
|
||||||
@ -1063,8 +1064,6 @@ def formsemestre_validate_previous_ue(formsemestre_id, etudid):
|
|||||||
"""Form. saisie UE validée hors ScoDoc
|
"""Form. saisie UE validée hors ScoDoc
|
||||||
(pour étudiants arrivant avec un UE antérieurement validée).
|
(pour étudiants arrivant avec un UE antérieurement validée).
|
||||||
"""
|
"""
|
||||||
from app.scodoc import sco_formations
|
|
||||||
|
|
||||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||||
formation: Formation = Formation.query.get_or_404(sem["formation_id"])
|
formation: Formation = Formation.query.get_or_404(sem["formation_id"])
|
||||||
@ -1087,8 +1086,8 @@ def formsemestre_validate_previous_ue(formsemestre_id, etudid):
|
|||||||
<em>dans un semestre hors ScoDoc</em>.</p>
|
<em>dans un semestre hors ScoDoc</em>.</p>
|
||||||
<p><b>Les UE validées dans ScoDoc sont déjà
|
<p><b>Les UE validées dans ScoDoc sont déjà
|
||||||
automatiquement prises en compte</b>. Cette page n'est utile que pour les étudiants ayant
|
automatiquement prises en compte</b>. Cette page n'est utile que pour les étudiants ayant
|
||||||
suivi un début de cursus dans <b>un autre établissement</b>, ou bien dans un semestre géré <b>sans
|
suivi un début de cursus dans <b>un autre établissement</b>, ou bien dans un semestre géré
|
||||||
ScoDoc</b> et qui <b>redouble</b> ce semestre
|
<b>sans ScoDoc</b> et qui <b>redouble</b> ce semestre
|
||||||
(<em>ne pas utiliser pour les semestres précédents !</em>).
|
(<em>ne pas utiliser pour les semestres précédents !</em>).
|
||||||
</p>
|
</p>
|
||||||
<p>Notez que l'UE est validée, avec enregistrement immédiat de la décision et
|
<p>Notez que l'UE est validée, avec enregistrement immédiat de la décision et
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
"""validation niveaux inferieurs
|
||||||
|
|
||||||
|
Revision ID: c701224fa255
|
||||||
|
Revises: d84bc592584e
|
||||||
|
Create Date: 2023-06-11 11:08:05.553898
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.orm import sessionmaker # added by ev
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "c701224fa255"
|
||||||
|
down_revision = "d84bc592584e"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
Session = sessionmaker()
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# Ajoute la colonne formation_id, nullable, la peuple puis la rend non nullable
|
||||||
|
op.add_column(
|
||||||
|
"apc_validation_annee", sa.Column("formation_id", sa.Integer(), nullable=True)
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"apc_validation_annee_formation_id_fkey",
|
||||||
|
"apc_validation_annee",
|
||||||
|
"notes_formations",
|
||||||
|
["formation_id"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Affecte la formation des anciennes validations
|
||||||
|
bind = op.get_bind()
|
||||||
|
session = Session(bind=bind)
|
||||||
|
session.execute(
|
||||||
|
sa.text(
|
||||||
|
"""
|
||||||
|
UPDATE apc_validation_annee AS a
|
||||||
|
SET formation_id = (
|
||||||
|
SELECT f.id
|
||||||
|
FROM notes_formations f
|
||||||
|
JOIN notes_formsemestre s ON f.id = s.formation_id
|
||||||
|
WHERE s.id = a.formsemestre_id
|
||||||
|
)
|
||||||
|
WHERE a.formsemestre_id IS NOT NULL;
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
op.alter_column(
|
||||||
|
"apc_validation_annee",
|
||||||
|
"formation_id",
|
||||||
|
nullable=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
with op.batch_alter_table("apc_validation_annee", schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint(
|
||||||
|
"apc_validation_annee_formation_id_fkey", type_="foreignkey"
|
||||||
|
)
|
||||||
|
batch_op.drop_column("formation_id")
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.4.83"
|
SCOVERSION = "9.4.84"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
@ -12,109 +12,109 @@ Formation:
|
|||||||
# Association des UEs aux compétences:
|
# Association des UEs aux compétences:
|
||||||
ues:
|
ues:
|
||||||
# S1 tronc commun:
|
# S1 tronc commun:
|
||||||
'UE1.1':
|
"UE1.1":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: "Solutions Bâtiment"
|
competence: "Solutions Bâtiment"
|
||||||
'UE1.2':
|
"UE1.2":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: "Solutions TP"
|
competence: "Solutions TP"
|
||||||
'UE1.3':
|
"UE1.3":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: "Dimensionner"
|
competence: "Dimensionner"
|
||||||
'UE1.4':
|
"UE1.4":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: Organiser
|
competence: Organiser
|
||||||
'UE1.5':
|
"UE1.5":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: Piloter
|
competence: Piloter
|
||||||
# S2 tronc commun:
|
# S2 tronc commun:
|
||||||
'UE2.1':
|
"UE2.1":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: "Solutions Bâtiment"
|
competence: "Solutions Bâtiment"
|
||||||
'UE2.2':
|
"UE2.2":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: "Solutions TP"
|
competence: "Solutions TP"
|
||||||
'UE2.3':
|
"UE2.3":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: "Dimensionner"
|
competence: "Dimensionner"
|
||||||
'UE2.4':
|
"UE2.4":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: Organiser
|
competence: Organiser
|
||||||
'UE2.5':
|
"UE2.5":
|
||||||
annee: BUT1
|
annee: BUT1
|
||||||
competence: Piloter
|
competence: Piloter
|
||||||
|
|
||||||
# S3 : Tronc commun
|
# S3 : Tronc commun
|
||||||
'UE3.1':
|
"UE3.1":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: "Solutions Bâtiment"
|
competence: "Solutions Bâtiment"
|
||||||
'UE3.2':
|
"UE3.2":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: "Solutions TP"
|
competence: "Solutions TP"
|
||||||
'UE3.3':
|
"UE3.3":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: "Dimensionner"
|
competence: "Dimensionner"
|
||||||
'UE3.4':
|
"UE3.4":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: Organiser
|
competence: Organiser
|
||||||
'UE3.5':
|
"UE3.5":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: Piloter
|
competence: Piloter
|
||||||
# S4 Tronc commun
|
# S4 Tronc commun
|
||||||
'UE4.1':
|
"UE4.1":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: "Solutions Bâtiment"
|
competence: "Solutions Bâtiment"
|
||||||
'UE4.2':
|
"UE4.2":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: "Solutions TP"
|
competence: "Solutions TP"
|
||||||
'UE4.3':
|
"UE4.3":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: "Dimensionner"
|
competence: "Dimensionner"
|
||||||
'UE4.4':
|
"UE4.4":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: Organiser
|
competence: Organiser
|
||||||
'UE4.5':
|
"UE4.5":
|
||||||
annee: BUT2
|
annee: BUT2
|
||||||
competence: Piloter
|
competence: Piloter
|
||||||
# S5 Parcours BAT + TP
|
# S5 Parcours BAT + TP
|
||||||
'UE5.1': # Parcours BAT seulement
|
"UE5.1": # Parcours BAT seulement
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: BAT # + RAPEB, BEC
|
parcours: BAT # + RAPEB, BEC
|
||||||
competence: "Solutions Bâtiment"
|
competence: "Solutions Bâtiment"
|
||||||
'UE5.2': # Parcours TP seulement
|
"UE5.2": # Parcours TP seulement
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: TP # + BEC
|
parcours: TP # + BEC
|
||||||
competence: "Solutions TP"
|
competence: "Solutions TP"
|
||||||
'UE5.3':
|
"UE5.3":
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: [RAPEB, BEC]
|
parcours: [RAPEB, BEC]
|
||||||
competence: "Dimensionner"
|
competence: "Dimensionner"
|
||||||
'UE5.4':
|
"UE5.4":
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: [BAT, TP]
|
parcours: [BAT, TP]
|
||||||
competence: Organiser
|
competence: Organiser
|
||||||
'UE5.5':
|
"UE5.5":
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: [BAT, TP]
|
parcours: [BAT, TP]
|
||||||
competence: Piloter
|
competence: Piloter
|
||||||
# S6 Parcours BAT + TP
|
# S6 Parcours BAT + TP
|
||||||
'UE6.1': # Parcours BAT seulement
|
"UE6.1": # Parcours BAT seulement
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: BAT # + RAPEB, BEC
|
parcours: BAT # + RAPEB, BEC
|
||||||
competence: "Solutions Bâtiment"
|
competence: "Solutions Bâtiment"
|
||||||
'UE6.2': # Parcours TP seulement
|
"UE6.2": # Parcours TP seulement
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: [TP, BEC]
|
parcours: [TP, BEC]
|
||||||
competence: "Solutions TP"
|
competence: "Solutions TP"
|
||||||
'UE6.3':
|
"UE6.3":
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: [RAPEB, BEC]
|
parcours: [RAPEB, BEC]
|
||||||
competence: "Dimensionner"
|
competence: "Dimensionner"
|
||||||
'UE6.4':
|
"UE6.4":
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: [BAT, TP]
|
parcours: [BAT, TP]
|
||||||
competence: Organiser
|
competence: Organiser
|
||||||
'UE6.5':
|
"UE6.5":
|
||||||
annee: BUT3
|
annee: BUT3
|
||||||
parcours: [BAT, TP]
|
parcours: [BAT, TP]
|
||||||
competence: Piloter
|
competence: Piloter
|
||||||
@ -135,32 +135,32 @@ FormSemestres:
|
|||||||
idx: 1
|
idx: 1
|
||||||
date_debut: 2021-09-01
|
date_debut: 2021-09-01
|
||||||
date_fin: 2022-01-15
|
date_fin: 2022-01-15
|
||||||
codes_parcours: ['BAT', 'TP']
|
codes_parcours: ["BAT", "TP"]
|
||||||
S2:
|
S2:
|
||||||
idx: 2
|
idx: 2
|
||||||
date_debut: 2022-01-15
|
date_debut: 2022-01-15
|
||||||
date_fin: 2022-06-30
|
date_fin: 2022-06-30
|
||||||
codes_parcours: ['BAT', 'TP']
|
codes_parcours: ["BAT", "TP"]
|
||||||
S3:
|
S3:
|
||||||
idx: 3
|
idx: 3
|
||||||
date_debut: 2022-09-01
|
date_debut: 2022-09-01
|
||||||
date_fin: 2023-01-15
|
date_fin: 2023-01-15
|
||||||
codes_parcours: ['BAT', 'TP']
|
codes_parcours: ["BAT", "TP"]
|
||||||
S4:
|
S4:
|
||||||
idx: 4
|
idx: 4
|
||||||
date_debut: 2023-01-16
|
date_debut: 2023-01-16
|
||||||
date_fin: 2023-06-30
|
date_fin: 2023-06-30
|
||||||
codes_parcours: ['BAT', 'TP']
|
codes_parcours: ["BAT", "TP"]
|
||||||
S5:
|
S5:
|
||||||
idx: 5
|
idx: 5
|
||||||
date_debut: 2023-09-01
|
date_debut: 2023-09-01
|
||||||
date_fin: 2024-01-15
|
date_fin: 2024-01-15
|
||||||
codes_parcours: ['BAT', 'TP']
|
codes_parcours: ["BAT", "TP"]
|
||||||
S6:
|
S6:
|
||||||
idx: 6
|
idx: 6
|
||||||
date_debut: 2024-01-16
|
date_debut: 2024-01-16
|
||||||
date_fin: 2024-06-30
|
date_fin: 2024-06-30
|
||||||
codes_parcours: ['BAT', 'TP']
|
codes_parcours: ["BAT", "TP"]
|
||||||
|
|
||||||
Etudiants:
|
Etudiants:
|
||||||
A_ok: # Etudiant parcours BAT qui va tout valider directement
|
A_ok: # Etudiant parcours BAT qui va tout valider directement
|
||||||
@ -171,10 +171,18 @@ Etudiants:
|
|||||||
parcours: BAT
|
parcours: BAT
|
||||||
notes_modules:
|
notes_modules:
|
||||||
"R1.01": 11 # toutes UEs
|
"R1.01": 11 # toutes UEs
|
||||||
|
"SAÉ 1-2": EXC
|
||||||
S2:
|
S2:
|
||||||
parcours: BAT
|
parcours: BAT
|
||||||
notes_modules:
|
notes_modules:
|
||||||
"R2.01": 12 # toutes UEs
|
"R2.01": 12 # toutes UEs
|
||||||
|
attendu: # les codes jury que l'on doit vérifier
|
||||||
|
deca:
|
||||||
|
passage_de_droit: True
|
||||||
|
autorisations_inscription: [3]
|
||||||
|
code_valide:
|
||||||
|
nb_competences: 5
|
||||||
|
nb_rcue_annee: 4
|
||||||
S3:
|
S3:
|
||||||
parcours: BAT
|
parcours: BAT
|
||||||
notes_modules:
|
notes_modules:
|
||||||
@ -186,7 +194,7 @@ Etudiants:
|
|||||||
|
|
||||||
S5:
|
S5:
|
||||||
parcours: BAT
|
parcours: BAT
|
||||||
dispense_ues: ['UE5.2', 'UE5.3']
|
dispense_ues: ["UE5.2", "UE5.3"]
|
||||||
notes_modules:
|
notes_modules:
|
||||||
"R5.01": 15 # toutes UE
|
"R5.01": 15 # toutes UE
|
||||||
"SAÉ 5.BAT.01": 10 # UE5.1
|
"SAÉ 5.BAT.01": 10 # UE5.1
|
||||||
@ -202,6 +210,7 @@ Etudiants:
|
|||||||
parcours: TP
|
parcours: TP
|
||||||
notes_modules:
|
notes_modules:
|
||||||
"R1.01": 11 # toutes UEs
|
"R1.01": 11 # toutes UEs
|
||||||
|
"SAÉ 1-2": EXC
|
||||||
S2:
|
S2:
|
||||||
parcours: TP
|
parcours: TP
|
||||||
notes_modules:
|
notes_modules:
|
||||||
@ -217,10 +226,32 @@ Etudiants:
|
|||||||
|
|
||||||
S5:
|
S5:
|
||||||
parcours: TP
|
parcours: TP
|
||||||
dispense_ues: ['UE5.1', 'UE5.3']
|
dispense_ues: ["UE5.1", "UE5.3"]
|
||||||
notes_modules:
|
notes_modules:
|
||||||
"R5.01": 15 # toutes UE
|
"R5.01": 15 # toutes UE
|
||||||
"SAÉ 5.BAT.01": 10 # UE5.1
|
"SAÉ 5.BAT.01": 10 # UE5.1
|
||||||
"SAÉ 5.BAT.02": 11 # UE5.4
|
"SAÉ 5.BAT.02": 11 # UE5.4
|
||||||
S6:
|
S6:
|
||||||
parcours: TP
|
parcours: TP
|
||||||
|
|
||||||
|
C: # Etudiant qui passe sans un RCUE et valide en BUT2
|
||||||
|
prenom: Étudiant_TP_but2
|
||||||
|
civilite: M
|
||||||
|
formsemestres:
|
||||||
|
S1:
|
||||||
|
parcours: TP
|
||||||
|
notes_modules:
|
||||||
|
"R1.01": 11 # toutes UEs
|
||||||
|
"SAÉ 1-2": 8 # plombe l'UE 2
|
||||||
|
S2:
|
||||||
|
parcours: TP
|
||||||
|
notes_modules:
|
||||||
|
"R2.01": 11 # toutes UEs
|
||||||
|
S3:
|
||||||
|
parcours: TP
|
||||||
|
notes_modules:
|
||||||
|
"R3.01": 12 # toutes UEs
|
||||||
|
S4:
|
||||||
|
parcours: TP
|
||||||
|
notes_modules:
|
||||||
|
"R4.01": 14 # toutes UE
|
||||||
|
Loading…
Reference in New Issue
Block a user