Table recap: ok pour APC et classic, recap et jury.

This commit is contained in:
Emmanuel Viennet 2023-02-05 23:15:50 +01:00
parent 724d01c36a
commit aaef3fac58
5 changed files with 78 additions and 61 deletions

View File

@ -61,9 +61,9 @@ class TableJury(TableRecap):
if self.res.is_apc: if self.res.is_apc:
self.add_rcues() self.add_rcues()
self.add_jury() self.add_jury()
self.add_groups_header()
# Termine la table # Termine la table
self.finalize() self.finalize()
self.add_groups_header()
def add_rcues(self): def add_rcues(self):
"""Ajoute les colonnes indiquant le nb de RCUEs et chaque RCUE """Ajoute les colonnes indiquant le nb de RCUEs et chaque RCUE
@ -90,30 +90,37 @@ class TableJury(TableRecap):
que pour les formations classiques, ce code n'est pas utilisé en BUT. que pour les formations classiques, ce code n'est pas utilisé en BUT.
""" """
res = self.res res = self.res
if res.validations:
for row in self.rows: for row in self.rows:
etud = row.etud etud = row.etud
if not res.is_apc: if not res.is_apc:
# formations classiques: code semestre # formations classiques: code semestre
if res.validations:
dec_sem = res.validations.decisions_jury.get(etud.id) dec_sem = res.validations.decisions_jury.get(etud.id)
jury_code_sem = dec_sem["code"] if dec_sem else "" jury_code_sem = dec_sem["code"] if dec_sem else ""
row.add_cell( else:
"jury_code_sem", "Jury", jury_code_sem, group="jury_code_sem" jury_code_sem = ""
)
row.add_cell( row.add_cell(
"jury_link", "jury_code_sem", "Jury", jury_code_sem, group="jury_code_sem"
"",
f"""{("modifier" if res.validations.has_decision(etud) else "saisir")
if res.formsemestre.etat else "voir"} décisions""",
group="col_jury_link",
target=url_for(
"notes.formsemestre_validation_etud_form",
scodoc_dept=g.scodoc_dept,
formsemestre_id=res.formsemestre.id,
etudid=etud.id,
),
target_attrs={"class": "stdlink"},
) )
self.foot_title_row.cells["jury_code_sem"].target_attrs[
"title"
] = """Code jury sur le semestre"""
row.add_cell(
"jury_link",
"",
f"""{("modifier" if res.validations and res.validations.has_decision(etud) else "saisir")
if res.formsemestre.etat else "voir"} décisions""",
group="col_jury_link",
target=url_for(
"notes.formsemestre_validation_etud_form",
scodoc_dept=g.scodoc_dept,
formsemestre_id=res.formsemestre.id,
etudid=etud.id,
),
target_attrs={"class": "stdlink"},
)
class RowJury(RowRecap): class RowJury(RowRecap):
@ -122,10 +129,11 @@ class RowJury(RowRecap):
def __init__(self, table: TableJury, etud: Identite, *args, **kwargs): def __init__(self, table: TableJury, etud: Identite, *args, **kwargs):
self.table: TableJury = table self.table: TableJury = table
super().__init__(table, etud, *args, **kwargs) super().__init__(table, etud, *args, **kwargs)
# Conserve le deca de cet étudiant: if table.res.is_apc:
self.deca = jury_but.DecisionsProposeesAnnee( # Conserve le deca de cet étudiant:
self.etud, self.table.res.formsemestre self.deca = jury_but.DecisionsProposeesAnnee(
) self.etud, self.table.res.formsemestre
)
def add_nb_rcues_cell(self): def add_nb_rcues_cell(self):
"cell avec nb niveaux validables / total" "cell avec nb niveaux validables / total"
@ -165,9 +173,10 @@ class RowJury(RowRecap):
data={"order": order}, data={"order": order},
) )
def add_ue_cols(self, ue: UniteEns, ue_status: dict): def add_ue_cols(self, ue: UniteEns, ue_status: dict, col_group: str = None):
"Ajoute 2 colonnes: moyenne d'UE et code jury" "Ajoute 2 colonnes: moyenne d'UE et code jury"
super().add_ue_cols(ue, ue_status) # table recap standard # table recap standard (mais avec group différent)
super().add_ue_cols(ue, ue_status, col_group=col_group or "col_ue")
dues = self.table.res.get_etud_decision_ues(self.etud.id) dues = self.table.res.get_etud_decision_ues(self.etud.id)
if not dues: if not dues:
return return

View File

