forked from ScoDoc/ScoDoc
Dispenses d'UE: corrige affichage en table recap. Intègre aux tests unitaires cursus. Légendes.
This commit is contained in:
parent
5103f162a7
commit
c889ba3d1d
@ -260,8 +260,10 @@ class UniteEns(db.Model):
|
|||||||
|
|
||||||
class DispenseUE(db.Model):
|
class DispenseUE(db.Model):
|
||||||
"""Dispense d'UE
|
"""Dispense d'UE
|
||||||
Utilisé en APC (BUT) pour indiquer les étudiants redoublants avec une UE capitalisée
|
Utilisé en APC (BUT) pour indiquer
|
||||||
qu'ils ne refont pas.
|
- les étudiants redoublants avec une UE capitalisée qu'ils ne refont pas.
|
||||||
|
- les étudiants "non inscrit" à une UE car elle ne fait pas partie de leur Parcours.
|
||||||
|
|
||||||
La dispense d'UE n'est PAS une validation:
|
La dispense d'UE n'est PAS une validation:
|
||||||
- elle n'est pas affectée par les décisions de jury (pas effacée)
|
- elle n'est pas affectée par les décisions de jury (pas effacée)
|
||||||
- elle est associée à un formsemestre
|
- elle est associée à un formsemestre
|
||||||
|
@ -613,11 +613,16 @@ def _list_but_ue_inscriptions(res: NotesTableCompat, read_only: bool = True) ->
|
|||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
<div class="help">
|
<div class="help">
|
||||||
L'inscription ou désinscription aux UEs du BUT n'affecte pas les inscriptions aux modules
|
<p>L'inscription ou désinscription aux UEs du BUT n'affecte pas les inscriptions aux modules
|
||||||
mais permet de "dispenser" un étudiant de suivre certaines UEs de son parcours.
|
mais permet de "dispenser" un étudiant de suivre certaines UEs de son parcours.
|
||||||
Il peut s'agit d'étudiants redoublants ayant déjà acquis l'UE, ou d'autres cas particuliers.
|
</p>
|
||||||
La dispense d'UE est réversible à tout moment (avant le jury de fin de semestre)
|
<p>Il peut s'agit d'étudiants redoublants ayant déjà acquis l'UE, ou d'une UE
|
||||||
|
présente dans le semestre mais pas dans le parcours de l'étudiant, ou bien d'autres
|
||||||
|
cas particuliers.
|
||||||
|
</p>
|
||||||
|
<p>La dispense d'UE est réversible à tout moment (avant le jury de fin de semestre)
|
||||||
et n'affecte pas les notes saisies.
|
et n'affecte pas les notes saisies.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
@ -242,7 +242,19 @@ def formsemestre_recapcomplet(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
# Légende
|
||||||
|
H.append(
|
||||||
|
"""
|
||||||
|
<div class="table_recap_caption">
|
||||||
|
<div class="title">Codes utilisés dans cette table:</div>
|
||||||
|
<div class="captions">
|
||||||
|
<div><tt>~</tt></div><div>valeur manquante</div>
|
||||||
|
<div><tt>=</tt></div><div>UE dispensée</div>
|
||||||
|
<div><tt>nan</tt></div><div>valeur non disponible</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
)
|
||||||
H.append(html_sco_header.sco_footer())
|
H.append(html_sco_header.sco_footer())
|
||||||
# HTML or binary data ?
|
# HTML or binary data ?
|
||||||
if len(H) > 1:
|
if len(H) > 1:
|
||||||
|
@ -2672,6 +2672,30 @@ table.notes_recapcomplet a:hover {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.table_recap_caption {
|
||||||
|
width: fit-content;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: rgb(202, 255, 180);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_recap_caption div.title {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_recap_caption div.captions {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 48px 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_recap_caption div.captions div:nth-child(odd) {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.table_recap_caption div.captions div:nth-child(even) {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
/* bulletin */
|
/* bulletin */
|
||||||
div.notes_bulletin {
|
div.notes_bulletin {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
@ -154,7 +154,7 @@ class TableJury(TableRecap):
|
|||||||
niveau: ApcNiveau = validation_rcue.niveau()
|
niveau: ApcNiveau = validation_rcue.niveau()
|
||||||
titre = f"C{niveau.competence.numero}" # à voir (nommer les compétences...)
|
titre = f"C{niveau.competence.numero}" # à voir (nommer les compétences...)
|
||||||
row.add_cell(
|
row.add_cell(
|
||||||
f"c_{competence_id}_annee",
|
f"c_{competence_id}_{annee}",
|
||||||
titre,
|
titre,
|
||||||
validation_rcue.code,
|
validation_rcue.code,
|
||||||
group="cursus_" + annee,
|
group="cursus_" + annee,
|
||||||
|
@ -285,9 +285,9 @@ class TableRecap(tb.Table):
|
|||||||
notes = res.modimpl_notes(modimpl.id, ue.id)
|
notes = res.modimpl_notes(modimpl.id, ue.id)
|
||||||
if np.isnan(notes).all():
|
if np.isnan(notes).all():
|
||||||
# aucune note valide
|
# aucune note valide
|
||||||
row_min.add_cell(col_id, None, np.nan)
|
row_min.add_cell(col_id, None, "")
|
||||||
row_max.add_cell(col_id, None, np.nan)
|
row_max.add_cell(col_id, None, "")
|
||||||
moy = np.nan
|
moy = ""
|
||||||
else:
|
else:
|
||||||
row_min.add_cell(col_id, None, self.fmt_note(np.nanmin(notes)))
|
row_min.add_cell(col_id, None, self.fmt_note(np.nanmin(notes)))
|
||||||
row_max.add_cell(col_id, None, self.fmt_note(np.nanmax(notes)))
|
row_max.add_cell(col_id, None, self.fmt_note(np.nanmax(notes)))
|
||||||
@ -297,7 +297,7 @@ class TableRecap(tb.Table):
|
|||||||
None,
|
None,
|
||||||
self.fmt_note(moy),
|
self.fmt_note(moy),
|
||||||
# aucune note dans ce module ?
|
# aucune note dans ce module ?
|
||||||
classes=["col_empty" if np.isnan(moy) else ""],
|
classes=["col_empty" if (moy == "" or np.isnan(moy)) else ""],
|
||||||
)
|
)
|
||||||
row_apo.add_cell(col_id, None, modimpl.module.code_apogee or "")
|
row_apo.add_cell(col_id, None, modimpl.module.code_apogee or "")
|
||||||
|
|
||||||
@ -618,7 +618,7 @@ class RowRecap(tb.Row):
|
|||||||
):
|
):
|
||||||
"""Ajoute cols moy_gen moy_ue et tous les modules..."""
|
"""Ajoute cols moy_gen moy_ue et tous les modules..."""
|
||||||
etud = self.etud
|
etud = self.etud
|
||||||
table = self.table
|
table: TableRecap = self.table
|
||||||
res = table.res
|
res = table.res
|
||||||
# --- Si DEM ou DEF, ne montre aucun résultat d'UE ni moy. gen.
|
# --- Si DEM ou DEF, ne montre aucun résultat d'UE ni moy. gen.
|
||||||
if res.get_etud_etat(etud.id) != scu.INSCRIT:
|
if res.get_etud_etat(etud.id) != scu.INSCRIT:
|
||||||
@ -701,13 +701,17 @@ class RowRecap(tb.Row):
|
|||||||
def add_ue_cols(self, ue: UniteEns, ue_status: dict, col_group: str = None):
|
def add_ue_cols(self, ue: UniteEns, ue_status: dict, col_group: str = None):
|
||||||
"Ajoute résultat UE au row (colonne col_ue)"
|
"Ajoute résultat UE au row (colonne col_ue)"
|
||||||
# sous-classé par JuryRow pour ajouter les codes
|
# sous-classé par JuryRow pour ajouter les codes
|
||||||
table = self.table
|
table: TableRecap = self.table
|
||||||
formsemestre: FormSemestre = table.res.formsemestre
|
formsemestre: FormSemestre = table.res.formsemestre
|
||||||
table.group_titles[
|
table.group_titles[
|
||||||
"col_ue"
|
"col_ue"
|
||||||
] = f"UEs du S{formsemestre.semestre_id} {formsemestre.annee_scolaire()}"
|
] = f"UEs du S{formsemestre.semestre_id} {formsemestre.annee_scolaire()}"
|
||||||
col_id = f"moy_ue_{ue.id}"
|
col_id = f"moy_ue_{ue.id}"
|
||||||
val = ue_status["moy"]
|
val = (
|
||||||
|
ue_status["moy"]
|
||||||
|
if (self.etud.id, ue.id) not in table.res.dispense_ues
|
||||||
|
else "="
|
||||||
|
)
|
||||||
note_classes = []
|
note_classes = []
|
||||||
if isinstance(val, float):
|
if isinstance(val, float):
|
||||||
if val < table.barre_moy:
|
if val < table.barre_moy:
|
||||||
|
@ -134,7 +134,7 @@ FormSemestres:
|
|||||||
codes_parcours: ['BAT', 'TP']
|
codes_parcours: ['BAT', 'TP']
|
||||||
|
|
||||||
Etudiants:
|
Etudiants:
|
||||||
A_ok: # Etudiant qui va tout valider directement
|
A_ok: # Etudiant parcours BAT qui va tout valider directement
|
||||||
prenom: Étudiant_BAT
|
prenom: Étudiant_BAT
|
||||||
civilite: M
|
civilite: M
|
||||||
formsemestres:
|
formsemestres:
|
||||||
@ -157,9 +157,41 @@ Etudiants:
|
|||||||
|
|
||||||
S5:
|
S5:
|
||||||
parcours: BAT
|
parcours: BAT
|
||||||
|
dispense_ues: ['UE5.2']
|
||||||
notes_modules:
|
notes_modules:
|
||||||
"R5.01": 15 # toutes UE
|
"R5.01": 15 # toutes UE
|
||||||
"SAÉ 5.BAT.01": 10 # UE5.1
|
"SAÉ 5.BAT.01": 10 # UE5.1
|
||||||
"SAÉ 5.BAT.02": 11 # UE5.4
|
"SAÉ 5.BAT.02": 11 # UE5.4
|
||||||
S6:
|
S6:
|
||||||
parcours: BAT
|
parcours: BAT
|
||||||
|
|
||||||
|
B_ok: # Etudiant parcours TP qui va tout valider directement
|
||||||
|
prenom: Étudiant_TP
|
||||||
|
civilite: M
|
||||||
|
formsemestres:
|
||||||
|
S1:
|
||||||
|
parcours: TP
|
||||||
|
notes_modules:
|
||||||
|
"R1.01": 11 # toutes UEs
|
||||||
|
S2:
|
||||||
|
parcours: TP
|
||||||
|
notes_modules:
|
||||||
|
"R2.01": 12 # toutes UEs
|
||||||
|
S3:
|
||||||
|
parcours: TP
|
||||||
|
notes_modules:
|
||||||
|
"R3.01": 13 # toutes UEs
|
||||||
|
S4:
|
||||||
|
parcours: TP
|
||||||
|
notes_modules:
|
||||||
|
"R4.01": 14 # toutes UE
|
||||||
|
|
||||||
|
S5:
|
||||||
|
parcours: TP
|
||||||
|
dispense_ues: ['UE5.1']
|
||||||
|
notes_modules:
|
||||||
|
"R5.01": 15 # toutes UE
|
||||||
|
"SAÉ 5.BAT.01": 10 # UE5.1
|
||||||
|
"SAÉ 5.BAT.02": 11 # UE5.4
|
||||||
|
S6:
|
||||||
|
parcours: TP
|
||||||
|
@ -53,12 +53,14 @@ from app.auth.models import User
|
|||||||
|
|
||||||
from app.models import (
|
from app.models import (
|
||||||
ApcParcours,
|
ApcParcours,
|
||||||
|
DispenseUE,
|
||||||
Evaluation,
|
Evaluation,
|
||||||
Formation,
|
Formation,
|
||||||
FormSemestre,
|
FormSemestre,
|
||||||
Identite,
|
Identite,
|
||||||
Module,
|
Module,
|
||||||
ModuleImpl,
|
ModuleImpl,
|
||||||
|
UniteEns,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
@ -263,6 +265,9 @@ def inscrit_les_etudiants(formation: Formation, doc: dict):
|
|||||||
group_ids = [group.id]
|
group_ids = [group.id]
|
||||||
else:
|
else:
|
||||||
group_ids = []
|
group_ids = []
|
||||||
|
# Génère des dispenses d'UEs
|
||||||
|
if "dispense_ues" in sem_infos:
|
||||||
|
etud_dispense_ues(formsemestre, etud, sem_infos["dispense_ues"])
|
||||||
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
|
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
|
||||||
formsemestre.id,
|
formsemestre.id,
|
||||||
etud.id,
|
etud.id,
|
||||||
@ -275,6 +280,19 @@ def inscrit_les_etudiants(formation: Formation, doc: dict):
|
|||||||
formsemestre.update_inscriptions_parcours_from_groups()
|
formsemestre.update_inscriptions_parcours_from_groups()
|
||||||
|
|
||||||
|
|
||||||
|
def etud_dispense_ues(
|
||||||
|
formsemestre: FormSemestre, etud: Identite, ue_acronymes: list[str]
|
||||||
|
):
|
||||||
|
"""Génère des dispenses d'UE"""
|
||||||
|
for ue_acronyme in set(ue_acronymes):
|
||||||
|
ue: UniteEns = formsemestre.formation.ues.filter_by(
|
||||||
|
acronyme=ue_acronyme
|
||||||
|
).first()
|
||||||
|
assert ue
|
||||||
|
disp = DispenseUE(formsemestre_id=formsemestre.id, ue_id=ue.id, etudid=etud.id)
|
||||||
|
db.session.add(disp)
|
||||||
|
|
||||||
|
|
||||||
def setup_from_yaml(filename: str) -> dict:
|
def setup_from_yaml(filename: str) -> dict:
|
||||||
"""Lit le fichier yaml et construit l'ensemble des objets"""
|
"""Lit le fichier yaml et construit l'ensemble des objets"""
|
||||||
with open(filename, encoding="utf-8") as f:
|
with open(filename, encoding="utf-8") as f:
|
||||||
|
Loading…
Reference in New Issue
Block a user