Jurys BUT: modif. autorisations passage. Cosmetic css.

This commit is contained in:
Emmanuel Viennet 2023-01-26 10:49:04 -03:00
parent fca090649c
commit 63ea4f31f2
9 changed files with 312 additions and 144 deletions

View File

@ -630,19 +630,38 @@ class DecisionsProposeesAnnee(DecisionsProposees):
d[dec_rcue.rcue.ue_2.id] = dec_rcue d[dec_rcue.rcue.ue_2.id] = dec_rcue
return d return d
def next_annee_semestre_id(self, code: str) -> int: def next_semestre_ids(self, code: str) -> set[int]:
"""L'indice du semestre dans lequel l'étudiant est autorisé à """Les indices des semestres dans lequels l'étudiant est autorisé
poursuivre l'année suivante. None si aucun.""" à poursuivre après le semestre courant.
if self.formsemestre_pair is None: """
return None # seulement sur année ids = set()
if code == RED: # La poursuite d'études dans un semestre pair dune même année
return self.formsemestre_pair.semestre_id - 1 # est de droit pour tout étudiant:
elif ( if (self.formsemestre.semestre_id % 2) and sco_codes.ParcoursBUT.NB_SEM:
code in sco_codes.BUT_CODES_PASSAGE ids.add(self.formsemestre.semestre_id + 1)
# La poursuite détudes dans un semestre impair est possible si
# et seulement si létudiant a obtenu :
# - la moyenne à plus de la moitié des regroupements cohérents dUE ;
# - et une moyenne égale ou supérieure à 8 sur 20 à chaque RCUE.
#
# La condition a paru trop stricte à de nombreux collègues.
# ScoDoc ne contraint donc pas à la respecter strictement.
# Si le code est dans BUT_CODES_PASSAGE (ADM, ADJ, PASD, PAS1NCI, ATJ),
# autorise à passer dans le semestre suivant
if (
self.jury_annuel
and code in sco_codes.BUT_CODES_PASSAGE
and self.formsemestre_pair.semestre_id < sco_codes.ParcoursBUT.NB_SEM and self.formsemestre_pair.semestre_id < sco_codes.ParcoursBUT.NB_SEM
): ):
return self.formsemestre_pair.semestre_id + 1 ids.add(self.formsemestre.semestre_id + 1)
return None
if code == RED:
ids.add(
self.formsemestre.semestre_id - (self.formsemestre.semestre_id + 1) % 2
)
return ids
def record_form(self, form: dict): def record_form(self, form: dict):
"""Enregistre les codes de jury en base """Enregistre les codes de jury en base
@ -704,47 +723,43 @@ class DecisionsProposeesAnnee(DecisionsProposees):
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):
self.recorded = True if code != self.code_valide and (self.code_valide is None or not no_overwrite):
return False # no change # Enregistrement du code annuel BUT
if self.validation: if self.validation:
db.session.delete(self.validation) db.session.delete(self.validation)
db.session.commit() db.session.commit()
if code is None: if code is None:
self.validation = None self.validation = None
else: else:
self.validation = ApcValidationAnnee( self.validation = ApcValidationAnnee(
etudid=self.etud.id, etudid=self.etud.id,
formsemestre=self.formsemestre_impair, formsemestre=self.formsemestre_impair,
ordre=self.annee_but, ordre=self.annee_but,
annee_scolaire=self.annee_scolaire(), annee_scolaire=self.annee_scolaire(),
code=code, code=code,
) )
db.session.add(self.validation) db.session.add(self.validation)
db.session.commit() db.session.commit()
log(f"Recording {self}: {code}") log(f"Recording {self}: {code}")
Scolog.logdb( Scolog.logdb(
method="jury_but", method="jury_but",
etudid=self.etud.id, etudid=self.etud.id,
msg=f"Validation année BUT{self.annee_but}: {code}", msg=f"Validation année BUT{self.annee_but}: {code}",
) )
# --- Autorisation d'inscription dans semestre suivant ? # --- Autorisation d'inscription dans semestre suivant ?
if self.formsemestre_pair is not None: ScolarAutorisationInscription.delete_autorisation_etud(
if code is None: etudid=self.etud.id,
ScolarAutorisationInscription.delete_autorisation_etud( origin_formsemestre_id=self.formsemestre.id,
etudid=self.etud.id, )
origin_formsemestre_id=self.formsemestre_pair.id, for next_semestre_id in self.next_semestre_ids(code):
) ScolarAutorisationInscription.autorise_etud(
else: self.etud.id,
next_semestre_id = self.next_annee_semestre_id(code) self.formsemestre.formation.formation_code,
if next_semestre_id is not None: self.formsemestre.id,
ScolarAutorisationInscription.autorise_etud( next_semestre_id,
self.etud.id, )
self.formsemestre_pair.formation.formation_code,
self.formsemestre_pair.id,
next_semestre_id,
)
db.session.commit() db.session.commit()
self.recorded = True self.recorded = True
@ -872,18 +887,18 @@ class DecisionsProposeesAnnee(DecisionsProposees):
self.invalidate_formsemestre_cache() self.invalidate_formsemestre_cache()
def get_autorisations_passage(self) -> list[int]: def get_autorisations_passage(self) -> list[int]:
"""Les liste des indices de semestres auxquels on est autorisé à """Liste des indices de semestres auxquels on est autorisé à
s'inscrire depuis cette année""" s'inscrire depuis le semestre courant.
formsemestre = self.formsemestre_pair or self.formsemestre_impair """
if not formsemestre: return sorted(
return [] [
return [ a.semestre_id
a.semestre_id for a in ScolarAutorisationInscription.query.filter_by(
for a in ScolarAutorisationInscription.query.filter_by( etudid=self.etud.id,
etudid=self.etud.id, origin_formsemestre_id=self.formsemestre.id,
origin_formsemestre_id=formsemestre.id, )
) ]
] )
def descr_niveaux_validation(self, line_sep: str = "\n") -> str: def descr_niveaux_validation(self, line_sep: str = "\n") -> str:
"""Description textuelle des niveaux validés (enregistrés) """Description textuelle des niveaux validés (enregistrés)

View File

@ -43,21 +43,20 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
""" """
H = [] H = []
H.append("""<div class="but_section_annee">""") if deca.jury_annuel:
H.append( H.append(
f""" f"""
<div> <div class="but_section_annee">
<b>Décision de jury pour l'année :</b> { <div>
_gen_but_select("code_annee", deca.codes, deca.code_valide, <b>Décision de jury pour l'année :</b> {
disabled=True, klass="manual") _gen_but_select("code_annee", deca.codes, deca.code_valide,
} disabled=True, klass="manual")
<span>({deca.code_valide or 'non'} enregistrée)</span> }
<span>({deca.code_valide or 'non'} enregistrée)</span>
</div>
</div> </div>
""" """
) )
div_explanation = f"""<div class="but_explanation">{deca.explanation}</div>"""
H.append("""</div>""")
formsemestre_1 = deca.formsemestre_impair formsemestre_1 = deca.formsemestre_impair
formsemestre_2 = deca.formsemestre_pair formsemestre_2 = deca.formsemestre_pair
@ -74,7 +73,7 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
<div class="titre_niveaux"> <div class="titre_niveaux">
<b>Niveaux de compétences et unités d'enseignement du BUT{deca.annee_but}</b> <b>Niveaux de compétences et unités d'enseignement du BUT{deca.annee_but}</b>
</div> </div>
{div_explanation} <div class="but_explanation">{deca.explanation}</div>
<div class="but_annee"> <div class="but_annee">
<div class="titre"></div> <div class="titre"></div>
<div class="titre">{"S" +str(formsemestre_1.semestre_id) <div class="titre">{"S" +str(formsemestre_1.semestre_id)
@ -285,7 +284,7 @@ def jury_but_semestriel(
read_only: bool, read_only: bool,
navigation_div: str = "", navigation_div: str = "",
) -> str: ) -> str:
"""Formulaire saisie décision d'UE d'un semestre BUT isolé (pas jury annuel)""" """Page: formulaire saisie décision d'UE d'un semestre BUT isolé (pas jury annuel)."""
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre) res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
parcour, ues = jury_but.list_ue_parcour_etud(formsemestre, etud, res) parcour, ues = jury_but.list_ue_parcour_etud(formsemestre, etud, res)
inscription_etat = etud.inscription_etat(formsemestre.id) inscription_etat = etud.inscription_etat(formsemestre.id)
@ -374,20 +373,20 @@ def jury_but_semestriel(
f""" f"""
<div class="jury_but"> <div class="jury_but">
<div> <div>
<div class="bull_head"> <div class="bull_head">
<div> <div>
<div class="titre_parcours">Jury BUT S{formsemestre.id} <div class="titre_parcours">Jury BUT S{formsemestre.id}
- Parcours {(parcour.libelle if parcour else False) or "non spécifié"} - Parcours {(parcour.libelle if parcour else False) or "non spécifié"}
</div>
<div class="nom_etud">{etud.nomprenom}</div>
</div>
<div class="bull_photo"><a href="{
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
</div>
</div> </div>
<div class="nom_etud">{etud.nomprenom}</div> <h3>Jury sur un semestre BUT isolé (ne concerne que les UEs)</h3>
</div> {warning}
<div class="bull_photo"><a href="{
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
</div>
</div>
<h3>Jury sur un semestre BUT isolé (ne concerne que les UEs)</h3>
{warning}
</div> </div>
<form method="post" id="jury_but"> <form method="post" id="jury_but">
@ -450,24 +449,35 @@ def jury_but_semestriel(
) )
H.append("</div>") # but_annee H.append("</div>") # but_annee
div_autorisations_passage = (
f"""
<div class="but_autorisations_passage">
<span>Autorisé à passer en&nbsp;:</span>
{ ", ".join( ["S" + str(a.semestre_id or '') for a in autorisations_passage ] )}
</div>
"""
if autorisations_passage
else """<div class="but_autorisations_passage but_explanation">pas d'autorisations de passage enregistrées.</div>"""
)
H.append(div_autorisations_passage)
if read_only: if read_only:
H.append( H.append(
"""<div class="but_explanation"> """<div class="but_explanation">
Vous n'avez pas la permission de modifier ces décisions. Vous n'avez pas la permission de modifier ces décisions.
Les champs entourés en vert sont enregistrés.</div>""" Les champs entourés en vert sont enregistrés.
</div>
"""
) )
else: else:
if formsemestre.semestre_id < formsemestre.formation.get_parcours().NB_SEM: if formsemestre.semestre_id < formsemestre.formation.get_parcours().NB_SEM:
H.append( H.append(
f""" f"""
<div class="but_settings"> <div class="but_settings">
<input type="checkbox" name="autorisation_passage" value="1" { <input type="checkbox" name="autorisation_passage" value="1" {
"checked" if est_autorise_a_passer else ""}> "checked" if est_autorise_a_passer else ""}>
<em>autoriser à passer dans le semestre S{formsemestre.semestre_id+1}</em> <em>autoriser à passer dans le semestre S{formsemestre.semestre_id+1}</em>
{("(autorisations enregistrées: " + ' '.join( </input>
'S' + str(a.semestre_id or '') for a in autorisations_passage) + ")"
) if autorisations_passage else ""}
</input>
</div> </div>
""" """
) )

