2023-07-16 19:59:45 +02:00
|
|
|
##############################################################################
|
|
|
|
# ScoDoc
|
|
|
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
|
|
|
# See LICENSE
|
|
|
|
##############################################################################
|
|
|
|
|
|
|
|
"""Jury édition manuelle des décisions (correction d'erreurs, parcours hors normes)
|
|
|
|
|
|
|
|
Non spécifique au BUT.
|
|
|
|
"""
|
|
|
|
|
|
|
|
from flask import render_template
|
|
|
|
import sqlalchemy as sa
|
|
|
|
|
|
|
|
from app import log
|
|
|
|
from app.but import cursus_but
|
|
|
|
from app.models import (
|
|
|
|
ApcCompetence,
|
|
|
|
ApcNiveau,
|
|
|
|
ApcReferentielCompetences,
|
|
|
|
# ApcValidationAnnee, # TODO
|
|
|
|
ApcValidationRCUE,
|
|
|
|
Formation,
|
|
|
|
FormSemestre,
|
|
|
|
Identite,
|
|
|
|
UniteEns,
|
|
|
|
# ScolarAutorisationInscription,
|
|
|
|
ScolarFormSemestreValidation,
|
|
|
|
)
|
|
|
|
from app.scodoc import codes_cursus
|
|
|
|
from app.scodoc.sco_exceptions import ScoNoReferentielCompetences
|
|
|
|
from app.views import ScoData
|
|
|
|
|
|
|
|
|
|
|
|
def validation_rcues(etud: Identite, formsemestre: FormSemestre, edit: bool = False):
|
|
|
|
"""Page de saisie des décisions de RCUEs "antérieures"
|
|
|
|
On peut l'utiliser pour saisir la validation de n'importe quel RCUE
|
|
|
|
d'une année antérieure et de la formation du formsemestre indiqué.
|
|
|
|
"""
|
|
|
|
formation: Formation = formsemestre.formation
|
|
|
|
refcomp = formation.referentiel_competence
|
|
|
|
if refcomp is None:
|
|
|
|
raise ScoNoReferentielCompetences(formation=formation)
|
|
|
|
parcour = formsemestre.etuds_inscriptions[etud.id].parcour
|
|
|
|
# Si non inscrit à un parcours, prend toutes les compétences
|
2023-10-19 22:24:56 +02:00
|
|
|
competences_parcour, ects_parcours = cursus_but.parcour_formation_competences(
|
|
|
|
parcour, formation
|
|
|
|
)
|
2023-07-16 19:59:45 +02:00
|
|
|
|
|
|
|
ue_validation_by_niveau = get_ue_validation_by_niveau(refcomp, etud)
|
|
|
|
rcue_validation_by_niveau = get_rcue_validation_by_niveau(refcomp, etud)
|
2023-10-19 22:24:56 +02:00
|
|
|
ects_acquis = sum((v.ects() for v in ue_validation_by_niveau.values()))
|
|
|
|
|
2023-07-16 19:59:45 +02:00
|
|
|
return render_template(
|
|
|
|
"but/validation_rcues.j2",
|
|
|
|
competences_parcour=competences_parcour,
|
|
|
|
edit=edit,
|
2023-10-19 22:24:56 +02:00
|
|
|
ects_acquis=ects_acquis,
|
|
|
|
ects_parcours=ects_parcours,
|
2023-07-16 19:59:45 +02:00
|
|
|
formation=formation,
|
|
|
|
parcour=parcour,
|
|
|
|
rcue_validation_by_niveau=rcue_validation_by_niveau,
|
|
|
|
rcue_codes=sorted(codes_cursus.CODES_JURY_RCUE),
|
|
|
|
sco=ScoData(formsemestre=formsemestre, etud=etud),
|
|
|
|
title=f"{formation.acronyme} - Niveaux et UEs",
|
|
|
|
ue_validation_by_niveau=ue_validation_by_niveau,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def get_ue_validation_by_niveau(
|
|
|
|
refcomp: ApcReferentielCompetences, etud: Identite
|
|
|
|
) -> dict[tuple[int, str], ScolarFormSemestreValidation]:
|
|
|
|
"""Les validations d'UEs de cet étudiant liées à ce référentiel de compétences.
|
|
|
|
Pour chaque niveau / pair ou impair, choisi la "meilleure" validation
|
|
|
|
"""
|
|
|
|
validations: list[ScolarFormSemestreValidation] = (
|
|
|
|
ScolarFormSemestreValidation.query.filter_by(etudid=etud.id)
|
|
|
|
.join(UniteEns)
|
|
|
|
.join(ApcNiveau)
|
|
|
|
.join(ApcCompetence)
|
|
|
|
.filter_by(referentiel_id=refcomp.id)
|
|
|
|
.all()
|
|
|
|
)
|
|
|
|
# La meilleure validation pour chaque UE
|
|
|
|
ue_validation_by_niveau = {} # { (niveau_id, pair|impair) : validation }
|
|
|
|
for validation in validations:
|
|
|
|
if validation.ue.niveau_competence is None:
|
|
|
|
log(
|
|
|
|
f"""validation_rcues: ignore validation d'UE {
|
|
|
|
validation.ue.id} pas de niveau de competence"""
|
|
|
|
)
|
|
|
|
key = (
|
|
|
|
validation.ue.niveau_competence.id,
|
|
|
|
"impair" if validation.ue.semestre_idx % 2 else "pair",
|
|
|
|
)
|
|
|
|
existing = ue_validation_by_niveau.get(key, None)
|
|
|
|
if (not existing) or (
|
|
|
|
codes_cursus.BUT_CODES_ORDER[existing.code]
|
|
|
|
< codes_cursus.BUT_CODES_ORDER[validation.code]
|
|
|
|
):
|
|
|
|
ue_validation_by_niveau[key] = validation
|
|
|
|
return ue_validation_by_niveau
|
|
|
|
|
|
|
|
|
|
|
|
def get_rcue_validation_by_niveau(
|
|
|
|
refcomp: ApcReferentielCompetences, etud: Identite
|
|
|
|
) -> dict[int, ApcValidationRCUE]:
|
|
|
|
"""Les validations d'UEs de cet étudiant liées à ce référentiel de compétences.
|
|
|
|
Pour chaque niveau / pair ou impair, choisi la "meilleure" validation
|
|
|
|
"""
|
|
|
|
validations: list[ApcValidationRCUE] = (
|
|
|
|
ApcValidationRCUE.query.filter_by(etudid=etud.id)
|
|
|
|
.join(UniteEns, UniteEns.id == ApcValidationRCUE.ue2_id)
|
|
|
|
.join(ApcNiveau, UniteEns.niveau_competence_id == ApcNiveau.id)
|
|
|
|
.join(ApcCompetence)
|
|
|
|
.filter_by(referentiel_id=refcomp.id)
|
|
|
|
.all()
|
|
|
|
)
|
|
|
|
return {
|
|
|
|
validation.ue2.niveau_competence.id: validation for validation in validations
|
|
|
|
}
|