forked from ScoDoc/ScoDoc
145 lines
5.1 KiB
Python
145 lines
5.1 KiB
Python
|
##############################################################################
|
||
|
# ScoDoc
|
||
|
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||
|
# See LICENSE
|
||
|
##############################################################################
|
||
|
|
||
|
"""Tableau recap. de toutes les évaluations d'un semestre
|
||
|
avec leur état.
|
||
|
|
||
|
Sur une idée de Pascal Bouron, de Lyon.
|
||
|
"""
|
||
|
import time
|
||
|
from flask import g, url_for
|
||
|
|
||
|
from app.models import Evaluation, FormSemestre
|
||
|
from app.comp import res_sem
|
||
|
from app.comp.res_compat import NotesTableCompat
|
||
|
from app.comp.moy_mod import ModuleImplResults
|
||
|
from app.scodoc import html_sco_header
|
||
|
import app.scodoc.sco_utils as scu
|
||
|
|
||
|
|
||
|
def evaluations_recap(formsemestre_id: int) -> str:
|
||
|
"""Page récap. de toutes les évaluations d'un semestre"""
|
||
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||
|
rows, titles = evaluations_recap_table(formsemestre)
|
||
|
column_ids = titles.keys()
|
||
|
filename = scu.sanitize_filename(
|
||
|
f"""evaluations-{formsemestre.titre_num()}-{time.strftime("%Y-%m-%d")}"""
|
||
|
)
|
||
|
if not rows:
|
||
|
return '<div class="evaluations_recap"><div class="message">aucune évaluation</div></div>'
|
||
|
H = [
|
||
|
html_sco_header.sco_header(
|
||
|
page_title="Évaluations du semestre",
|
||
|
javascripts=["js/evaluations_recap.js"],
|
||
|
),
|
||
|
f"""<div class="evaluations_recap"><table class="evaluations_recap compact {
|
||
|
'apc' if formsemestre.formation.is_apc() else 'classic'
|
||
|
}"
|
||
|
data-filename="{filename}">""",
|
||
|
]
|
||
|
# header
|
||
|
H.append(
|
||
|
f"""
|
||
|
<thead>
|
||
|
{scu.gen_row(column_ids, titles, "th", with_col_classes=True)}
|
||
|
</thead>
|
||
|
"""
|
||
|
)
|
||
|
# body
|
||
|
H.append("<tbody>")
|
||
|
for row in rows:
|
||
|
H.append(f"{scu.gen_row(column_ids, row, with_col_classes=True)}\n")
|
||
|
|
||
|
H.append("""</tbody></table></div>""")
|
||
|
H.append(
|
||
|
html_sco_header.sco_footer(),
|
||
|
)
|
||
|
return "".join(H)
|
||
|
|
||
|
|
||
|
def evaluations_recap_table(formsemestre: FormSemestre) -> list[dict]:
|
||
|
"""Tableau recap. de toutes les évaluations d'un semestre
|
||
|
Colonnes:
|
||
|
- code (UE ou module),
|
||
|
- titre
|
||
|
- complete
|
||
|
- publiée
|
||
|
- inscrits (non dem. ni def.)
|
||
|
- nb notes manquantes
|
||
|
- nb ATT
|
||
|
- nb ABS
|
||
|
- nb EXC
|
||
|
"""
|
||
|
rows = []
|
||
|
titles = {
|
||
|
"type": "",
|
||
|
"code": "Code",
|
||
|
"titre": "",
|
||
|
"date": "Date",
|
||
|
"complete": "Comptée",
|
||
|
"inscrits": "Inscrits",
|
||
|
"manquantes": "Manquantes", # notes eval non entrées
|
||
|
"nb_abs": "ABS",
|
||
|
"nb_att": "ATT",
|
||
|
"nb_exc": "EXC",
|
||
|
}
|
||
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||
|
line_idx = 0
|
||
|
for modimpl in nt.formsemestre.modimpls_sorted:
|
||
|
modimpl_results: ModuleImplResults = nt.modimpls_results[modimpl.id]
|
||
|
row = {
|
||
|
"type": modimpl.module.type_abbrv().upper(),
|
||
|
"_type_order": f"{line_idx:04d}",
|
||
|
"code": modimpl.module.code,
|
||
|
"_code_target": url_for(
|
||
|
"notes.moduleimpl_status",
|
||
|
scodoc_dept=g.scodoc_dept,
|
||
|
moduleimpl_id=modimpl.id,
|
||
|
),
|
||
|
"titre": modimpl.module.titre,
|
||
|
"_titre_class": "titre",
|
||
|
"inscrits": modimpl_results.nb_inscrits_module,
|
||
|
"date": "-",
|
||
|
"_date_order": "",
|
||
|
"_tr_class": f"module {modimpl.module.type_abbrv()}",
|
||
|
}
|
||
|
rows.append(row)
|
||
|
line_idx += 1
|
||
|
for evaluation_id in modimpl_results.evals_notes:
|
||
|
e = Evaluation.query.get(evaluation_id)
|
||
|
eval_etat = modimpl_results.evaluations_etat[evaluation_id]
|
||
|
row = {
|
||
|
"type": "",
|
||
|
"_type_order": f"{line_idx:04d}",
|
||
|
"titre": e.description or "sans titre",
|
||
|
"_titre_target": url_for(
|
||
|
"notes.evaluation_listenotes",
|
||
|
scodoc_dept=g.scodoc_dept,
|
||
|
evaluation_id=evaluation_id,
|
||
|
),
|
||
|
"_titre_target_attrs": 'class="discretelink"',
|
||
|
"date": e.jour.strftime("%d/%m/%Y") if e.jour else "",
|
||
|
"_date_order": e.jour.isoformat() if e.jour else "",
|
||
|
"complete": "oui" if eval_etat.is_complete else "non",
|
||
|
"_complete_target": "#",
|
||
|
"_complete_target_attrs": 'class="bull_link" title="prise en compte dans les moyennes"'
|
||
|
if eval_etat.is_complete
|
||
|
else 'class="bull_link incomplete" title="il manque des notes"',
|
||
|
"manquantes": len(modimpl_results.evals_etudids_sans_note[e.id]),
|
||
|
"inscrits": modimpl_results.nb_inscrits_module,
|
||
|
"nb_abs": sum(modimpl_results.evals_notes[e.id] == scu.NOTES_ABSENCE),
|
||
|
"nb_att": eval_etat.nb_attente,
|
||
|
"nb_exc": sum(
|
||
|
modimpl_results.evals_notes[e.id] == scu.NOTES_NEUTRALISE
|
||
|
),
|
||
|
"_tr_class": "evaluation"
|
||
|
+ (" incomplete" if not eval_etat.is_complete else ""),
|
||
|
}
|
||
|
rows.append(row)
|
||
|
line_idx += 1
|
||
|
|
||
|
return rows, titles
|