forked from ScoDoc/ScoDoc
Test unitaire superficiel de (presque) toutes les vues du tableau de bord semestre
This commit is contained in:
parent
4c7c6e1be0
commit
7ed20a8f8c
@ -257,6 +257,11 @@ class FormSemestre(db.Model):
|
|||||||
d["etapes_apo_str"] = self.etapes_apo_str()
|
d["etapes_apo_str"] = self.etapes_apo_str()
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def flip_lock(self):
|
||||||
|
"""Flip etat (lock)"""
|
||||||
|
self.etat = not self.etat
|
||||||
|
db.session.add(self)
|
||||||
|
|
||||||
def get_parcours_apc(self) -> list[ApcParcours]:
|
def get_parcours_apc(self) -> list[ApcParcours]:
|
||||||
"""Liste des parcours proposés par ce semestre.
|
"""Liste des parcours proposés par ce semestre.
|
||||||
Si aucun n'est coché et qu'il y a un référentiel, tous ceux du référentiel.
|
Si aucun n'est coché et qu'il y a un référentiel, tous ceux du référentiel.
|
||||||
|
@ -908,7 +908,8 @@ def formsemestre_bulletinetud(
|
|||||||
)[0]
|
)[0]
|
||||||
if format not in {"html", "pdfmail"}:
|
if format not in {"html", "pdfmail"}:
|
||||||
filename = scu.bul_filename(formsemestre, etud, format)
|
filename = scu.bul_filename(formsemestre, etud, format)
|
||||||
return scu.send_file(bulletin, filename, mime=scu.get_mime_suffix(format)[0])
|
mime, suffix = scu.get_mime_suffix(format)
|
||||||
|
return scu.send_file(bulletin, filename, mime=mime, suffix=suffix)
|
||||||
elif format == "pdfmail":
|
elif format == "pdfmail":
|
||||||
return ""
|
return ""
|
||||||
H = [
|
H = [
|
||||||
|
@ -32,12 +32,12 @@
|
|||||||
"""
|
"""
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
from app.models import FormSemestre
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_moduleimpl
|
from app.scodoc import sco_moduleimpl
|
||||||
from app.scodoc import sco_formsemestre_status
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
import app.scodoc.sco_utils as scu
|
||||||
import sco_version
|
import sco_version
|
||||||
|
|
||||||
|
|
||||||
@ -57,37 +57,35 @@ def formsemestre_table_estim_cost(
|
|||||||
peut conduire à une sur-estimation du coût s'il y a des modules optionnels
|
peut conduire à une sur-estimation du coût s'il y a des modules optionnels
|
||||||
(dans ce cas, retoucher le tableau excel exporté).
|
(dans ce cas, retoucher le tableau excel exporté).
|
||||||
"""
|
"""
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
sco_formsemestre_status.fill_formsemestre(sem)
|
|
||||||
Mlist = sco_moduleimpl.moduleimpl_withmodule_list(formsemestre_id=formsemestre_id)
|
rows = []
|
||||||
T = []
|
for modimpl in formsemestre.modimpls:
|
||||||
for M in Mlist:
|
rows.append(
|
||||||
Mod = M["module"]
|
|
||||||
T.append(
|
|
||||||
{
|
{
|
||||||
"code": Mod["code"] or "",
|
"code": modimpl.module.code or "",
|
||||||
"titre": Mod["titre"],
|
"titre": modimpl.module.titre,
|
||||||
"heures_cours": Mod["heures_cours"],
|
"heures_cours": modimpl.module.heures_cours,
|
||||||
"heures_td": Mod["heures_td"] * n_group_td,
|
"heures_td": modimpl.module.heures_td * n_group_td,
|
||||||
"heures_tp": Mod["heures_tp"] * n_group_tp,
|
"heures_tp": modimpl.module.heures_tp * n_group_tp,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# calcul des heures:
|
# calcul des heures:
|
||||||
for t in T:
|
for t in rows:
|
||||||
t["HeqTD"] = (
|
t["HeqTD"] = (
|
||||||
t["heures_td"] + coef_cours * t["heures_cours"] + coef_tp * t["heures_tp"]
|
t["heures_td"] + coef_cours * t["heures_cours"] + coef_tp * t["heures_tp"]
|
||||||
)
|
)
|
||||||
sum_cours = sum([t["heures_cours"] for t in T])
|
sum_cours = sum([t["heures_cours"] for t in rows])
|
||||||
sum_td = sum([t["heures_td"] for t in T])
|
sum_td = sum([t["heures_td"] for t in rows])
|
||||||
sum_tp = sum([t["heures_tp"] for t in T])
|
sum_tp = sum([t["heures_tp"] for t in rows])
|
||||||
sum_heqtd = sum_td + coef_cours * sum_cours + coef_tp * sum_tp
|
sum_heqtd = sum_td + coef_cours * sum_cours + coef_tp * sum_tp
|
||||||
assert abs(sum([t["HeqTD"] for t in T]) - sum_heqtd) < 0.01, "%s != %s" % (
|
assert abs(sum([t["HeqTD"] for t in rows]) - sum_heqtd) < 0.01, "%s != %s" % (
|
||||||
sum([t["HeqTD"] for t in T]),
|
sum([t["HeqTD"] for t in rows]),
|
||||||
sum_heqtd,
|
sum_heqtd,
|
||||||
)
|
)
|
||||||
|
|
||||||
T.append(
|
rows.append(
|
||||||
{
|
{
|
||||||
"code": "TOTAL SEMESTRE",
|
"code": "TOTAL SEMESTRE",
|
||||||
"heures_cours": sum_cours,
|
"heures_cours": sum_cours,
|
||||||
@ -117,13 +115,15 @@ def formsemestre_table_estim_cost(
|
|||||||
"heures_tp",
|
"heures_tp",
|
||||||
"HeqTD",
|
"HeqTD",
|
||||||
),
|
),
|
||||||
rows=T,
|
rows=rows,
|
||||||
html_sortable=True,
|
html_sortable=True,
|
||||||
preferences=sco_preferences.SemPreferences(formsemestre_id),
|
preferences=sco_preferences.SemPreferences(formsemestre_id),
|
||||||
html_class="table_leftalign table_listegroupe",
|
html_class="table_leftalign table_listegroupe",
|
||||||
xls_before_table=[
|
xls_before_table=[
|
||||||
["%(titre)s %(num_sem)s %(modalitestr)s" % sem],
|
[formsemestre.titre_annee()],
|
||||||
["Formation %(titre)s version %(version)s" % sem["formation"]],
|
[
|
||||||
|
f"Formation {formsemestre.formation.titre} version {formsemestre.formation.version}"
|
||||||
|
],
|
||||||
[],
|
[],
|
||||||
["", "TD", "TP"],
|
["", "TD", "TP"],
|
||||||
["Nombre de groupes", n_group_td, n_group_tp],
|
["Nombre de groupes", n_group_td, n_group_tp],
|
||||||
@ -140,10 +140,8 @@ def formsemestre_table_estim_cost(
|
|||||||
(dans ce cas, retoucher le tableau excel exporté).
|
(dans ce cas, retoucher le tableau excel exporté).
|
||||||
</div>
|
</div>
|
||||||
""",
|
""",
|
||||||
origin="Généré par %s le " % sco_version.SCONAME
|
origin=f"""Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}""",
|
||||||
+ scu.timedate_human_repr()
|
filename=f"EstimCout-S{formsemestre.semestre_id}",
|
||||||
+ "",
|
|
||||||
filename="EstimCout-S%s" % sem["semestre_id"],
|
|
||||||
)
|
)
|
||||||
return tab
|
return tab
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@ def formation_list_table() -> GenTable:
|
|||||||
)
|
)
|
||||||
+ f""", <a class="stdlink" id="add-semestre-{
|
+ f""", <a class="stdlink" id="add-semestre-{
|
||||||
formation.acronyme.lower().replace(" ", "-")}"
|
formation.acronyme.lower().replace(" ", "-")}"
|
||||||
href={ url_for("notes.formsemestre_createwithmodules",
|
href="{ url_for("notes.formsemestre_createwithmodules",
|
||||||
scodoc_dept=g.scodoc_dept, formation_id=formation.id, semestre_id=1
|
scodoc_dept=g.scodoc_dept, formation_id=formation.id, semestre_id=1
|
||||||
)
|
)
|
||||||
}">ajouter</a>
|
}">ajouter</a>
|
||||||
|
@ -1659,20 +1659,6 @@ def formsemestre_edit_options(formsemestre_id):
|
|||||||
return sco_preferences.SemPreferences(formsemestre_id).edit(categories=["bul"])
|
return sco_preferences.SemPreferences(formsemestre_id).edit(categories=["bul"])
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_change_lock(formsemestre_id) -> None:
|
|
||||||
"""Change etat (verrouille si ouvert, déverrouille si fermé)
|
|
||||||
nota: etat (1 ouvert, 0 fermé)
|
|
||||||
"""
|
|
||||||
ok, err = sco_permissions_check.check_access_diretud(formsemestre_id)
|
|
||||||
if not ok:
|
|
||||||
return err
|
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
|
||||||
etat = not sem["etat"]
|
|
||||||
|
|
||||||
args = {"formsemestre_id": formsemestre_id, "etat": etat}
|
|
||||||
sco_formsemestre.do_formsemestre_edit(args)
|
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_change_publication_bul(
|
def formsemestre_change_publication_bul(
|
||||||
formsemestre_id, dialog_confirmed=False, redirect=True
|
formsemestre_id, dialog_confirmed=False, redirect=True
|
||||||
):
|
):
|
||||||
|
@ -200,7 +200,7 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": change_lock_msg,
|
"title": change_lock_msg,
|
||||||
"endpoint": "notes.formsemestre_change_lock",
|
"endpoint": "notes.formsemestre_flip_lock",
|
||||||
"args": {"formsemestre_id": formsemestre_id},
|
"args": {"formsemestre_id": formsemestre_id},
|
||||||
"enabled": has_perm_change_sem,
|
"enabled": has_perm_change_sem,
|
||||||
"helpmsg": "",
|
"helpmsg": "",
|
||||||
@ -546,59 +546,6 @@ def formsemestre_page_title(formsemestre_id=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def fill_formsemestre(sem):
|
|
||||||
"""Add some useful fields to help display formsemestres"""
|
|
||||||
sem["notes_url"] = scu.NotesURL()
|
|
||||||
formsemestre_id = sem["formsemestre_id"]
|
|
||||||
if not sem["etat"]:
|
|
||||||
sem[
|
|
||||||
"locklink"
|
|
||||||
] = f"""<a href="{url_for('notes.formsemestre_change_lock',
|
|
||||||
scodoc_dept=g.scodoc_dept,formsemestre_id=formsemestre_id )
|
|
||||||
}">{scu.icontag("lock_img", border="0", title="Semestre verrouillé")}</a>"""
|
|
||||||
else:
|
|
||||||
sem["locklink"] = ""
|
|
||||||
if sco_preferences.get_preference("bul_display_publication", formsemestre_id):
|
|
||||||
if sem["bul_hide_xml"]:
|
|
||||||
eyeicon = scu.icontag("hide_img", border="0", title="Bulletins NON publiés")
|
|
||||||
else:
|
|
||||||
eyeicon = scu.icontag("eye_img", border="0", title="Bulletins publiés")
|
|
||||||
sem[
|
|
||||||
"eyelink"
|
|
||||||
] = f"""<a href="{
|
|
||||||
url_for('notes.formsemestre_change_publication_bul',
|
|
||||||
scodoc_dept=g.scodoc_dept,formsemestre_id=formsemestre_id)
|
|
||||||
}">{eyeicon}</a>"""
|
|
||||||
else:
|
|
||||||
sem["eyelink"] = ""
|
|
||||||
sem["formation"] = Formation.query.get_or_404(sem["formation_id"]).to_dict(
|
|
||||||
with_departement=False
|
|
||||||
)
|
|
||||||
parcours = codes_cursus.get_cursus_from_code(F["type_parcours"])
|
|
||||||
if sem["semestre_id"] != -1:
|
|
||||||
sem["num_sem"] = f""", {parcours.SESSION_NAME} {sem["semestre_id"]}"""
|
|
||||||
else:
|
|
||||||
sem["num_sem"] = "" # formation sans semestres
|
|
||||||
if sem["modalite"]:
|
|
||||||
sem["modalitestr"] = f""" en {sem["modalite"]}"""
|
|
||||||
else:
|
|
||||||
sem["modalitestr"] = ""
|
|
||||||
|
|
||||||
sem["etape_apo_str"] = "Code étape Apogée: " + (
|
|
||||||
sco_formsemestre.formsemestre_etape_apo_str(sem) or "Pas de code étape"
|
|
||||||
)
|
|
||||||
|
|
||||||
inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
|
||||||
args={"formsemestre_id": formsemestre_id}
|
|
||||||
)
|
|
||||||
sem["nbinscrits"] = len(inscrits)
|
|
||||||
uresps = [
|
|
||||||
sco_users.user_info(responsable_id) for responsable_id in sem["responsables"]
|
|
||||||
]
|
|
||||||
sem["resp"] = ", ".join([u["prenomnom"] for u in uresps])
|
|
||||||
sem["nomcomplet"] = ", ".join([u["nomcomplet"] for u in uresps])
|
|
||||||
|
|
||||||
|
|
||||||
# Description du semestre sous forme de table exportable
|
# Description du semestre sous forme de table exportable
|
||||||
def formsemestre_description_table(
|
def formsemestre_description_table(
|
||||||
formsemestre_id: int, with_evals=False, with_parcours=False
|
formsemestre_id: int, with_evals=False, with_parcours=False
|
||||||
@ -645,7 +592,7 @@ def formsemestre_description_table(
|
|||||||
titles["publish_incomplete_str"] = "Toujours utilisée"
|
titles["publish_incomplete_str"] = "Toujours utilisée"
|
||||||
title = f"{parcours.SESSION_NAME.capitalize()} {formsemestre.titre_mois()}"
|
title = f"{parcours.SESSION_NAME.capitalize()} {formsemestre.titre_mois()}"
|
||||||
|
|
||||||
R = []
|
rows = []
|
||||||
sum_coef = 0
|
sum_coef = 0
|
||||||
sum_ects = 0
|
sum_ects = 0
|
||||||
last_ue_id = None
|
last_ue_id = None
|
||||||
@ -671,7 +618,7 @@ def formsemestre_description_table(
|
|||||||
if use_ue_coefs:
|
if use_ue_coefs:
|
||||||
ue_info["Coef."] = ue.coefficient
|
ue_info["Coef."] = ue.coefficient
|
||||||
ue_info["Coef._class"] = "ue_coef"
|
ue_info["Coef._class"] = "ue_coef"
|
||||||
R.append(ue_info)
|
rows.append(ue_info)
|
||||||
|
|
||||||
mod_inscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
|
mod_inscrits = sco_moduleimpl.do_moduleimpl_inscription_list(
|
||||||
moduleimpl_id=modimpl.id
|
moduleimpl_id=modimpl.id
|
||||||
@ -713,14 +660,15 @@ def formsemestre_description_table(
|
|||||||
sorted([pa.code for pa in modimpl.module.parcours])
|
sorted([pa.code for pa in modimpl.module.parcours])
|
||||||
)
|
)
|
||||||
|
|
||||||
R.append(l)
|
rows.append(l)
|
||||||
|
|
||||||
if with_evals:
|
if with_evals:
|
||||||
# Ajoute lignes pour evaluations
|
# Ajoute lignes pour evaluations
|
||||||
evals = nt.get_mod_evaluation_etat_list(modimpl.id)
|
evals = nt.get_mod_evaluation_etat_list(modimpl.id)
|
||||||
evals.reverse() # ordre chronologique
|
evals.reverse() # ordre chronologique
|
||||||
# Ajoute etat:
|
# Ajoute etat:
|
||||||
for e in evals:
|
for eval_dict in evals:
|
||||||
|
e = eval_dict.copy()
|
||||||
e["_jour_order"] = e["jour"].isoformat()
|
e["_jour_order"] = e["jour"].isoformat()
|
||||||
e["jour"] = e["jour"].strftime("%d/%m/%Y") if e["jour"] else ""
|
e["jour"] = e["jour"].strftime("%d/%m/%Y") if e["jour"] else ""
|
||||||
e["UE"] = l["UE"]
|
e["UE"] = l["UE"]
|
||||||
@ -749,14 +697,14 @@ def formsemestre_description_table(
|
|||||||
e[f"_ue_{ue_id}_class"] = "poids"
|
e[f"_ue_{ue_id}_class"] = "poids"
|
||||||
e[f"_ue_{ue_id}_help"] = "poids vers l'UE"
|
e[f"_ue_{ue_id}_help"] = "poids vers l'UE"
|
||||||
|
|
||||||
R += evals
|
rows += evals
|
||||||
|
|
||||||
sums = {"_css_row_class": "moyenne sortbottom", "ects": sum_ects, "Coef.": sum_coef}
|
sums = {"_css_row_class": "moyenne sortbottom", "ects": sum_ects, "Coef.": sum_coef}
|
||||||
R.append(sums)
|
rows.append(sums)
|
||||||
|
|
||||||
return GenTable(
|
return GenTable(
|
||||||
columns_ids=columns_ids,
|
columns_ids=columns_ids,
|
||||||
rows=R,
|
rows=rows,
|
||||||
titles=titles,
|
titles=titles,
|
||||||
origin=f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}",
|
origin=f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}",
|
||||||
caption=title,
|
caption=title,
|
||||||
|
@ -294,9 +294,8 @@ def _formsemestre_recapcomplet_to_file(
|
|||||||
include_evaluations=include_evaluations,
|
include_evaluations=include_evaluations,
|
||||||
filename=filename,
|
filename=filename,
|
||||||
)
|
)
|
||||||
return scu.send_file(
|
mime, suffix = scu.get_mime_suffix(tabformat)
|
||||||
data, filename=filename, mime=scu.get_mime_suffix(tabformat)
|
return scu.send_file(data, filename=filename, mime=mime, suffix=suffix)
|
||||||
)
|
|
||||||
elif tabformat == "xml":
|
elif tabformat == "xml":
|
||||||
data = gen_formsemestre_recapcomplet_xml(
|
data = gen_formsemestre_recapcomplet_xml(
|
||||||
formsemestre.id,
|
formsemestre.id,
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
table.dataTable {
|
table.dataTable {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
margin-left: 0px;
|
||||||
clear: both;
|
clear: both;
|
||||||
border-collapse: separate;
|
border-collapse: separate;
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
@ -643,10 +644,12 @@ table.dataTable.order-column.stripe.hover tbody tr.even:hover td.sorting_1 {
|
|||||||
/* Reglage largeur de la table */
|
/* Reglage largeur de la table */
|
||||||
table.dataTable.gt_table {
|
table.dataTable.gt_table {
|
||||||
width: auto;
|
width: auto;
|
||||||
|
margin-left: 32px;
|
||||||
|
margin-top: 8px;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tables non centrées */
|
/* Tables non centrées (inutile) */
|
||||||
table.dataTable.gt_table.gt_left {
|
table.dataTable.gt_table.gt_left {
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
}
|
}
|
@ -2069,9 +2069,11 @@ table#formation_list_table tr.gt_hl {
|
|||||||
table.formation_list_table td.buttons {
|
table.formation_list_table td.buttons {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.formation_list_table td.buttons a {
|
table.formation_list_table td.buttons a {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.formation_list_table td.buttons span.but_placeholder {
|
table.formation_list_table td.buttons span.but_placeholder {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 15px;
|
width: 15px;
|
||||||
@ -4036,7 +4038,8 @@ div.table_recap {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
div.table_recap table.table_recap {
|
div.table_recap table.table_recap,
|
||||||
|
div.evaluations_recap table.evaluations_recap {
|
||||||
width: auto;
|
width: auto;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
/* font-family: Consolas, monaco, monospace; */
|
/* font-family: Consolas, monaco, monospace; */
|
||||||
@ -4230,6 +4233,7 @@ table.table_recap th.col_res {
|
|||||||
border-right: 1px dashed green;
|
border-right: 1px dashed green;
|
||||||
border-left: 1px dashed green;
|
border-left: 1px dashed green;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.table_recap td.abs,
|
table.table_recap td.abs,
|
||||||
table.table_recap th.abs {
|
table.table_recap th.abs {
|
||||||
color: rgb(80, 0, 0);
|
color: rgb(80, 0, 0);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
title="{{sco.sem.responsables_str(abbrev_prenom=False)}}">{{sco.sem.responsables_str()}}</a></span>
|
title="{{sco.sem.responsables_str(abbrev_prenom=False)}}">{{sco.sem.responsables_str()}}</a></span>
|
||||||
<span class="nbinscrits"><a class="discretelink" href="{{url_for('scolar.groups_view', scodoc_dept=g.scodoc_dept,
|
<span class="nbinscrits"><a class="discretelink" href="{{url_for('scolar.groups_view', scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=sco.sem.id)}}">{{sco.sem.inscriptions|length}} inscrits</a></span><span class="lock">{% if
|
formsemestre_id=sco.sem.id)}}">{{sco.sem.inscriptions|length}} inscrits</a></span><span class="lock">{% if
|
||||||
not sco.sem.etat %}<a href="{{url_for('notes.formsemestre_change_lock', scodoc_dept=g.scodoc_dept,
|
not sco.sem.etat %}<a href="{{url_for('notes.formsemestre_flip_lock', scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=sco.sem.id)}}">{{sco.scu.icontag("lock_img", border="0", title="Semestre
|
formsemestre_id=sco.sem.id)}}">{{sco.scu.icontag("lock_img", border="0", title="Semestre
|
||||||
verrouillé")|safe}}</a>{% endif %}</span><span class="eye">
|
verrouillé")|safe}}</a>{% endif %}</span><span class="eye">
|
||||||
{% if sco.prefs["bul_display_publication"] %}
|
{% if sco.prefs["bul_display_publication"] %}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)
|
||||||
}}">{{formsemestre.etuds_inscriptions|length}} inscrits</a></span><span class="lock">
|
}}">{{formsemestre.etuds_inscriptions|length}} inscrits</a></span><span class="lock">
|
||||||
{%-if not formsemestre.etat -%}
|
{%-if not formsemestre.etat -%}
|
||||||
<a href="{{ url_for( 'notes.formsemestre_change_lock',
|
<a href="{{ url_for( 'notes.formsemestre_flip_lock',
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id )}}">{{
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id )}}">{{
|
||||||
scu.icontag("lock_img", border="0", title="Semestre verrouillé")|safe
|
scu.icontag("lock_img", border="0", title="Semestre verrouillé")|safe
|
||||||
}}</a>
|
}}</a>
|
||||||
|
@ -820,20 +820,22 @@ sco_publish(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre_change_lock", methods=["GET", "POST"])
|
@bp.route("/formsemestre_flip_lock", methods=["GET", "POST"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView) # acces vérifié dans la fonction
|
@permission_required(Permission.ScoView) # acces vérifié dans la vue
|
||||||
@scodoc7func
|
@scodoc7func
|
||||||
def formsemestre_change_lock(formsemestre_id, dialog_confirmed=False):
|
def formsemestre_flip_lock(formsemestre_id, dialog_confirmed=False):
|
||||||
"Changement de l'état de verrouillage du semestre"
|
"Changement de l'état de verrouillage du semestre"
|
||||||
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
|
dest_url = url_for(
|
||||||
|
"notes.formsemestre_status",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre.id,
|
||||||
|
)
|
||||||
|
if not formsemestre.est_chef_or_diretud():
|
||||||
|
raise ScoPermissionDenied("opération non autorisée", dest_url=dest_url)
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
msg = "verrouillage" if formsemestre.etat else "déverrouillage"
|
||||||
etat = not sem["etat"]
|
|
||||||
if etat:
|
|
||||||
msg = "déverrouillage"
|
|
||||||
else:
|
|
||||||
msg = "verrouillage"
|
|
||||||
return scu.confirm_dialog(
|
return scu.confirm_dialog(
|
||||||
f"<h2>Confirmer le {msg} du semestre ?</h2>",
|
f"<h2>Confirmer le {msg} du semestre ?</h2>",
|
||||||
helpmsg="""Les notes d'un semestre verrouillé ne peuvent plus être modifiées.
|
helpmsg="""Les notes d'un semestre verrouillé ne peuvent plus être modifiées.
|
||||||
@ -843,23 +845,14 @@ def formsemestre_change_lock(formsemestre_id, dialog_confirmed=False):
|
|||||||
Le programme d'une formation qui a un semestre verrouillé ne peut plus être modifié.
|
Le programme d'une formation qui a un semestre verrouillé ne peut plus être modifié.
|
||||||
""",
|
""",
|
||||||
dest_url="",
|
dest_url="",
|
||||||
cancel_url=url_for(
|
cancel_url=dest_url,
|
||||||
"notes.formsemestre_status",
|
|
||||||
scodoc_dept=g.scodoc_dept,
|
|
||||||
formsemestre_id=formsemestre_id,
|
|
||||||
),
|
|
||||||
parameters={"formsemestre_id": formsemestre_id},
|
parameters={"formsemestre_id": formsemestre_id},
|
||||||
)
|
)
|
||||||
|
|
||||||
sco_formsemestre_edit.formsemestre_change_lock(formsemestre_id)
|
formsemestre.flip_lock()
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
return flask.redirect(
|
return flask.redirect(dest_url)
|
||||||
url_for(
|
|
||||||
"notes.formsemestre_status",
|
|
||||||
scodoc_dept=g.scodoc_dept,
|
|
||||||
formsemestre_id=formsemestre_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
sco_publish(
|
sco_publish(
|
||||||
|
@ -1 +1,17 @@
|
|||||||
# Unit tests
|
# ScoDoc Unit Tests
|
||||||
|
|
||||||
|
"""Set of unit tests for ScoDoc
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def call_view(view_function, *args, **kwargs):
|
||||||
|
"""Undecorate a view and call it directly."""
|
||||||
|
# On a 3 décorateurs: @scodoc, @permission_required, @scodoc7func
|
||||||
|
func = (
|
||||||
|
view_function.__closure__[0]
|
||||||
|
.cell_contents.__closure__[0]
|
||||||
|
.cell_contents.__closure__[0]
|
||||||
|
.cell_contents
|
||||||
|
)
|
||||||
|
assert func
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
@ -42,7 +42,7 @@ def test_but_jury_GB(test_client):
|
|||||||
app.set_sco_dept(DEPT)
|
app.set_sco_dept(DEPT)
|
||||||
# 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_gb.yaml")
|
doc = yaml_setup.setup_from_yaml("tests/ressources/yaml/cursus_but_gb.yaml")
|
||||||
|
|
||||||
# Vérifie les deca de tous les semestres:
|
# Vérifie les deca de tous les semestres:
|
||||||
for formsemestre in FormSemestre.query:
|
for formsemestre in FormSemestre.query:
|
||||||
@ -69,7 +69,7 @@ def test_but_jury_GMP_lm(test_client):
|
|||||||
app.set_sco_dept(DEPT)
|
app.set_sco_dept(DEPT)
|
||||||
# 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_gmp_iutlm.yaml")
|
doc = yaml_setup.setup_from_yaml("tests/ressources/yaml/cursus_but_gmp_iutlm.yaml")
|
||||||
|
|
||||||
formsemestres = FormSemestre.query.order_by(
|
formsemestres = FormSemestre.query.order_by(
|
||||||
FormSemestre.date_debut, FormSemestre.semestre_id
|
FormSemestre.date_debut, FormSemestre.semestre_id
|
||||||
@ -95,7 +95,7 @@ def test_but_jury_GEII_lyon(test_client):
|
|||||||
app.set_sco_dept(DEPT)
|
app.set_sco_dept(DEPT)
|
||||||
# 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/ressources/yaml/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()
|
||||||
|
@ -3,12 +3,37 @@
|
|||||||
|
|
||||||
""" Test création/accès/clonage formsemestre
|
""" Test création/accès/clonage formsemestre
|
||||||
"""
|
"""
|
||||||
|
from flask import Response
|
||||||
import pytest
|
import pytest
|
||||||
from tests.unit import yaml_setup
|
from tests.unit import yaml_setup, call_view
|
||||||
|
|
||||||
import app
|
import app
|
||||||
from app.models import Formation
|
from app import db
|
||||||
from app.scodoc import sco_formsemestre_edit
|
from app.models import Formation, FormSemestre
|
||||||
|
from app.scodoc import (
|
||||||
|
sco_archives,
|
||||||
|
sco_cost_formation,
|
||||||
|
sco_debouche,
|
||||||
|
sco_edit_ue,
|
||||||
|
sco_evaluations,
|
||||||
|
sco_evaluation_check_abs,
|
||||||
|
sco_evaluation_recap,
|
||||||
|
sco_formsemestre_edit,
|
||||||
|
sco_formsemestre_inscriptions,
|
||||||
|
sco_formsemestre_status,
|
||||||
|
sco_groups,
|
||||||
|
sco_inscr_passage,
|
||||||
|
sco_lycee,
|
||||||
|
sco_moduleimpl_inscriptions,
|
||||||
|
sco_poursuite_dut,
|
||||||
|
sco_preferences,
|
||||||
|
sco_recapcomplet,
|
||||||
|
sco_report,
|
||||||
|
sco_undo_notes,
|
||||||
|
)
|
||||||
|
|
||||||
|
from app.scodoc import sco_utils as scu
|
||||||
|
from app.views import notes, scolar
|
||||||
from config import TestConfig
|
from config import TestConfig
|
||||||
|
|
||||||
DEPT = TestConfig.DEPT_TEST
|
DEPT = TestConfig.DEPT_TEST
|
||||||
@ -34,3 +59,128 @@ def test_formsemestres_associate_new_version(test_client):
|
|||||||
assert new_formation
|
assert new_formation
|
||||||
assert formsemestres[0].formation_id == new_formation.id
|
assert formsemestres[0].formation_id == new_formation.id
|
||||||
assert formsemestres[1].formation_id == new_formation.id
|
assert formsemestres[1].formation_id == new_formation.id
|
||||||
|
|
||||||
|
|
||||||
|
def test_formsemestre_misc_views(test_client):
|
||||||
|
"""Test de nombreuses vues: test juste que la page ne plante,
|
||||||
|
pas de vérif du contenu ni de soumission si c'est un formulaire.
|
||||||
|
|
||||||
|
Note: les anciennes vues renvoient souvent des str au lieu de Response.
|
||||||
|
"""
|
||||||
|
app.set_sco_dept(DEPT)
|
||||||
|
yaml_setup.setup_from_yaml("tests/ressources/yaml/simple_formsemestres.yaml")
|
||||||
|
formsemestre: FormSemestre = FormSemestre.query.first()
|
||||||
|
|
||||||
|
# ----- MENU SEMESTRE
|
||||||
|
_ = sco_formsemestre_status.formsemestre_status(formsemestre_id=formsemestre.id)
|
||||||
|
_ = sco_edit_ue.ue_table(formsemestre.formation_id)
|
||||||
|
_ = sco_formsemestre_edit.formsemestre_editwithmodules(formsemestre.id)
|
||||||
|
_ = sco_preferences.SemPreferences(formsemestre_id=formsemestre.id).edit()
|
||||||
|
_ = sco_formsemestre_edit.formsemestre_edit_options(formsemestre.id)
|
||||||
|
assert formsemestre.etat
|
||||||
|
formsemestre.flip_lock()
|
||||||
|
assert not formsemestre.etat
|
||||||
|
formsemestre.flip_lock()
|
||||||
|
assert formsemestre.etat
|
||||||
|
ans = sco_formsemestre_status.formsemestre_description(
|
||||||
|
formsemestre.id, with_evals=True
|
||||||
|
)
|
||||||
|
assert isinstance(ans, (str, Response)) # ici c'est une str
|
||||||
|
ans = sco_formsemestre_status.formsemestre_description(
|
||||||
|
formsemestre.id, with_evals=True, format="xls"
|
||||||
|
)
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.XLSX_MIMETYPE
|
||||||
|
ans = sco_formsemestre_status.formsemestre_description(
|
||||||
|
formsemestre.id, with_evals=True, format="pdf"
|
||||||
|
)
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.PDF_MIMETYPE
|
||||||
|
ans = sco_evaluation_check_abs.formsemestre_check_absences_html(formsemestre.id)
|
||||||
|
assert isinstance(ans, (str, Response))
|
||||||
|
# Appel direct de la vue: enlève les décorateurs:
|
||||||
|
ans = call_view(notes.formsemestre_enseignants_list, formsemestre.id)
|
||||||
|
assert isinstance(ans, (str, Response)) # ici str
|
||||||
|
# Juste la page dialogue avant opération::
|
||||||
|
ans = sco_formsemestre_edit.formsemestre_clone(formsemestre.id)
|
||||||
|
ans = sco_formsemestre_edit.formsemestre_associate_new_version(formsemestre.id)
|
||||||
|
ans = sco_formsemestre_edit.formsemestre_delete(formsemestre.id)
|
||||||
|
|
||||||
|
# ----- MENU INSCRIPTIONS
|
||||||
|
ans = sco_moduleimpl_inscriptions.moduleimpl_inscriptions_stats(formsemestre.id)
|
||||||
|
ans = sco_inscr_passage.formsemestre_inscr_passage(formsemestre.id)
|
||||||
|
ans = call_view(scolar.form_students_import_excel, formsemestre.id)
|
||||||
|
assert isinstance(ans, str)
|
||||||
|
ans = call_view(scolar.form_students_import_infos_admissions, formsemestre.id)
|
||||||
|
ans = sco_formsemestre_inscriptions.formsemestre_inscrits_ailleurs(formsemestre.id)
|
||||||
|
|
||||||
|
# ----- MENU GROUPES
|
||||||
|
ans = call_view(scolar.groups_view, formsemestre.id)
|
||||||
|
ans = call_view(scolar.partition_editor, formsemestre.id)
|
||||||
|
ans = sco_groups.edit_partition_form(formsemestre.id)
|
||||||
|
|
||||||
|
# ----- MENU NOTES
|
||||||
|
ans = sco_recapcomplet.formsemestre_recapcomplet(formsemestre.id)
|
||||||
|
ans = sco_recapcomplet.formsemestre_recapcomplet(formsemestre.id, tabformat="evals")
|
||||||
|
ans = sco_recapcomplet.formsemestre_recapcomplet(formsemestre.id, tabformat="xlsx")
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.XLSX_MIMETYPE
|
||||||
|
ans = sco_recapcomplet.formsemestre_recapcomplet(formsemestre.id, tabformat="json")
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.JSON_MIMETYPE
|
||||||
|
ans = sco_evaluation_recap.evaluations_recap(formsemestre.id)
|
||||||
|
|
||||||
|
# Bulletins pdf:
|
||||||
|
ans = call_view(notes.formsemestre_bulletins_pdf_choice, formsemestre.id)
|
||||||
|
assert isinstance(ans, str) # sans version, on a le formulaire de choix, une str
|
||||||
|
ans = call_view(
|
||||||
|
notes.formsemestre_bulletins_pdf_choice, formsemestre.id, version="long"
|
||||||
|
)
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.PDF_MIMETYPE
|
||||||
|
# on ne teste pas les mails :)
|
||||||
|
ans = sco_evaluations.formsemestre_evaluations_cal(formsemestre.id)
|
||||||
|
assert isinstance(ans, str)
|
||||||
|
sco_undo_notes.formsemestre_list_saisies_notes(formsemestre.id)
|
||||||
|
|
||||||
|
# ----- MENU JURY
|
||||||
|
ans = sco_recapcomplet.formsemestre_recapcomplet(formsemestre.id, mode_jury=True)
|
||||||
|
ans = sco_recapcomplet.formsemestre_recapcomplet(
|
||||||
|
formsemestre.id, mode_jury=True, tabformat="xlsx"
|
||||||
|
)
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.XLSX_MIMETYPE
|
||||||
|
ans = sco_recapcomplet.formsemestre_recapcomplet(
|
||||||
|
formsemestre.id, mode_jury=True, tabformat="json"
|
||||||
|
)
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.JSON_MIMETYPE
|
||||||
|
ans = sco_archives.formsemestre_archive(formsemestre.id)
|
||||||
|
ans = sco_archives.formsemestre_list_archives(formsemestre.id)
|
||||||
|
|
||||||
|
# ----- MENU STATISTIQUES
|
||||||
|
ans = sco_report.formsemestre_report_counts(formsemestre.id)
|
||||||
|
ans = sco_report.formsemestre_report_counts(formsemestre.id, format="xls")
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.XLSX_MIMETYPE
|
||||||
|
ans = sco_report.formsemestre_suivi_cohorte(formsemestre.id)
|
||||||
|
ans = sco_report.formsemestre_suivi_cohorte(formsemestre.id, format="pdf")
|
||||||
|
assert isinstance(ans, Response)
|
||||||
|
assert ans.status == "200 OK"
|
||||||
|
assert ans.mimetype == scu.PDF_MIMETYPE
|
||||||
|
ans = sco_report.formsemestre_graph_cursus(formsemestre.id)
|
||||||
|
ans = sco_report.formsemestre_suivi_cursus(formsemestre.id)
|
||||||
|
ans = sco_lycee.formsemestre_etuds_lycees(formsemestre.id)
|
||||||
|
ans = sco_poursuite_dut.formsemestre_poursuite_report(formsemestre.id)
|
||||||
|
# pas de test des avis de poursuite
|
||||||
|
ans = sco_debouche.report_debouche_date(start_year=2000)
|
||||||
|
ans = sco_cost_formation.formsemestre_estim_cost(formsemestre.id)
|
||||||
|
# pas de test des indicateurs de suivi BUT
|
||||||
|
Loading…
Reference in New Issue
Block a user