Saisie automatique des décisions de jury BUT pour semestres pairs ou impairs.
This commit is contained in:
parent
4430eb9a61
commit
a4072efe4c
@ -693,20 +693,20 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
def record(self, code: str, no_overwrite=False):
|
def record(self, code: str, no_overwrite=False) -> bool:
|
||||||
"""Enregistre le code de l'année, et au besoin l'autorisation d'inscription.
|
"""Enregistre le code de l'année, et au besoin l'autorisation d'inscription.
|
||||||
Si no_overwrite, ne fait rien si un code est déjà enregistré.
|
Si no_overwrite, ne fait rien si un code est déjà enregistré.
|
||||||
Si l'étudiant est DEM ou DEF, ne fait rien.
|
Si l'étudiant est DEM ou DEF, ne fait rien.
|
||||||
"""
|
"""
|
||||||
if self.inscription_etat != scu.INSCRIT:
|
if self.inscription_etat != scu.INSCRIT:
|
||||||
return
|
return False
|
||||||
if code and not code in self.codes:
|
if code and not code in self.codes:
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
f"code annee <tt>{html.escape(code)}</tt> invalide pour formsemestre {html.escape(self.formsemestre)}"
|
f"code annee <tt>{html.escape(code)}</tt> invalide pour formsemestre {html.escape(self.formsemestre)}"
|
||||||
)
|
)
|
||||||
if code == self.code_valide or (self.code_valide is not None and no_overwrite):
|
if code == self.code_valide or (self.code_valide is not None and no_overwrite):
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
return # no change
|
return False # no change
|
||||||
if self.validation:
|
if self.validation:
|
||||||
db.session.delete(self.validation)
|
db.session.delete(self.validation)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
@ -746,9 +746,10 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
next_semestre_id,
|
next_semestre_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.recorded = True
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
self.recorded = True
|
||||||
self.invalidate_formsemestre_cache()
|
self.invalidate_formsemestre_cache()
|
||||||
|
return True
|
||||||
|
|
||||||
def invalidate_formsemestre_cache(self):
|
def invalidate_formsemestre_cache(self):
|
||||||
"invalide le résultats des deux formsemestres"
|
"invalide le résultats des deux formsemestres"
|
||||||
@ -759,13 +760,20 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
if self.formsemestre_pair is not None:
|
if self.formsemestre_pair is not None:
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre_pair.id)
|
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre_pair.id)
|
||||||
|
|
||||||
def record_all(self, no_overwrite: bool = True):
|
def record_all(
|
||||||
|
self, no_overwrite: bool = True, only_validantes: bool = False
|
||||||
|
) -> bool:
|
||||||
"""Enregistre les codes qui n'ont pas été spécifiés par le formulaire,
|
"""Enregistre les codes qui n'ont pas été spécifiés par le formulaire,
|
||||||
et sont donc en mode "automatique".
|
et sont donc en mode "automatique".
|
||||||
- Si "à cheval", ne modifie pas les codes UE de l'année scolaire précédente.
|
- Si "à cheval", ne modifie pas les codes UE de l'année scolaire précédente.
|
||||||
- Pour les RCUE: n'enregistre que si la nouvelle décision est plus favorable que l'ancienne.
|
- Pour les RCUE: n'enregistre que si la nouvelle décision est plus favorable que l'ancienne.
|
||||||
|
|
||||||
|
Si only_validantes, n'enregistre que des décisions "validantes" de droit: ADM ou CMP.
|
||||||
|
|
||||||
|
Return: True si au moins un code modifié et enregistré.
|
||||||
"""
|
"""
|
||||||
# Toujours valider dans l'ordre UE, RCUE, Année:
|
modif = False
|
||||||
|
# Toujours valider dans l'ordre UE, RCUE, Année
|
||||||
annee_scolaire = self.formsemestre.annee_scolaire()
|
annee_scolaire = self.formsemestre.annee_scolaire()
|
||||||
# UEs
|
# UEs
|
||||||
for dec_ue in self.decisions_ues.values():
|
for dec_ue in self.decisions_ues.values():
|
||||||
@ -774,25 +782,40 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
) and dec_ue.formsemestre.annee_scolaire() == annee_scolaire:
|
) and dec_ue.formsemestre.annee_scolaire() == annee_scolaire:
|
||||||
# rappel: le code par défaut est en tête
|
# rappel: le code par défaut est en tête
|
||||||
code = dec_ue.codes[0] if dec_ue.codes else None
|
code = dec_ue.codes[0] if dec_ue.codes else None
|
||||||
# enregistre le code jury seulement s'il n'y a pas déjà de code
|
if (not only_validantes) or code in sco_codes.CODES_UE_VALIDES_DE_DROIT:
|
||||||
# (no_overwrite=True) sauf en mode test yaml
|
# enregistre le code jury seulement s'il n'y a pas déjà de code
|
||||||
dec_ue.record(code, no_overwrite=no_overwrite)
|
# (no_overwrite=True) sauf en mode test yaml
|
||||||
# RCUE : enregistre seulement si pas déjà validé "mieux"
|
modif |= dec_ue.record(code, no_overwrite=no_overwrite)
|
||||||
|
# RCUE :
|
||||||
for dec_rcue in self.decisions_rcue_by_niveau.values():
|
for dec_rcue in self.decisions_rcue_by_niveau.values():
|
||||||
code = dec_rcue.codes[0] if dec_rcue.codes else None
|
code = dec_rcue.codes[0] if dec_rcue.codes else None
|
||||||
if (not dec_rcue.recorded) and (
|
if (
|
||||||
(not dec_rcue.validation)
|
(not dec_rcue.recorded)
|
||||||
or BUT_CODES_ORDERED.get(dec_rcue.validation.code, 0)
|
and ( # enregistre seulement si pas déjà validé "mieux"
|
||||||
< BUT_CODES_ORDERED.get(code, 0)
|
(not dec_rcue.validation)
|
||||||
|
or BUT_CODES_ORDERED.get(dec_rcue.validation.code, 0)
|
||||||
|
< BUT_CODES_ORDERED.get(code, 0)
|
||||||
|
)
|
||||||
|
and ( # décision validante de droit ?
|
||||||
|
(
|
||||||
|
(not only_validantes)
|
||||||
|
or code in sco_codes.CODES_RCUE_VALIDES_DE_DROIT
|
||||||
|
)
|
||||||
|
)
|
||||||
):
|
):
|
||||||
dec_rcue.record(code, no_overwrite=no_overwrite)
|
modif |= dec_rcue.record(code, no_overwrite=no_overwrite)
|
||||||
# Année:
|
# Année:
|
||||||
if not self.recorded:
|
if not self.recorded:
|
||||||
# rappel: le code par défaut est en tête
|
# rappel: le code par défaut est en tête
|
||||||
code = self.codes[0] if self.codes else None
|
code = self.codes[0] if self.codes else None
|
||||||
# enregistre le code jury seulement s'il n'y a pas déjà de code
|
# enregistre le code jury seulement s'il n'y a pas déjà de code
|
||||||
# (no_overwrite=True) sauf en mode test yaml
|
# (no_overwrite=True) sauf en mode test yaml
|
||||||
self.record(code, no_overwrite=no_overwrite)
|
if (
|
||||||
|
not only_validantes
|
||||||
|
) or code in sco_codes.CODES_ANNEE_BUT_VALIDES_DE_DROIT:
|
||||||
|
modif |= self.record(code, no_overwrite=no_overwrite)
|
||||||
|
|
||||||
|
return modif
|
||||||
|
|
||||||
def erase(self, only_one_sem=False):
|
def erase(self, only_one_sem=False):
|
||||||
"""Efface les décisions de jury de cet étudiant
|
"""Efface les décisions de jury de cet étudiant
|
||||||
@ -1005,23 +1028,23 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
return f"""<{self.__class__.__name__} rcue={self.rcue} valid={self.code_valide
|
return f"""<{self.__class__.__name__} rcue={self.rcue} valid={self.code_valide
|
||||||
} codes={self.codes} explanation={self.explanation}"""
|
} codes={self.codes} explanation={self.explanation}"""
|
||||||
|
|
||||||
def record(self, code: str, no_overwrite=False):
|
def record(self, code: str, no_overwrite=False) -> bool:
|
||||||
"""Enregistre le code RCUE.
|
"""Enregistre le code RCUE.
|
||||||
Note:
|
Note:
|
||||||
- si le RCUE est ADJ, les UE non validées sont passées à ADJ
|
- si le RCUE est ADJ, les UE non validées sont passées à ADJ
|
||||||
XXX on pourra imposer ici d'autres règles de cohérence
|
XXX on pourra imposer ici d'autres règles de cohérence
|
||||||
"""
|
"""
|
||||||
if self.rcue is None:
|
if self.rcue is None:
|
||||||
return # pas de RCUE a enregistrer
|
return False # pas de RCUE a enregistrer
|
||||||
if self.inscription_etat != scu.INSCRIT:
|
if self.inscription_etat != scu.INSCRIT:
|
||||||
return
|
return False
|
||||||
if code and not code in self.codes:
|
if code and not code in self.codes:
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
f"code UE invalide pour ue_id={self.ue.id}: {html.escape(code)}"
|
f"code UE invalide pour ue_id={self.ue.id}: {html.escape(code)}"
|
||||||
)
|
)
|
||||||
if code == self.code_valide or (self.code_valide is not None and no_overwrite):
|
if code == self.code_valide or (self.code_valide is not None and no_overwrite):
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
return # no change
|
return False # no change
|
||||||
parcours_id = self.parcour.id if self.parcour is not None else None
|
parcours_id = self.parcour.id if self.parcour is not None else None
|
||||||
if self.validation:
|
if self.validation:
|
||||||
db.session.delete(self.validation)
|
db.session.delete(self.validation)
|
||||||
@ -1072,6 +1095,7 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
)
|
)
|
||||||
self.code_valide = code # mise à jour état
|
self.code_valide = code # mise à jour état
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
|
return True
|
||||||
|
|
||||||
def erase(self):
|
def erase(self):
|
||||||
"""Efface la décision de jury de cet étudiant pour cet RCUE"""
|
"""Efface la décision de jury de cet étudiant pour cet RCUE"""
|
||||||
@ -1203,9 +1227,10 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
self.codes = [sco_codes.AJ, sco_codes.ADJ] + self.codes
|
self.codes = [sco_codes.AJ, sco_codes.ADJ] + self.codes
|
||||||
self.explanation = "notes insuffisantes"
|
self.explanation = "notes insuffisantes"
|
||||||
|
|
||||||
def record(self, code: str, no_overwrite=False):
|
def record(self, code: str, no_overwrite=False) -> bool:
|
||||||
"""Enregistre le code jury pour cette UE.
|
"""Enregistre le code jury pour cette UE.
|
||||||
Si no_overwrite, n'enregistre pas s'il y a déjà un code.
|
Si no_overwrite, n'enregistre pas s'il y a déjà un code.
|
||||||
|
Return: True si code enregistré (modifié)
|
||||||
"""
|
"""
|
||||||
if code and not code in self.codes:
|
if code and not code in self.codes:
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
@ -1213,7 +1238,7 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
)
|
)
|
||||||
if code == self.code_valide or (self.code_valide is not None and no_overwrite):
|
if code == self.code_valide or (self.code_valide is not None and no_overwrite):
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
return # no change
|
return False # no change
|
||||||
self.erase()
|
self.erase()
|
||||||
if code is None:
|
if code is None:
|
||||||
self.validation = None
|
self.validation = None
|
||||||
@ -1244,6 +1269,7 @@ class DecisionsProposeesUE(DecisionsProposees):
|
|||||||
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre.id)
|
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre.id)
|
||||||
self.code_valide = code # mise à jour
|
self.code_valide = code # mise à jour
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
|
return True
|
||||||
|
|
||||||
def erase(self):
|
def erase(self):
|
||||||
"""Efface la décision de jury de cet étudiant pour cette UE"""
|
"""Efface la décision de jury de cet étudiant pour cette UE"""
|
||||||
|
@ -18,29 +18,29 @@ from app.scodoc.sco_exceptions import ScoValueError
|
|||||||
def formsemestre_validation_auto_but(
|
def formsemestre_validation_auto_but(
|
||||||
formsemestre: FormSemestre, only_adm: bool = True, no_overwrite: bool = True
|
formsemestre: FormSemestre, only_adm: bool = True, no_overwrite: bool = True
|
||||||
) -> int:
|
) -> int:
|
||||||
"""Calcul automatique des décisions de jury sur une année BUT.
|
"""Calcul automatique des décisions de jury sur une "année" BUT.
|
||||||
Ne modifie jamais de décisions de l'année scolaire précédente, même
|
|
||||||
|
- N'enregistre jamais de décisions de l'année scolaire précédente, même
|
||||||
si on a des RCUE "à cheval".
|
si on a des RCUE "à cheval".
|
||||||
Normalement, only_adm est True et on n'enregistre que les décisions ADM (de droit).
|
- Ne modifie jamais de décisions déjà enregistrées (sauf si no_overwrite est faux,
|
||||||
Si only_adm est faux, on enregistre la première décision proposée par ScoDoc
|
ce qui est utilisé pour certains tests unitaires).
|
||||||
(mode à n'utiliser que pour les tests)
|
- Normalement, only_adm est True et on n'enregistre que les décisions validantes
|
||||||
|
de droit: ADM ou CMP.
|
||||||
|
En revanche, si only_adm est faux, on enregistre la première décision proposée par ScoDoc
|
||||||
|
(mode à n'utiliser que pour les tests unitaires vérifiant la saisie des jurys)
|
||||||
|
|
||||||
Si no_overwrite est vrai (défaut), ne ré-écrit jamais les codes déjà enregistrés
|
Returns: nombre d'étudiants pour lesquels on a enregistré au moins un code.
|
||||||
(utiliser faux pour certains tests)
|
|
||||||
|
|
||||||
Returns: nombre d'étudiants "admis"
|
|
||||||
"""
|
"""
|
||||||
if not formsemestre.formation.is_apc():
|
if not formsemestre.formation.is_apc():
|
||||||
raise ScoValueError("fonction réservée aux formations BUT")
|
raise ScoValueError("fonction réservée aux formations BUT")
|
||||||
nb_admis = 0
|
nb_etud_modif = 0
|
||||||
with sco_cache.DeferredSemCacheManager():
|
with sco_cache.DeferredSemCacheManager():
|
||||||
for etudid in formsemestre.etuds_inscriptions:
|
for etudid in formsemestre.etuds_inscriptions:
|
||||||
etud: Identite = Identite.query.get(etudid)
|
etud: Identite = Identite.query.get(etudid)
|
||||||
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
||||||
if deca.admis: # année réussie
|
nb_etud_modif += deca.record_all(
|
||||||
nb_admis += 1
|
no_overwrite=no_overwrite, only_validantes=only_adm
|
||||||
if deca.admis or not only_adm:
|
)
|
||||||
deca.record_all(no_overwrite=no_overwrite)
|
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return nb_admis
|
return nb_etud_modif
|
||||||
|
@ -563,9 +563,8 @@ class JuryPE(object):
|
|||||||
dec = nt.get_etud_decision_sem(
|
dec = nt.get_etud_decision_sem(
|
||||||
etudid
|
etudid
|
||||||
) # quelle est la décision du jury ?
|
) # quelle est la décision du jury ?
|
||||||
if dec and dec["code"] in list(
|
if dec and (dec["code"] in sco_codes_parcours.CODES_SEM_VALIDES):
|
||||||
sco_codes_parcours.CODES_SEM_VALIDES.keys()
|
# isinstance( sesMoyennes[i+1], float) and
|
||||||
): # isinstance( sesMoyennes[i+1], float) and
|
|
||||||
# mT = sesMoyennes[i+1] # substitue la moyenne si le semestre suivant est "valide"
|
# mT = sesMoyennes[i+1] # substitue la moyenne si le semestre suivant est "valide"
|
||||||
leFid = sem["formsemestre_id"]
|
leFid = sem["formsemestre_id"]
|
||||||
else:
|
else:
|
||||||
|
@ -187,20 +187,23 @@ CODES_EXPL = {
|
|||||||
|
|
||||||
# Les codes de semestres:
|
# Les codes de semestres:
|
||||||
CODES_JURY_SEM = {ADC, ADJ, ADM, AJ, ATB, ATJ, ATT, DEF, NAR, RAT}
|
CODES_JURY_SEM = {ADC, ADJ, ADM, AJ, ATB, ATJ, ATT, DEF, NAR, RAT}
|
||||||
CODES_SEM_VALIDES = {ADM: True, ADC: True, ADJ: True} # semestre validé
|
CODES_SEM_VALIDES_DE_DROIT = {ADM, ADC}
|
||||||
CODES_SEM_ATTENTES = {ATT: True, ATB: True, ATJ: True} # semestre en attente
|
CODES_SEM_VALIDES = CODES_SEM_VALIDES_DE_DROIT | {ADJ} # semestre validé
|
||||||
|
CODES_SEM_ATTENTES = {ATT, ATB, ATJ} # semestre en attente
|
||||||
|
|
||||||
CODES_SEM_REO = {NAR: 1} # reorientation
|
CODES_SEM_REO = {NAR} # reorientation
|
||||||
|
|
||||||
CODES_UE_VALIDES = {ADM: True, CMP: True, ADJ: True, ADJR: True}
|
CODES_UE_VALIDES_DE_DROIT = {ADM, CMP} # validation "de droit"
|
||||||
|
CODES_UE_VALIDES = CODES_UE_VALIDES_DE_DROIT | {ADJ, ADJR}
|
||||||
"UE validée"
|
"UE validée"
|
||||||
|
|
||||||
CODES_RCUE_VALIDES = {ADM, CMP, ADJ}
|
CODES_RCUE_VALIDES_DE_DROIT = {ADM, CMP}
|
||||||
|
CODES_RCUE_VALIDES = CODES_RCUE_VALIDES_DE_DROIT | {ADJ}
|
||||||
"Niveau RCUE validé"
|
"Niveau RCUE validé"
|
||||||
|
|
||||||
# Pour le BUT:
|
# Pour le BUT:
|
||||||
|
CODES_ANNEE_BUT_VALIDES_DE_DROIT = {ADM, PASD}
|
||||||
CODES_ANNEE_ARRET = {DEF, DEM, ABAN, ABL}
|
CODES_ANNEE_ARRET = {DEF, DEM, ABAN, ABL}
|
||||||
CODES_RCUE = {ADM, AJ, CMP}
|
|
||||||
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
|
||||||
BUT_RCUE_SUFFISANT = 8.0 - NOTES_TOLERANCE
|
BUT_RCUE_SUFFISANT = 8.0 - NOTES_TOLERANCE
|
||||||
@ -230,17 +233,17 @@ BUT_CODES_ORDERED = {
|
|||||||
|
|
||||||
def code_semestre_validant(code: str) -> bool:
|
def code_semestre_validant(code: str) -> bool:
|
||||||
"Vrai si ce CODE entraine la validation du semestre"
|
"Vrai si ce CODE entraine la validation du semestre"
|
||||||
return CODES_SEM_VALIDES.get(code, False)
|
return code in CODES_SEM_VALIDES
|
||||||
|
|
||||||
|
|
||||||
def code_semestre_attente(code: str) -> bool:
|
def code_semestre_attente(code: str) -> bool:
|
||||||
"Vrai si ce CODE est un code d'attente (semestre validable plus tard par jury ou compensation)"
|
"Vrai si ce CODE est un code d'attente (semestre validable plus tard par jury ou compensation)"
|
||||||
return CODES_SEM_ATTENTES.get(code, False)
|
return code in CODES_SEM_ATTENTES
|
||||||
|
|
||||||
|
|
||||||
def code_ue_validant(code: str) -> bool:
|
def code_ue_validant(code: str) -> bool:
|
||||||
"Vrai si ce code d'UE est validant (ie attribue les ECTS)"
|
"Vrai si ce code d'UE est validant (ie attribue les ECTS)"
|
||||||
return CODES_UE_VALIDES.get(code, False)
|
return code in CODES_UE_VALIDES
|
||||||
|
|
||||||
|
|
||||||
DEVENIR_EXPL = {
|
DEVENIR_EXPL = {
|
||||||
|
@ -890,7 +890,7 @@ def formsemestre_validate_ues(formsemestre_id, etudid, code_etat_sem, assiduite)
|
|||||||
car ils ne dépendent que de la note d'UE et de la validation ou non du semestre.
|
car ils ne dépendent que de la note d'UE et de la validation ou non du semestre.
|
||||||
Les UE des semestres NON ASSIDUS ne sont jamais validées (code AJ).
|
Les UE des semestres NON ASSIDUS ne sont jamais validées (code AJ).
|
||||||
"""
|
"""
|
||||||
valid_semestre = CODES_SEM_VALIDES.get(code_etat_sem, False)
|
valid_semestre = code_etat_sem in CODES_SEM_VALIDES
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
|
@ -781,8 +781,8 @@ def form_decision_manuelle(Se, formsemestre_id, etudid, desturl="", sortcol=None
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Choix code semestre:
|
# Choix code semestre:
|
||||||
codes = list(sco_codes_parcours.CODES_JURY_SEM)
|
codes = sorted(sco_codes_parcours.CODES_JURY_SEM)
|
||||||
codes.sort() # fortuitement, cet ordre convient bien !
|
# fortuitement, cet ordre convient bien !
|
||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
'<tr><td>Code semestre: </td><td><select name="code_etat"><option value="" selected>Choisir...</option>'
|
'<tr><td>Code semestre: </td><td><select name="code_etat"><option value="" selected>Choisir...</option>'
|
||||||
|
@ -8,14 +8,22 @@
|
|||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
|
|
||||||
<h2>Calcul automatique des décisions de jury annuelle BUT</h2>
|
<h2>Calcul automatique des décisions de jury du BUT</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Seuls les étudiants qui valident l'année seront affectés:
|
<li>N'enregistre jamais de décisions de l'année scolaire précédente, même
|
||||||
tous les niveaux de compétences (RCUE) validables
|
si on a des RCUE "à cheval" sur deux années.
|
||||||
(moyenne annuelle au dessus de 10);
|
</li>
|
||||||
|
<li>Ne modifie jamais de décisions déjà enregistrées.
|
||||||
|
</li>
|
||||||
|
<li>N'enregistre que les décisions <b>validantes de droit: ADM ou CMP</b>.
|
||||||
|
</li>
|
||||||
|
<li>L'assiduité n'est <b>pas</b> prise en compte.
|
||||||
</li>
|
</li>
|
||||||
<li>l'assiduité n'est <b>pas</b> prise en compte;</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
<p>
|
||||||
|
En conséquence, saisir ensuite <b>manuellement les décisions manquantes</b>,
|
||||||
|
notamment sur les UEs en dessous de 10.
|
||||||
|
</p>
|
||||||
<p class="warning">
|
<p class="warning">
|
||||||
Il est nécessaire de relire soigneusement les décisions à l'issue de cette procédure !
|
Il est nécessaire de relire soigneusement les décisions à l'issue de cette procédure !
|
||||||
</p>
|
</p>
|
||||||
|
@ -2548,10 +2548,10 @@ def formsemestre_validation_auto_but(formsemestre_id: int = None):
|
|||||||
form = jury_but_forms.FormSemestreValidationAutoBUTForm()
|
form = jury_but_forms.FormSemestreValidationAutoBUTForm()
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if not form.cancel.data:
|
if not form.cancel.data:
|
||||||
nb_admis = jury_but_validation_auto.formsemestre_validation_auto_but(
|
nb_etud_modif = jury_but_validation_auto.formsemestre_validation_auto_but(
|
||||||
formsemestre
|
formsemestre
|
||||||
)
|
)
|
||||||
flash(f"Décisions enregistrées ({nb_admis} admis)")
|
flash(f"Décisions enregistrées ({nb_etud_modif} étudiants modifiés)")
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for(
|
url_for(
|
||||||
"notes.formsemestre_saisie_jury",
|
"notes.formsemestre_saisie_jury",
|
||||||
@ -2563,7 +2563,7 @@ def formsemestre_validation_auto_but(formsemestre_id: int = None):
|
|||||||
"but/formsemestre_validation_auto_but.html",
|
"but/formsemestre_validation_auto_but.html",
|
||||||
form=form,
|
form=form,
|
||||||
sco=ScoData(formsemestre=formsemestre),
|
sco=ScoData(formsemestre=formsemestre),
|
||||||
title=f"Calcul automatique jury BUT",
|
title="Calcul automatique jury BUT",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -2641,7 +2641,17 @@ def formsemestre_validation_auto(formsemestre_id):
|
|||||||
message="<p>Opération non autorisée pour %s</h2>" % current_user,
|
message="<p>Opération non autorisée pour %s</h2>" % current_user,
|
||||||
dest_url=scu.ScoURL(),
|
dest_url=scu.ScoURL(),
|
||||||
)
|
)
|
||||||
|
formsemestre: FormSemestre = FormSemestre.query.filter_by(
|
||||||
|
id=formsemestre_id, dept_id=g.scodoc_dept_id
|
||||||
|
).first_or_404()
|
||||||
|
if formsemestre.formation.is_apc():
|
||||||
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"notes.formsemestre_validation_auto_but",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
return sco_formsemestre_validation.formsemestre_validation_auto(formsemestre_id)
|
return sco_formsemestre_validation.formsemestre_validation_auto(formsemestre_id)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user