Jury BUT: traitement des DEF et DEM. Close #426

This commit is contained in:
Emmanuel Viennet 2022-07-04 23:50:55 +02:00
parent fa358c2da4
commit 512b38665f
4 changed files with 78 additions and 20 deletions

View File

@ -68,7 +68,7 @@ from flask import g, url_for
from app import db from app import db
from app import log from app import log
from app.comp.res_but import ResultatsSemestreBUT from app.comp.res_but import ResultatsSemestreBUT
from app.comp import res_sem from app.comp import inscr_mod, res_sem
from app.models import formsemestre from app.models import formsemestre
from app.models.but_refcomp import ( from app.models.but_refcomp import (
@ -219,15 +219,16 @@ class DecisionsProposeesAnnee(DecisionsProposees):
"le 1er semestre de l'année scolaire considérée (S1, S3, S5)" "le 1er semestre de l'année scolaire considérée (S1, S3, S5)"
self.formsemestre_pair = formsemestre_pair self.formsemestre_pair = formsemestre_pair
"le second formsemestre de la même année scolaire (S2, S4, S6)" "le second formsemestre de la même année scolaire (S2, S4, S6)"
self.annee_but = ( formsemestre_last = formsemestre_pair or formsemestre_impair
(formsemestre_impair.semestre_id + 1) // 2 "le formsemestre le plus avancé dans cette année"
if formsemestre_impair
else (formsemestre_pair.semestre_id + 1) // 2 self.annee_but = (formsemestre_last.semestre_id + 1) // 2
)
"le rang de l'année dans le BUT: 1, 2, 3" "le rang de l'année dans le BUT: 1, 2, 3"
assert self.annee_but in (1, 2, 3) assert self.annee_but in (1, 2, 3)
self.rcues_annee = [] self.rcues_annee = []
"RCUEs de l'année" "RCUEs de l'année"
self.inscription_etat = etud.inscription_etat(formsemestre_last.id)
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,
@ -255,13 +256,17 @@ class DecisionsProposeesAnnee(DecisionsProposees):
self.ues_impair, self.ues_pair = self.compute_ues_annee() # pylint: disable=all self.ues_impair, self.ues_pair = self.compute_ues_annee() # pylint: disable=all
self.decisions_ues = { self.decisions_ues = {
ue.id: DecisionsProposeesUE(etud, formsemestre_impair, ue) ue.id: DecisionsProposeesUE(
etud, formsemestre_impair, ue, self.inscription_etat
)
for ue in self.ues_impair for ue in self.ues_impair
} }
"{ue_id : DecisionsProposeesUE} pour toutes les UE de l'année" "{ue_id : DecisionsProposeesUE} pour toutes les UE de l'année"
self.decisions_ues.update( self.decisions_ues.update(
{ {
ue.id: DecisionsProposeesUE(etud, formsemestre_pair, ue) ue.id: DecisionsProposeesUE(
etud, formsemestre_pair, ue, self.inscription_etat
)
for ue in self.ues_pair for ue in self.ues_pair
} }
) )
@ -291,8 +296,10 @@ class DecisionsProposeesAnnee(DecisionsProposees):
[rcue for rcue in rcues_avec_niveau if not rcue.est_suffisant()] [rcue for rcue in rcues_avec_niveau if not rcue.est_suffisant()]
) )
"le nb de comp. sous la barre de 8/20" "le nb de comp. sous la barre de 8/20"
# année ADM si toutes RCUE validées (sinon PASD) # année ADM si toutes RCUE validées (sinon PASD) et non DEM ou DEF
self.admis = self.nb_validables == self.nb_competences self.admis = (self.nb_validables == self.nb_competences) and (
self.inscription_etat == scu.INSCRIT
)
"vrai si l'année est réussie, tous niveaux validables" "vrai si l'année est réussie, tous niveaux validables"
self.valide_moitie_rcue = self.nb_validables > (self.nb_competences // 2) self.valide_moitie_rcue = self.nb_validables > (self.nb_competences // 2)
# Peut passer si plus de la moitié validables et tous > 8 # Peut passer si plus de la moitié validables et tous > 8
@ -310,6 +317,19 @@ class DecisionsProposeesAnnee(DecisionsProposees):
if self.admis: if self.admis:
self.codes = [sco_codes.ADM] + self.codes self.codes = [sco_codes.ADM] + self.codes
self.explanation = expl_rcues self.explanation = expl_rcues
elif self.inscription_etat != scu.INSCRIT:
self.codes = [
sco_codes.DEM
if self.inscription_etat == scu.DEMISSION
else sco_codes.DEF,
# propose aussi d'autres codes, au cas où...
sco_codes.DEM
if self.inscription_etat != scu.DEMISSION
else sco_codes.DEF,
sco_codes.ABAN,
sco_codes.ABL,
sco_codes.EXCLU,
]
elif self.passage_de_droit: elif self.passage_de_droit:
self.codes = [sco_codes.PASD, sco_codes.ADJ] + self.codes self.codes = [sco_codes.PASD, sco_codes.ADJ] + self.codes
self.explanation = expl_rcues self.explanation = expl_rcues
@ -482,6 +502,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
ue_impair, ue_impair,
self.formsemestre_pair, self.formsemestre_pair,
ue_pair, ue_pair,
self.inscription_etat,
) )
ues_impair_sans_rcue.discard(ue_impair.id) ues_impair_sans_rcue.discard(ue_impair.id)
break break
@ -509,7 +530,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
rcue = rc rcue = rc
break break
if rcue is not None: if rcue is not None:
dec_rcue = DecisionsProposeesRCUE(self, rcue) dec_rcue = DecisionsProposeesRCUE(self, rcue, self.inscription_etat)
rc_niveaux.append((dec_rcue, niveau.id)) rc_niveaux.append((dec_rcue, niveau.id))
# prévient les UE concernées :-) # prévient les UE concernées :-)
self.decisions_ues[dec_rcue.rcue.ue_1.id].set_rcue(dec_rcue.rcue) self.decisions_ues[dec_rcue.rcue.ue_1.id].set_rcue(dec_rcue.rcue)
@ -724,14 +745,26 @@ class DecisionsProposeesRCUE(DecisionsProposees):
] ]
def __init__( def __init__(
self, dec_prop_annee: DecisionsProposeesAnnee, rcue: RegroupementCoherentUE self,
dec_prop_annee: DecisionsProposeesAnnee,
rcue: RegroupementCoherentUE,
inscription_etat: str = scu.INSCRIT,
): ):
super().__init__(etud=dec_prop_annee.etud) super().__init__(etud=dec_prop_annee.etud)
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 = []
return return
self.inscription_etat = inscription_etat
"inscription: I, DEM, DEF"
self.parcour = dec_prop_annee.parcour self.parcour = dec_prop_annee.parcour
if inscription_etat != scu.INSCRIT:
self.validation = None # cache toute validation
self.explanation = "non incrit (dem. ou déf.)"
self.codes = [
sco_codes.DEM if inscription_etat == scu.DEMISSION else sco_codes.DEF
]
return
self.validation = rcue.query_validations().first() self.validation = rcue.query_validations().first()
if self.validation is not None: if self.validation is not None:
self.code_valide = self.validation.code self.code_valide = self.validation.code
@ -828,12 +861,27 @@ class DecisionsProposeesUE(DecisionsProposees):
etud: Identite, etud: Identite,
formsemestre: FormSemestre, formsemestre: FormSemestre,
ue: UniteEns, ue: UniteEns,
inscription_etat: str = scu.INSCRIT,
): ):
super().__init__(etud=etud) super().__init__(etud=etud)
self.formsemestre = formsemestre self.formsemestre = formsemestre
self.ue: UniteEns = ue self.ue: UniteEns = ue
self.rcue: RegroupementCoherentUE = None self.rcue: RegroupementCoherentUE = None
"Le rcu auquel est rattaché cette UE, ou None" "Le rcu auquel est rattaché cette UE, ou None"
self.inscription_etat = inscription_etat
"inscription: I, DEM, DEF"
if ue.type == sco_codes.UE_SPORT:
self.explanation = "UE bonus, pas de décision de jury"
self.codes = [] # aucun code proposé
return
if inscription_etat != scu.INSCRIT:
self.validation = None # cache toute validation
self.explanation = "non incrit (dem. ou déf.)"
self.codes = [
sco_codes.DEM if inscription_etat == scu.DEMISSION else sco_codes.DEF
]
self.moy_ue = "-"
return
# Une UE peut être validée plusieurs fois en cas de redoublement (qu'elle soit capitalisée ou non) # Une UE peut être validée plusieurs fois en cas de redoublement (qu'elle soit capitalisée ou non)
# mais ici on a restreint au formsemestre donc une seule (prend la première) # mais ici on a restreint au formsemestre donc une seule (prend la première)
self.validation = ScolarFormSemestreValidation.query.filter_by( self.validation = ScolarFormSemestreValidation.query.filter_by(
@ -841,10 +889,6 @@ class DecisionsProposeesUE(DecisionsProposees):
).first() ).first()
if self.validation is not None: if self.validation is not None:
self.code_valide = self.validation.code self.code_valide = self.validation.code
if ue.type == sco_codes.UE_SPORT:
self.explanation = "UE bonus, pas de décision de jury"
self.codes = [] # aucun code proposé
return
# Moyenne de l'UE ? # Moyenne de l'UE ?
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre) res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
@ -863,6 +907,8 @@ class DecisionsProposeesUE(DecisionsProposees):
def compute_codes(self): def compute_codes(self):
"""Calcul des .codes attribuables et de l'explanation associée""" """Calcul des .codes attribuables et de l'explanation associée"""
if self.inscription_etat != scu.INSCRIT:
return
if self.moy_ue > (sco_codes.ParcoursBUT.BARRE_MOY - sco_codes.NOTES_TOLERANCE): if self.moy_ue > (sco_codes.ParcoursBUT.BARRE_MOY - sco_codes.NOTES_TOLERANCE):
self.codes.insert(0, sco_codes.ADM) self.codes.insert(0, sco_codes.ADM)
self.explanation = (f"Moyenne >= {sco_codes.ParcoursBUT.BARRE_MOY}/20",) self.explanation = (f"Moyenne >= {sco_codes.ParcoursBUT.BARRE_MOY}/20",)

