forked from ScoDoc/ScoDoc
139 lines
5.2 KiB
Python
139 lines
5.2 KiB
Python
##############################################################################
|
|
# ScoDoc
|
|
# Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved.
|
|
# See LICENSE
|
|
##############################################################################
|
|
|
|
"""Jury édition manuelle des décisions RCUE antérieures
|
|
"""
|
|
|
|
from flask import render_template
|
|
|
|
from app import db, log
|
|
from app.but import cursus_but
|
|
from app.models import (
|
|
ApcCompetence,
|
|
ApcNiveau,
|
|
ApcReferentielCompetences,
|
|
# ApcValidationAnnee, # TODO
|
|
ApcValidationRCUE,
|
|
Formation,
|
|
FormSemestre,
|
|
Identite,
|
|
# ScolarAutorisationInscription,
|
|
ScolarFormSemestreValidation,
|
|
UniteEns,
|
|
)
|
|
from app.models.ues import UEParcours
|
|
from app.scodoc import codes_cursus
|
|
from app.scodoc.sco_exceptions import ScoNoReferentielCompetences, ScoValueError
|
|
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)
|
|
if etud.id not in formsemestre.etuds_inscriptions:
|
|
raise ScoValueError(
|
|
f"Etudiant {etud.nom_prenom()} non inscrit à {formsemestre.titre_mois()}"
|
|
)
|
|
parcour = formsemestre.etuds_inscriptions[etud.id].parcour
|
|
# Si non inscrit à un parcours, prend toutes les compétences
|
|
competences_parcour, ects_parcours = cursus_but.parcour_formation_competences(
|
|
parcour, formation
|
|
)
|
|
|
|
ue_validation_by_niveau = get_ue_validation_by_niveau(refcomp, etud)
|
|
rcue_validation_by_niveau = get_rcue_validation_by_niveau(
|
|
refcomp, etud, None if parcour is None else parcour.id
|
|
)
|
|
ects_acquis = sum((v.ects() for v in ue_validation_by_niveau.values()))
|
|
|
|
return render_template(
|
|
"but/validation_rcues.j2",
|
|
competences_parcour=competences_parcour,
|
|
edit=edit,
|
|
ects_acquis=ects_acquis,
|
|
ects_parcours=ects_parcours,
|
|
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
|
|
dans le parcours suivi par l'étudiant (celui de son semestre le plus récent
|
|
dans un semestre de ce référentiel).
|
|
Pour chaque niveau / pair ou impair, choisi la "meilleure" validation.
|
|
"""
|
|
parcour = cursus_but.get_etud_parcours(etud, refcomp.id)
|
|
validations = (
|
|
cursus_but.but_validations_ues_parcours(etud, parcour.id)
|
|
if parcour is not None
|
|
else cursus_but.but_validations_ues(etud, refcomp.id)
|
|
)
|
|
|
|
# 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, parcour_id: int | None
|
|
) -> dict[int, ApcValidationRCUE]:
|
|
"""Les validations d'UEs de cet étudiant liées à ce référentiel de compétences.
|
|
Si parcour_id n'est pas None, restreint aux niveaux de ce parcours
|
|
et du tronc commun.
|
|
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)
|
|
.filter(
|
|
db.or_(
|
|
UniteEns.id.in_(
|
|
UEParcours.query.with_entities(UEParcours.ue_id).filter(
|
|
UEParcours.parcours_id == parcour_id
|
|
)
|
|
),
|
|
~UniteEns.id.in_(UEParcours.query.with_entities(UEParcours.ue_id)),
|
|
)
|
|
)
|
|
.all()
|
|
)
|
|
return {
|
|
validation.ue2.niveau_competence.id: validation for validation in validations
|
|
}
|