forked from ScoDoc/ScoDoc
Jury BUT:
- Modification gestion de l'enregistrement des codes. - Signale quand un RCUE change de code. - Calcul auto du jury: peut modifier les décisions RCUE.
This commit is contained in:
parent
b696f772bf
commit
449c1f0cb0
@ -278,11 +278,15 @@ 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,
|
|
||||||
ordre=self.annee_but,
|
ordre=self.annee_but,
|
||||||
).first()
|
)
|
||||||
|
.join(Formation)
|
||||||
|
.filter_by(formation_code=self.formsemestre.formation.formation_code)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.validation = None
|
self.validation = None
|
||||||
if self.validation is not None:
|
if self.validation is not None:
|
||||||
@ -721,7 +725,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
et qu'il n'y en a pas déjà, enregistre ceux par défaut.
|
et qu'il n'y en a pas déjà, enregistre ceux par défaut.
|
||||||
"""
|
"""
|
||||||
log("jury_but.DecisionsProposeesAnnee.record_form")
|
log("jury_but.DecisionsProposeesAnnee.record_form")
|
||||||
code_annee = None
|
code_annee = self.codes[0] # si pas dans le form, valeur par defaut
|
||||||
codes_rcues = [] # [ (dec_rcue, code), ... ]
|
codes_rcues = [] # [ (dec_rcue, code), ... ]
|
||||||
codes_ues = [] # [ (dec_ue, code), ... ]
|
codes_ues = [] # [ (dec_ue, code), ... ]
|
||||||
for key in form:
|
for key in form:
|
||||||
@ -753,16 +757,15 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
dec_ue.record(code)
|
dec_ue.record(code)
|
||||||
for dec_rcue, code in codes_rcues:
|
for dec_rcue, code in codes_rcues:
|
||||||
dec_rcue.record(code)
|
dec_rcue.record(code)
|
||||||
self.record(code_annee) # XXX , mark_recorded=False)
|
self.record(code_annee)
|
||||||
self.record_autorisation_inscription(code_annee)
|
self.record_autorisation_inscription(code_annee)
|
||||||
self.record_all()
|
self.record_all()
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
def record(self, code: str, no_overwrite=False, mark_recorded: bool = True) -> bool:
|
def record(self, code: str, mark_recorded: bool = True) -> 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 l'étudiant est DEM ou DEF, ne fait rien.
|
Si l'étudiant est DEM ou DEF, ne fait rien.
|
||||||
Si mark_recorded est vrai, positionne self.recorded
|
Si mark_recorded est vrai, positionne self.recorded
|
||||||
"""
|
"""
|
||||||
@ -773,14 +776,15 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
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 and (self.code_valide is None or not no_overwrite):
|
if code != self.code_valide:
|
||||||
# Enregistrement du code annuel BUT
|
# Enregistrement du code annuel BUT
|
||||||
|
if code is None:
|
||||||
if self.validation:
|
if self.validation:
|
||||||
db.session.delete(self.validation)
|
db.session.delete(self.validation)
|
||||||
db.session.commit()
|
|
||||||
if code is None:
|
|
||||||
self.validation = None
|
self.validation = None
|
||||||
|
db.session.commit()
|
||||||
else:
|
else:
|
||||||
|
if self.validation is None:
|
||||||
self.validation = ApcValidationAnnee(
|
self.validation = ApcValidationAnnee(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
formsemestre=self.formsemestre_impair,
|
formsemestre=self.formsemestre_impair,
|
||||||
@ -789,7 +793,17 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
annee_scolaire=self.annee_scolaire(),
|
annee_scolaire=self.annee_scolaire(),
|
||||||
code=code,
|
code=code,
|
||||||
)
|
)
|
||||||
|
else: # Update validation année BUT
|
||||||
|
self.validation.etud = self.etud
|
||||||
|
self.validation.formsemestre = self.formsemestre_impair
|
||||||
|
self.validation.formation_id = self.formsemestre.formation_id
|
||||||
|
self.validation.ordre = self.annee_but
|
||||||
|
self.validation.annee_scolaire = self.annee_scolaire()
|
||||||
|
self.validation.code = code
|
||||||
|
self.validation.date = datetime.now()
|
||||||
|
|
||||||
db.session.add(self.validation)
|
db.session.add(self.validation)
|
||||||
|
db.session.commit()
|
||||||
log(f"Recording {self}: {code}")
|
log(f"Recording {self}: {code}")
|
||||||
Scolog.logdb(
|
Scolog.logdb(
|
||||||
method="jury_but",
|
method="jury_but",
|
||||||
@ -840,9 +854,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
)
|
)
|
||||||
return res and self.etud.id in res.get_etudids_attente()
|
return res and self.etud.id in res.get_etudids_attente()
|
||||||
|
|
||||||
def record_all(
|
def record_all(self, only_validantes: bool = False) -> bool:
|
||||||
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.
|
||||||
@ -868,9 +880,8 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
# 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
|
||||||
if (not only_validantes) or code in sco_codes.CODES_UE_VALIDES_DE_DROIT:
|
if (not only_validantes) or code in sco_codes.CODES_UE_VALIDES_DE_DROIT:
|
||||||
# enregistre le code jury seulement s'il n'y a pas déjà de code
|
# enregistre le code jury
|
||||||
# (no_overwrite=True) sauf en mode test yaml
|
modif |= dec_ue.record(code)
|
||||||
modif |= dec_ue.record(code, no_overwrite=no_overwrite)
|
|
||||||
# RCUE :
|
# 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
|
||||||
@ -888,17 +899,15 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
modif |= dec_rcue.record(code, no_overwrite=no_overwrite)
|
modif |= dec_rcue.record(code)
|
||||||
# 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
|
|
||||||
# (no_overwrite=True) sauf en mode test yaml
|
|
||||||
if (
|
if (
|
||||||
not only_validantes
|
not only_validantes
|
||||||
) or code in sco_codes.CODES_ANNEE_BUT_VALIDES_DE_DROIT:
|
) or code in sco_codes.CODES_ANNEE_BUT_VALIDES_DE_DROIT:
|
||||||
modif |= self.record(code, no_overwrite=no_overwrite)
|
modif |= self.record(code)
|
||||||
self.record_autorisation_inscription(code)
|
self.record_autorisation_inscription(code)
|
||||||
return modif
|
return modif
|
||||||
|
|
||||||
@ -1133,7 +1142,7 @@ 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) -> bool:
|
def record(self, code: str) -> 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
|
||||||
@ -1147,7 +1156,7 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
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:
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
return False # 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
|
||||||
@ -1322,11 +1331,15 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
if annee_inferieure < 1:
|
if annee_inferieure < 1:
|
||||||
return
|
return
|
||||||
# Garde-fou: Année déjà validée ?
|
# Garde-fou: Année déjà validée ?
|
||||||
validations_annee: ApcValidationAnnee = ApcValidationAnnee.query.filter_by(
|
validations_annee: ApcValidationAnnee = (
|
||||||
|
ApcValidationAnnee.query.filter_by(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
ordre=annee_inferieure,
|
ordre=annee_inferieure,
|
||||||
formation_id=self.rcue.formsemestre_1.formation_id,
|
)
|
||||||
).all()
|
.join(Formation)
|
||||||
|
.filter_by(formation_code=self.rcue.formsemestre_1.formation.code)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
if len(validations_annee) > 1:
|
if len(validations_annee) > 1:
|
||||||
log(
|
log(
|
||||||
f"warning: {len(validations_annee)} validations d'année\n{validations_annee}"
|
f"warning: {len(validations_annee)} validations d'année\n{validations_annee}"
|
||||||
@ -1519,16 +1532,15 @@ 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) -> bool:
|
def record(self, code: str) -> 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.
|
|
||||||
Return: True si code enregistré (modifié)
|
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(
|
||||||
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:
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
return False # no change
|
return False # no change
|
||||||
self.erase()
|
self.erase()
|
||||||
@ -1627,7 +1639,6 @@ class BUTCursusEtud: # WIP TODO
|
|||||||
ApcValidationAnnee.query.filter_by(
|
ApcValidationAnnee.query.filter_by(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
ordre=ordre,
|
ordre=ordre,
|
||||||
formation_id=self.formsemestre.formation_id,
|
|
||||||
)
|
)
|
||||||
.join(Formation)
|
.join(Formation)
|
||||||
.filter(
|
.filter(
|
||||||
|
@ -16,14 +16,12 @@ 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
|
||||||
) -> 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.
|
||||||
|
|
||||||
- N'enregistre 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".
|
||||||
- Ne modifie jamais de décisions déjà enregistrées (sauf si no_overwrite est faux,
|
|
||||||
ce qui est utilisé pour certains tests unitaires).
|
|
||||||
- Normalement, only_adm est True et on n'enregistre que les décisions validantes
|
- Normalement, only_adm est True et on n'enregistre que les décisions validantes
|
||||||
de droit: ADM ou CMP.
|
de droit: ADM ou CMP.
|
||||||
En revanche, si only_adm est faux, on enregistre la première décision proposée par ScoDoc
|
En revanche, si only_adm est faux, on enregistre la première décision proposée par ScoDoc
|
||||||
@ -38,9 +36,7 @@ def formsemestre_validation_auto_but(
|
|||||||
for etudid in formsemestre.etuds_inscriptions:
|
for etudid in formsemestre.etuds_inscriptions:
|
||||||
etud = Identite.get_etud(etudid)
|
etud = Identite.get_etud(etudid)
|
||||||
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
||||||
nb_etud_modif += deca.record_all(
|
nb_etud_modif += deca.record_all(only_validantes=only_adm)
|
||||||
no_overwrite=no_overwrite, only_validantes=only_adm
|
|
||||||
)
|
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return nb_etud_modif
|
return nb_etud_modif
|
||||||
|
@ -155,6 +155,7 @@ def _gen_but_select(
|
|||||||
disabled: bool = False,
|
disabled: bool = False,
|
||||||
klass: str = "",
|
klass: str = "",
|
||||||
data: dict = {},
|
data: dict = {},
|
||||||
|
code_valide_label: str = "",
|
||||||
) -> str:
|
) -> str:
|
||||||
"Le menu html select avec les codes"
|
"Le menu html select avec les codes"
|
||||||
# if disabled: # mauvaise idée car le disabled est traité en JS
|
# if disabled: # mauvaise idée car le disabled est traité en JS
|
||||||
@ -164,7 +165,10 @@ def _gen_but_select(
|
|||||||
f"""<option value="{code}"
|
f"""<option value="{code}"
|
||||||
{'selected' if code == code_valide else ''}
|
{'selected' if code == code_valide else ''}
|
||||||
class="{'recorded' if code == code_valide else ''}"
|
class="{'recorded' if code == code_valide else ''}"
|
||||||
>{code}</option>"""
|
>{code
|
||||||
|
if ((code != code_valide) or not code_valide_label)
|
||||||
|
else code_valide_label
|
||||||
|
}</option>"""
|
||||||
for code in codes
|
for code in codes
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -246,6 +250,7 @@ def _gen_but_rcue(dec_rcue: DecisionsProposeesRCUE, niveau: ApcNiveau) -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
code_propose_menu = dec_rcue.code_valide # le code enregistré
|
code_propose_menu = dec_rcue.code_valide # le code enregistré
|
||||||
|
code_valide_label = code_propose_menu
|
||||||
if dec_rcue.validation:
|
if dec_rcue.validation:
|
||||||
if dec_rcue.code_valide == dec_rcue.codes[0]:
|
if dec_rcue.code_valide == dec_rcue.codes[0]:
|
||||||
descr_validation = dec_rcue.validation.html()
|
descr_validation = dec_rcue.validation.html()
|
||||||
@ -257,6 +262,9 @@ def _gen_but_rcue(dec_rcue: DecisionsProposeesRCUE, niveau: ApcNiveau) -> str:
|
|||||||
> sco_codes.BUT_CODES_ORDER[dec_rcue.code_valide]
|
> sco_codes.BUT_CODES_ORDER[dec_rcue.code_valide]
|
||||||
):
|
):
|
||||||
code_propose_menu = dec_rcue.codes[0]
|
code_propose_menu = dec_rcue.codes[0]
|
||||||
|
code_valide_label = (
|
||||||
|
f"{dec_rcue.codes[0]} (actuel {dec_rcue.code_valide})"
|
||||||
|
)
|
||||||
scoplement = f"""<div class="scoplement">{descr_validation}</div>"""
|
scoplement = f"""<div class="scoplement">{descr_validation}</div>"""
|
||||||
else:
|
else:
|
||||||
scoplement = "" # "pas de validation"
|
scoplement = "" # "pas de validation"
|
||||||
@ -282,7 +290,8 @@ def _gen_but_rcue(dec_rcue: DecisionsProposeesRCUE, niveau: ApcNiveau) -> str:
|
|||||||
code_propose_menu,
|
code_propose_menu,
|
||||||
disabled=True,
|
disabled=True,
|
||||||
klass="manual code_rcue",
|
klass="manual code_rcue",
|
||||||
data = { "niveau_id" : str(niveau.id)}
|
data = { "niveau_id" : str(niveau.id)},
|
||||||
|
code_valide_label = code_valide_label,
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -223,8 +223,15 @@ BUT_CODES_PASSAGE = {
|
|||||||
# les codes, du plus "défavorable" à l'étudiant au plus favorable:
|
# les codes, du plus "défavorable" à l'étudiant au plus favorable:
|
||||||
# (valeur par défaut 0)
|
# (valeur par défaut 0)
|
||||||
BUT_CODES_ORDER = {
|
BUT_CODES_ORDER = {
|
||||||
NAR: 0,
|
ABAN: 0,
|
||||||
|
ABL: 0,
|
||||||
|
DEM: 0,
|
||||||
DEF: 0,
|
DEF: 0,
|
||||||
|
EXCLU: 0,
|
||||||
|
NAR: 0,
|
||||||
|
UEBSL: 0,
|
||||||
|
RAT: 5,
|
||||||
|
RED: 6,
|
||||||
AJ: 10,
|
AJ: 10,
|
||||||
ATJ: 20,
|
ATJ: 20,
|
||||||
CMP: 50,
|
CMP: 50,
|
||||||
@ -233,7 +240,7 @@ BUT_CODES_ORDER = {
|
|||||||
PASD: 60,
|
PASD: 60,
|
||||||
ADJR: 90,
|
ADJR: 90,
|
||||||
ADSUP: 90,
|
ADSUP: 90,
|
||||||
ADJ: 100,
|
ADJ: 90,
|
||||||
ADM: 100,
|
ADM: 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +495,9 @@ class ApoEtud(dict):
|
|||||||
ApcValidationAnnee.query.filter_by(
|
ApcValidationAnnee.query.filter_by(
|
||||||
formsemestre_id=formsemestre.id,
|
formsemestre_id=formsemestre.id,
|
||||||
etudid=self.etud["etudid"],
|
etudid=self.etud["etudid"],
|
||||||
formation_id=self.cur_sem["formation_id"],
|
formation_id=self.cur_sem[
|
||||||
|
"formation_id"
|
||||||
|
], # XXX utiliser formation_code
|
||||||
).first()
|
).first()
|
||||||
)
|
)
|
||||||
self.is_nar = (
|
self.is_nar = (
|
||||||
|
@ -168,6 +168,7 @@ div.but_niveau_ue.recorded_different,
|
|||||||
div.but_niveau_rcue.recorded_different {
|
div.but_niveau_rcue.recorded_different {
|
||||||
box-shadow: 0 0 0 3px red;
|
box-shadow: 0 0 0 3px red;
|
||||||
outline: dashed 3px var(--color-recorded);
|
outline: dashed 3px var(--color-recorded);
|
||||||
|
background-color: yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.but_niveau_ue.annee_prec {
|
div.but_niveau_ue.annee_prec {
|
||||||
|
@ -1128,7 +1128,8 @@ div.sco_help {
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
background-color: rgb(200, 200, 220);
|
max-width: 800px;
|
||||||
|
background-color: rgb(209, 255, 214);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.vertical_spacing_but {
|
div.vertical_spacing_but {
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
(transcription paramétrable par votre administrateur ScoDoc).
|
(transcription paramétrable par votre administrateur ScoDoc).
|
||||||
</p>
|
</p>
|
||||||
<div class="but_doc_section">Codes d'année</div>
|
<div class="but_doc_section">Codes d'année</div>
|
||||||
|
<em>Les codes d'année BUT sont associés à la formation et non au semestre: on ne valide
|
||||||
|
qu'une seule fois BUT1, BUT2 puis BUT3.</em>
|
||||||
<div class="but_doc">
|
<div class="but_doc">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@ -100,7 +102,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="but_doc_section">Codes RCUE (niveaux de compétences annuels)</div>
|
<div class="but_doc_section">Codes RCUE (niveaux de compétences annuels)</div>
|
||||||
|
<em>Les codes de RCUE sont associés à la formation: chaque niveau de compétence
|
||||||
|
est validé une fois au maximum. En cas de redoublement, le code RCUE peut changer.</em>
|
||||||
<div class="but_doc">
|
<div class="but_doc">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@ -161,7 +164,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="but_doc_section">Codes des Unités d'Enseignement (UE)</div>
|
<div class="but_doc_section">Codes des Unités d'Enseignement (UE)</div>
|
||||||
|
<em>Les codes d'UE sont associés aux UE d'un semestre. En cas de redoublement,
|
||||||
|
l'UE antérieure garde son code, non écrasé par le redoublement. Chaque UE suivie a son code.
|
||||||
|
</em>
|
||||||
<div class="but_doc">
|
<div class="but_doc">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -8,19 +8,27 @@
|
|||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
|
|
||||||
|
<div class="sco_help">
|
||||||
<h2>Calcul automatique des décisions de jury du BUT</h2>
|
<h2>Calcul automatique des décisions de jury du BUT</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>N'enregistre jamais de décisions de l'année scolaire précédente, même
|
<li>N'enregistre jamais de décisions de l'année scolaire précédente, même
|
||||||
si on a des RCUE "à cheval" sur deux années.
|
si on a des RCUE "à cheval" sur deux années.
|
||||||
</li>
|
</li>
|
||||||
<li>Ne modifie jamais de décisions déjà enregistrées.
|
|
||||||
|
<li><b>Attention: peut modifier des décisions déjà enregistrées</b>, si la
|
||||||
|
validation de droit est calculée. Par exemple, vous aviez saisi <b>RAT</b>
|
||||||
|
pour un étudiant dont les moyennes d'UE dépassent 10 mais qui pour une
|
||||||
|
raison particulière ne valide pas son année. Le calcul automatique peut
|
||||||
|
remplacer ce <b>RAT</b> par un <b>ADM</b>, ScoDoc considérant que les
|
||||||
|
conditions sont satisfaites. On peut éviter cela en laissant une note de
|
||||||
|
l'étudiant en ATTente.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>N'enregistre que les décisions <b>validantes de droit: ADM ou CMP</b>.
|
<li>N'enregistre que les décisions <b>validantes de droit: ADM ou CMP</b>.
|
||||||
</li>
|
</li>
|
||||||
<li>N'enregistre pas de décision si l'étudiant a une ou plusieurs notes en ATTente.
|
<li>N'enregistre pas de décision si l'étudiant a une ou plusieurs notes en ATTente.
|
||||||
</li>
|
</li>
|
||||||
<li>L'assiduité n'est <b>pas</b> prise en compte.
|
<li>L'assiduité n'est <b>pas</b> prise en compte. </li>
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
En conséquence, saisir ensuite <b>manuellement les décisions manquantes</b>,
|
En conséquence, saisir ensuite <b>manuellement les décisions manquantes</b>,
|
||||||
@ -34,9 +42,10 @@
|
|||||||
<li>Il est nécessaire de relire soigneusement les décisions à l'issue de cette procédure !</li>
|
<li>Il est nécessaire de relire soigneusement les décisions à l'issue de cette procédure !</li>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-5">
|
<div class="col-md-10">
|
||||||
{{ wtf.quick_form(form) }}
|
{{ wtf.quick_form(form) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -108,9 +108,7 @@ def test_but_jury_GEII_lyon(test_client):
|
|||||||
# Saisie de toutes les décisions de jury "automatiques"
|
# Saisie de toutes les décisions de jury "automatiques"
|
||||||
# et vérification des résultats attendus:
|
# et vérification des résultats attendus:
|
||||||
for formsemestre in formsemestres:
|
for formsemestre in formsemestres:
|
||||||
formsemestre_validation_auto_but(
|
formsemestre_validation_auto_but(formsemestre, only_adm=False)
|
||||||
formsemestre, only_adm=False, no_overwrite=False
|
|
||||||
)
|
|
||||||
yaml_setup_but.but_test_jury(formsemestre, doc)
|
yaml_setup_but.but_test_jury(formsemestre, doc)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user