View File

@ -409,7 +409,9 @@ def get_table_jury_but(
)}" class="stdlink"> )}" class="stdlink">
{"voir" if read_only else ("modif." if deca.code_valide else "saisie")} {"voir" if read_only else ("modif." if deca.code_valide else "saisie")}
décision</a> décision</a>
""", """
if deca.inscription_etat == scu.INSCRIT
else deca.inscription_etat,
"col_lien_saisie_but", "col_lien_saisie_but",
) )
rows.append(row) rows.append(row)

View File

@ -16,6 +16,7 @@ from app.models.ues import UniteEns
from app.models.formations import Formation from app.models.formations import Formation
from app.models.formsemestre import FormSemestre from app.models.formsemestre import FormSemestre
from app.scodoc import sco_codes_parcours as sco_codes from app.scodoc import sco_codes_parcours as sco_codes
from app.scodoc import sco_utils as scu
class ApcValidationRCUE(db.Model): class ApcValidationRCUE(db.Model):
@ -84,6 +85,7 @@ class RegroupementCoherentUE:
ue_1: UniteEns, ue_1: UniteEns,
formsemestre_2: FormSemestre, formsemestre_2: FormSemestre,
ue_2: UniteEns, ue_2: UniteEns,
inscription_etat: str,
): ):
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_but import ResultatsSemestreBUT from app.comp.res_but import ResultatsSemestreBUT
@ -109,6 +111,11 @@ class RegroupementCoherentUE:
"semestre pair" "semestre pair"
self.ue_2 = ue_2 self.ue_2 = ue_2
# Stocke les moyennes d'UE # Stocke les moyennes d'UE
if inscription_etat != scu.INSCRIT:
self.moy_rcue = None
self.moy_ue_1 = self.moy_ue_2 = "-"
self.moy_ue_1_val = self.moy_ue_2_val = 0.0
return
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre_1) res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre_1)
if ue_1.id in res.etud_moy_ue and etud.id in res.etud_moy_ue[ue_1.id]: if ue_1.id in res.etud_moy_ue and etud.id in res.etud_moy_ue[ue_1.id]:
self.moy_ue_1 = res.etud_moy_ue[ue_1.id][etud.id] self.moy_ue_1 = res.etud_moy_ue[ue_1.id][etud.id]
@ -201,8 +208,9 @@ class RegroupementCoherentUE:
return None return None
# unused
def find_rcues( def find_rcues(
formsemestre: FormSemestre, ue: UniteEns, etud: Identite formsemestre: FormSemestre, ue: UniteEns, etud: Identite, inscription_etat: str
) -> list[RegroupementCoherentUE]: ) -> list[RegroupementCoherentUE]:
"""Les RCUE (niveau de compétence) à considérer pour cet étudiant dans """Les RCUE (niveau de compétence) à considérer pour cet étudiant dans
ce semestre pour cette UE. ce semestre pour cette UE.
@ -250,7 +258,9 @@ def find_rcues(
other_ue = UniteEns.query.get(ue_id) other_ue = UniteEns.query.get(ue_id)
other_formsemestre = FormSemestre.query.get(formsemestre_id) other_formsemestre = FormSemestre.query.get(formsemestre_id)
rcues.append( rcues.append(
RegroupementCoherentUE(etud, formsemestre, ue, other_formsemestre, other_ue) RegroupementCoherentUE(
etud, formsemestre, ue, other_formsemestre, other_ue, inscription_etat
)
) )
# safety check: 1 seul niveau de comp. concerné: # safety check: 1 seul niveau de comp. concerné:
assert len({rcue.ue_1.niveau_competence_id for rcue in rcues}) == 1 assert len({rcue.ue_1.niveau_competence_id for rcue in rcues}) == 1

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.3.13" SCOVERSION = "9.3.14"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"