@ -59,7 +59,7 @@ class ResultatsSemestre(ResultatsCache):
def __init__(self, formsemestre: FormSemestre): def __init__(self, formsemestre: FormSemestre):
super().__init__(formsemestre, ResultatsSemestreCache) super().__init__(formsemestre, ResultatsSemestreCache)
# BUT ou standard ? (apc == "approche par compétences") # BUT ou standard ? (apc == "approche par compétences")
self.is_apc = formsemestre.formation.is_apc() self.is_apc: bool = formsemestre.formation.is_apc()
# Attributs "virtuels", définis dans les sous-classes # Attributs "virtuels", définis dans les sous-classes
self.bonus: pd.Series = None # virtuel self.bonus: pd.Series = None # virtuel
"Bonus sur moy. gen. Series de float, index etudid" "Bonus sur moy. gen. Series de float, index etudid"

View File

@ -42,7 +42,6 @@ from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre from app.models import FormSemestre
from app.models.etudiants import Identite from app.models.etudiants import Identite
from app.scodoc.gen_tables import GenTable
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc import html_sco_header from app.scodoc import html_sco_header
from app.scodoc import sco_bulletins_json from app.scodoc import sco_bulletins_json
@ -55,13 +54,13 @@ from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_permissions_check from app.scodoc import sco_permissions_check
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.tables.recap import TableRecap from app.tables.recap import TableRecap
from app.but.jury_but_recap import TableJury
def formsemestre_recapcomplet( def formsemestre_recapcomplet(
formsemestre_id=None, formsemestre_id=None,
mode_jury=False, mode_jury=False,
tabformat="html", tabformat="html",
sortcol=None,
xml_with_decisions=False, xml_with_decisions=False,
force_publishing=True, force_publishing=True,
selected_etudid=None, selected_etudid=None,
@ -101,7 +100,6 @@ def formsemestre_recapcomplet(
formsemestre_id, formsemestre_id,
format=tabformat, format=tabformat,
mode_jury=mode_jury, mode_jury=mode_jury,
sortcol=sortcol,
xml_with_decisions=xml_with_decisions, xml_with_decisions=xml_with_decisions,
force_publishing=force_publishing, force_publishing=force_publishing,
selected_etudid=selected_etudid, selected_etudid=selected_etudid,
@ -205,7 +203,6 @@ def _do_formsemestre_recapcomplet(
format="html", # html, xml, xls, xlsall, json format="html", # html, xml, xls, xlsall, json
xml_nodate=False, # format XML sans dates (sert pour debug cache: comparaison de XML) xml_nodate=False, # format XML sans dates (sert pour debug cache: comparaison de XML)
mode_jury=False, # saisie décisions jury mode_jury=False, # saisie décisions jury
sortcol=None, # indice colonne a trier dans table T
xml_with_decisions=False, xml_with_decisions=False,
force_publishing=True, force_publishing=True,
selected_etudid=None, selected_etudid=None,
@ -422,7 +419,8 @@ def _gen_formsemestre_recapcomplet_html(
selected_etudid=None, selected_etudid=None,
) -> str: ) -> str:
"""Génère le html""" """Génère le html"""
table = TableRecap( table_class = TableJury if mode_jury else TableRecap
table = table_class(
res, res,
convert_values=True, convert_values=True,
include_evaluations=include_evaluations, include_evaluations=include_evaluations,

View File

@ -4069,21 +4069,6 @@ table.table_recap.jury tr.odd td.col_rcue_code {
background-color: #e0eeff; background-color: #e0eeff;
} }
/* table.table_recap.jury tr.even td.col_rcue,
table.table_recap.jury tr.even td.col_rcue_code {
background-color: #e5f2ff;
} */
/* table.table_recap.jury tr.odd td.col_rcues_validables {
background-color: #d5eaff !important;
}
table.table_recap.jury tr.even td.col_rcues_validables {
background-color: #e5f2ff !important;
} */
table.table_recap .group { table.table_recap .group {
border-left: 1px dashed rgb(160, 160, 160); border-left: 1px dashed rgb(160, 160, 160);
white-space: nowrap; white-space: nowrap;
@ -4111,6 +4096,11 @@ table.table_recap tr th.col_ue_code {
border-left: none; border-left: none;
} }
table.table_recap tr td.jury_code_sem {
font-weight: bold;
border-left: 1px solid blue;
}
table.table_recap .admission { table.table_recap .admission {
white-space: nowrap; white-space: nowrap;
color: rgb(6, 73, 6); color: rgb(6, 73, 6);

View File

@ -103,6 +103,9 @@ class TableRecap(tb.Table):
if include_evaluations: if include_evaluations:
self.add_evaluations() self.add_evaluations()
if finalize:
self.finalize()
def finalize(self): def finalize(self):
"""Termine la table: ajoute ligne avec les types, """Termine la table: ajoute ligne avec les types,
et ajoute classe sur les colonnes vides""" et ajoute classe sur les colonnes vides"""
@ -217,7 +220,6 @@ class TableRecap(tb.Table):
"moy_gen", "moy_gen",
None, None,
self.fmt_note(res.etud_moy_gen.mean()), self.fmt_note(res.etud_moy_gen.mean()),
# classes=["col_moy_gen"],
) )
for ue in ues: for ue in ues:
@ -399,9 +401,27 @@ class TableRecap(tb.Table):
classes=col_classes + ["non_inscrit"], classes=col_classes + ["non_inscrit"],
) )
self.get_row_by_id("coef").row[col_id] = e.coefficient row_coef = self.get_row_by_id("coef")
self.get_row_by_id("min").row[col_id] = "0" row_coef.add_cell(
self.get_row_by_id("max").row[col_id] = self.fmt_note(e.note_max) col_id,
None,
self.fmt_note(e.coefficient),
group="eval",
)
row_min = self.get_row_by_id("min")
row_min.add_cell(
col_id,
None,
0,
group="eval",
)
row_max = self.get_row_by_id("max")
row_max.add_cell(
col_id,
None,
self.fmt_note(e.note_max),
group="eval",
)
row_descr_eval.add_cell( row_descr_eval.add_cell(
col_id, col_id,
None, None,
@ -570,10 +590,11 @@ class RowRecap(tb.Row):
classes=[note_class], classes=[note_class],
) )
# Ajoute bulle sur titre du pied de table: # Ajoute bulle sur titre du pied de table:
if res.is_apc: table.foot_title_row.cells["moy_gen"].target_attrs["title"] = (
table.foot_title_row.cells["moy_gen"].target_attrs[ "Moyenne générale indicative"
"title" if res.is_apc
] = "moyenne indicative" else "Moyenne générale du semestre"
)
# --- Moyenne d'UE # --- Moyenne d'UE
self.nb_ues_validables, self.nb_ues_warning = 0, 0 self.nb_ues_validables, self.nb_ues_warning = 0, 0
@ -584,7 +605,6 @@ class RowRecap(tb.Row):
if table.mode_jury: if table.mode_jury:
# pas d'autre colonnes de résultats # pas d'autre colonnes de résultats
continue continue
# Bonus (sport) dans cette UE ? # Bonus (sport) dans cette UE ?
# Le bonus sport appliqué sur cette UE # Le bonus sport appliqué sur cette UE
if (res.bonus_ues is not None) and (ue.id in res.bonus_ues): if (res.bonus_ues is not None) and (ue.id in res.bonus_ues):
@ -600,7 +620,7 @@ class RowRecap(tb.Row):
val_fmt_html, val_fmt_html,
raw_content=val_fmt, raw_content=val_fmt,
group=f"col_ue_{ue.id}", group=f"col_ue_{ue.id}",
column_classes={"col_ue_bonus"}, column_classes={"col_ue_bonus", "col_res"},
) )
# Les moyennes des modules (ou ressources et SAÉs) dans cette UE # Les moyennes des modules (ou ressources et SAÉs) dans cette UE
self.add_ue_modimpls_cols(ue, ue_status["is_capitalized"]) self.add_ue_modimpls_cols(ue, ue_status["is_capitalized"])
@ -629,7 +649,7 @@ class RowRecap(tb.Row):
data={"order": self.nb_ues_validables}, # tri data={"order": self.nb_ues_validables}, # tri
) )
def add_ue_cols(self, ue: UniteEns, ue_status: dict): 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 = self.table
@ -650,9 +670,9 @@ class RowRecap(tb.Row):
col_id, col_id,
ue.acronyme, ue.acronyme,
table.fmt_note(val), table.fmt_note(val),
group="col_ue", group=col_group or f"col_ue_{ue.id}",
classes=[note_class], classes=[note_class],
column_classes={f"col_ue_{ue.id}", "col_moy_ue"}, column_classes={f"col_ue_{ue.id}", "col_moy_ue", "col_ue"},
) )
table.foot_title_row.cells[col_id].target_attrs[ table.foot_title_row.cells[col_id].target_attrs[
"title" "title"