View File

@ -544,7 +544,9 @@ def _ligne_evaluation(
if not first_eval: if not first_eval:
H.append("""<tr><td colspan="8">&nbsp;</td></tr>""") H.append("""<tr><td colspan="8">&nbsp;</td></tr>""")
tr_class_1 += " mievr_spaced" tr_class_1 += " mievr_spaced"
H.append(f"""<tr class="{tr_class_1}"><td class="mievr_tit" colspan="8">""") H.append(
f"""<tr class="{tr_class_1} mievr_tit"><td class="mievr_tit" colspan="8">"""
)
coef = evaluation.coefficient coef = evaluation.coefficient
if is_apc: if is_apc:
if not evaluation.get_ue_poids_dict(): if not evaluation.get_ue_poids_dict():
@ -588,7 +590,9 @@ def _ligne_evaluation(
) )
# #
H.append( H.append(
f"""<div class="evaluation_order"> f"""
</td>
<td class="evaluation_order">
<span class="evalindex" title="Indice dans les vecteurs (formules)">{ <span class="evalindex" title="Indice dans les vecteurs (formules)">{
eval_index:2}</span> eval_index:2}</span>
<span class="eval_arrows_chld"> <span class="eval_arrows_chld">
@ -612,20 +616,6 @@ def _ligne_evaluation(
else: else:
H.append(arrow_none) H.append(arrow_none)
H.append(
f"""</span></span></td>
</div>
</tr>
<tr class="{tr_class}">
<th class="moduleimpl_evaluations" colspan="2">&nbsp;</th>
<th class="moduleimpl_evaluations">Durée</th>
<th class="moduleimpl_evaluations">Coef.</th>
<th class="moduleimpl_evaluations">Notes</th>
<th class="moduleimpl_evaluations">Abs</th>
<th class="moduleimpl_evaluations">N</th>
<th class="moduleimpl_evaluations">Moyenne """
)
if etat["evalcomplete"]: if etat["evalcomplete"]:
etat_txt = """(prise en compte)""" etat_txt = """(prise en compte)"""
etat_descr = "notes utilisées dans les moyennes" etat_descr = "notes utilisées dans les moyennes"
@ -648,9 +638,19 @@ def _ligne_evaluation(
}" title="{etat_descr}">{etat_txt}</a>""" }" title="{etat_descr}">{etat_txt}</a>"""
H.append( H.append(
f"""{etat_txt}</th> f"""</span></span></td>
</tr> </tr>
<tr class="{tr_class}"><td class="mievr">""" <tr class="{tr_class}">
<th class="moduleimpl_evaluations" colspan="2">&nbsp;</th>
<th class="moduleimpl_evaluations">Durée</th>
<th class="moduleimpl_evaluations">Coef.</th>
<th class="moduleimpl_evaluations">Notes</th>
<th class="moduleimpl_evaluations">Abs</th>
<th class="moduleimpl_evaluations">N</th>
<th class="moduleimpl_evaluations" colspan="2">Moyenne {etat_txt}</th>
</tr>
<tr class="{tr_class}">
<td class="mievr">"""
) )
if can_edit_evals: if can_edit_evals:
H.append( H.append(
@ -726,7 +726,7 @@ def _ligne_evaluation(
<td class="rightcell mievr_nbnotes">{etat["nb_notes"]} / {etat["nb_inscrits"]}</td> <td class="rightcell mievr_nbnotes">{etat["nb_notes"]} / {etat["nb_inscrits"]}</td>
<td class="rightcell mievr_coef">{etat["nb_abs"]}</td> <td class="rightcell mievr_coef">{etat["nb_abs"]}</td>
<td class="rightcell mievr_coef">{etat["nb_neutre"]}</td> <td class="rightcell mievr_coef">{etat["nb_neutre"]}</td>
<td class="rightcell">""" <td class="rightcell" colspan="2">"""
% etat % etat
) )
if etat["moy"]: if etat["moy"]:
@ -750,11 +750,11 @@ def _ligne_evaluation(
H.append(f"""<tr class="{tr_class}"><td></td>""") H.append(f"""<tr class="{tr_class}"><td></td>""")
if modimpl.module.is_apc(): if modimpl.module.is_apc():
H.append( H.append(
f"""<td colspan="7" class="eval_poids">{ f"""<td colspan="8" class="eval_poids">{
evaluation.get_ue_poids_str()}</td>""" evaluation.get_ue_poids_str()}</td>"""
) )
else: else:
H.append('<td colspan="7"></td>') H.append('<td colspan="8"></td>')
H.append("""</tr>""") H.append("""</tr>""")
else: # il y a deja des notes saisies else: # il y a deja des notes saisies
gr_moyennes = etat["gr_moyennes"] gr_moyennes = etat["gr_moyennes"]
@ -773,7 +773,10 @@ def _ligne_evaluation(
name = "Tous" # tous name = "Tous" # tous
else: else:
name = f"""Groupe {gr_moyenne["group_name"]}""" name = f"""Groupe {gr_moyenne["group_name"]}"""
H.append(f"""<td colspan="2" class="mievr_grtit">{name} &nbsp;</td><td>""") H.append(
f"""<td colspan="2" class="mievr_grtit">{name} &nbsp;</td>
<td colspan="2">"""
)
if gr_moyenne["gr_nb_notes"] > 0: if gr_moyenne["gr_nb_notes"] > 0:
H.append( H.append(
f"""{gr_moyenne["gr_moy"]}&nbsp; (<a href="{ f"""{gr_moyenne["gr_moy"]}&nbsp; (<a href="{

View File

@ -1,5 +1,10 @@
/* Saisie décision de jury BUT */ /* Saisie décision de jury BUT */
:root {
--color-recorded: rgb(3, 157, 3);
--color-explanation: blueviolet;
}
.jury_but { .jury_but {
font-family: Verdana, Geneva, Tahoma, sans-serif; font-family: Verdana, Geneva, Tahoma, sans-serif;
} }
@ -18,6 +23,19 @@
margin-top: 0px; margin-top: 0px;
} }
form#jury_but {
margin: 0px 16px 16px 16px;
background-color: rgb(253, 253, 231);
border: 2px solid rgb(4, 4, 118);
border-radius: 4px;
padding-top: 8px;
padding-left: 16px;
padding-right: 16px;
padding-bottom: 16px;
min-width: var(--sco-content-min-width);
max-width: var(--sco-content-max-width);
}
.but_annee { .but_annee {
margin-left: 32px; margin-left: 32px;
display: inline-grid; display: inline-grid;
@ -112,11 +130,10 @@ div.but_settings {
} }
.but_explanation { .but_explanation {
color: blueviolet; color: var(--color-explanation);
font-style: italic; font-style: italic;
padding-top: 4px; padding-top: 4px;
padding-bottom: 12px; padding-bottom: 12px;
;
} }
select:disabled { select:disabled {
@ -130,7 +147,7 @@ select:invalid {
select.but_code option.recorded, select.but_code option.recorded,
div.but_code recorded { div.but_code recorded {
color: rgb(3, 157, 3); color: var(--color-recorded);
font-weight: bold; font-weight: bold;
} }
@ -143,14 +160,14 @@ div.but_code {
div.but_niveau_ue.recorded, div.but_niveau_ue.recorded,
div.but_niveau_rcue.recorded { div.but_niveau_rcue.recorded {
border-color: rgb(0, 169, 0); border-color: var(--color-recorded);
border-width: 3px; border-width: 3px;
} }
div.but_niveau_ue.recorded_different, 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 rgb(0, 169, 0); outline: dashed 3px var(--color-recorded);
} }
div.but_niveau_ue.annee_prec { div.but_niveau_ue.annee_prec {
@ -174,6 +191,8 @@ div.but_buttons span {
div.but_doc_codes { div.but_doc_codes {
margin: 16px; margin: 16px;
min-width: var(--sco-content-min-width);
max-width: var(--sco-content-max-width);
background-color: rgb(227, 254, 254); background-color: rgb(227, 254, 254);
font-size: 75%; font-size: 75%;
border: 2px solid rgb(4, 4, 118); border: 2px solid rgb(4, 4, 118);
@ -227,4 +246,16 @@ div.but_doc table tr td.amue {
.but_niveau_rcue .scoplement { .but_niveau_rcue .scoplement {
font-weight: normal; font-weight: normal;
}
.but_autorisations_passage {
margin-top: 12px;
margin-left: 32px;
font-weight: bold;
color: var(--color-recorded);
}
.but_autorisations_passage.but_explanation {
font-weight: normal;
color: var(--color-explanation);
} }

View File

@ -1,7 +1,11 @@
/* # -*- mode: css -*- /* ScoDoc, (c) Emmanuel Viennet 1998 - 2023
ScoDoc, (c) Emmanuel Viennet 1998 - 2021
*/ */
:root {
--sco-content-min-width: 600px;
--sco-content-max-width: 1024px;
}
html, html,
body { body {
margin: 0; margin: 0;
@ -1728,6 +1732,8 @@ ul.ue_inscr_list li.etud {
div.moduleimpl_tableaubord { div.moduleimpl_tableaubord {
padding: 7px; padding: 7px;
border: 2px solid gray; border: 2px solid gray;
min-width: var(--sco-content-min-width);
max-width: var(--sco-content-max-width);
} }
div.moduleimpl_type_sae { div.moduleimpl_type_sae {
@ -1855,11 +1861,19 @@ span.mievr_rattr {
padding: 1px 3px 1px 3px; padding: 1px 3px 1px 3px;
} }
tr.mievr td.mievr_tit { tr.mievr_tit td.mievr_tit {
font-weight: bold; font-weight: bold;
background-color: #cccccc;
border-top-left-radius: 8px; border-top-left-radius: 8px;
}
tr.mievr.mievr_tit td {
background-color: #e1e1e1;
}
tr.mievr_tit td:last-child {
border-top-right-radius: 8px; border-top-right-radius: 8px;
text-align: right;
padding-right: 8px;
} }
tr.mievr td { tr.mievr td {
@ -1922,11 +1936,6 @@ span.eval_warning_coef {
background-color: rgb(255, 225, 0); background-color: rgb(255, 225, 0);
} }
div.evaluation_order {
position: absolute;
right: 1em;
}
span.evalindex { span.evalindex {
font-weight: normal; font-weight: normal;
font-size: 80%; font-size: 80%;
@ -2580,11 +2589,13 @@ div.bull_head {
display: grid; display: grid;
justify-content: space-between; justify-content: space-between;
grid-template-columns: auto auto; grid-template-columns: auto auto;
min-width: 600px;
max-width: 1072px;
} }
div.bull_photo { div.bull_photo {
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 8px;
} }
span.bulletin_menubar_but { span.bulletin_menubar_but {

View File

@ -2499,11 +2499,26 @@ def formsemestre_validation_but(
H.append(jury_but_view.show_etud(deca, read_only=read_only)) H.append(jury_but_view.show_etud(deca, read_only=read_only))
autorisations_idx = deca.get_autorisations_passage()
div_autorisations_passage = (
f"""
<div class="but_autorisations_passage">
<span>Autorisé à passer en&nbsp;:</span>
{ ", ".join( ["S" + str(i) for i in autorisations_idx ] )}
</div>
"""
if autorisations_idx
else """<div class="but_autorisations_passage but_explanation">pas d'autorisations de passage enregistrées.</div>"""
)
H.append(div_autorisations_passage)
if read_only: if read_only:
H.append( H.append(
"""<div class="but_explanation"> """
<div class="but_explanation">
Vous n'avez pas la permission de modifier ces décisions. Vous n'avez pas la permission de modifier ces décisions.
Les champs entourés en vert sont enregistrés.</div>""" Les champs entourés en vert sont enregistrés.
</div>"""
) )
else: else:
erase_span = f"""<a href="{ erase_span = f"""<a href="{
@ -2513,9 +2528,11 @@ def formsemestre_validation_but(
H.append( H.append(
f"""<div class="but_settings"> f"""<div class="but_settings">
<input type="checkbox" onchange="enable_manual_codes(this)"> <input type="checkbox" onchange="enable_manual_codes(this)">
<em>permettre la saisie manuelles des codes d'année et de niveaux. <em>permettre la saisie manuelles des codes
Dans ce cas, il vous revient de vous assurer de la cohérence entre {"d'année et " if deca.jury_annuel else ""}
vos codes d'UE/RCUE/Année !</em> de niveaux.
Dans ce cas, assurez-vous de la cohérence entre les codes d'UE/RCUE/Année !
</em>
</input> </input>
</div> </div>

View File

@ -32,7 +32,7 @@ from app.models import GroupDescr
from app.models import Identite from app.models import Identite
from app.models import ModuleImpl, ModuleImplInscription from app.models import ModuleImpl, ModuleImplInscription
from app.models import Partition from app.models import Partition
from app.models import ScolarFormSemestreValidation from app.models import ScolarAutorisationInscription, ScolarFormSemestreValidation
from app.models.but_refcomp import ( from app.models.but_refcomp import (
ApcCompetence, ApcCompetence,
ApcNiveau, ApcNiveau,
@ -101,6 +101,7 @@ def make_shell_context():
"ResultatsSemestreBUT": ResultatsSemestreBUT, "ResultatsSemestreBUT": ResultatsSemestreBUT,
"Role": Role, "Role": Role,
"scolar": scolar, "scolar": scolar,
"ScolarAutorisationInscription": ScolarAutorisationInscription,
"ScolarFormSemestreValidation": ScolarFormSemestreValidation, "ScolarFormSemestreValidation": ScolarFormSemestreValidation,
"ScolarNews": models.ScolarNews, "ScolarNews": models.ScolarNews,
"scu": scu, "scu": scu,

View File

@ -1022,3 +1022,84 @@ Etudiants:
moy_ue: 9.5000 moy_ue: 9.5000
moy_ue_with_cap: 12.7600 moy_ue_with_cap: 12.7600
decision_annee: AJ decision_annee: AJ
geii1000:
prenom: etugeii1000
civilite: M
formsemestres:
S1:
notes_modules: # on joue avec les SAE seulement car elles sont "diagonales"
"S1.1": 12.0000
"S1.2": 9.0000
attendu: # les codes jury que l'on doit vérifier
deca:
passage_de_droit: False
nb_competences: 2
nb_rcue_annee: 0
decisions_ues:
"UE11":
codes: [ "ADM", "..." ]
code_valide: ADM
moy_ue: 12.0000
"UE12":
codes: [ "AJ", "..." ]
code_valide: AJ
decision_jury: AJ
moy_ue: 9.0000
S2:
notes_modules: # on joue avec les SAE seulement car elles sont "diagonales"
"S2.1": 12.0000
"S2.2": 10.50 # capitalise mais ne compense pas
attendu: # les codes jury que l'on doit vérifier
deca:
passage_de_droit: False
nb_competences: 2
nb_rcue_annee: 2
valide_moitie_rcue: False
codes: [ "RED", "..." ]
decisions_ues:
"UE21":
codes: [ "ADM", "..." ]
code_valide: ADM
moy_ue: 12.0000
"UE22":
code_valide: ADM
moy_ue: 10.5
decisions_rcues: # on repère ici les RCUE par l'acronyme de leur 1ere UE (donc du S1)
"UE11":
code_valide: ADM
decision_jury: ADM
rcue:
moy_rcue: 12.0000
est_compensable: False
"UE12":
code_valide: AJ
decision_jury: AJ
rcue:
moy_rcue: 9.75
est_compensable: False
decision_annee: RED
S1-red:
notes_modules: # on joue avec les SAE seulement car elles sont "diagonales"
"S1.1": 5.0000
"S1.2": 12.0000
attendu: # les codes jury que l'on doit vérifier
deca:
passage_de_droit: False
nb_competences: 2
nb_rcue_annee: 0
decisions_ues:
"UE11":
code_valide: AJ
moy_ue: 5. # LA MOYENNE COURANTE
moy_ue_with_cap: 12.0000
"UE12":
code_valide: ADM
decision_jury: ADM
moy_ue: 12.0000
# RCUE inter-annuel
decisions_rcues: # on repère ici les RCUE par l'acronyme de leur 1ere UE (donc du S1)
"UE12":
code_valide: ADM
rcue:
moy_rcue: 11.25
est_compensable: False

View File

@ -33,7 +33,7 @@ DEPT = TestConfig.DEPT_TEST
@pytest.mark.but_gb @pytest.mark.but_gb
def test_but_jury_GB(test_client): def test_but_jury_GB(test_client):
"""Tests sur un cursus GB """Tests sur un cursus GB
- construction des semestres et de leurs étudianst à partir du yaml - construction des semestres et de leurs étudiants à partir du yaml
- vérification jury de S1 - vérification jury de S1
- vérification jury de S2 - vérification jury de S2
- vérification jury de S3 - vérification jury de S3
@ -96,7 +96,6 @@ def test_but_jury_GEII_lyon(test_client):
# Construit la base de test GB une seule fois # Construit la base de test GB une seule fois
# puis lance les tests de jury # puis lance les tests de jury
doc = yaml_setup.setup_from_yaml("tests/unit/cursus_but_geii_lyon.yaml") doc = yaml_setup.setup_from_yaml("tests/unit/cursus_but_geii_lyon.yaml")
formsemestres = FormSemestre.query.order_by( formsemestres = FormSemestre.query.order_by(
FormSemestre.date_debut, FormSemestre.semestre_id FormSemestre.date_debut, FormSemestre.semestre_id
).all() ).all()