Un peu de modernisation de code

This commit is contained in:
Emmanuel Viennet 2022-09-07 17:40:40 +02:00
parent 9b54980b31
commit d3f79c1592
3 changed files with 102 additions and 78 deletions

View File

@ -1236,12 +1236,11 @@ def formsemestre_associate_new_version(
other_formsemestre_ids = [int(x) for x in other_formsemestre_ids] other_formsemestre_ids = [int(x) for x in other_formsemestre_ids]
if not dialog_confirmed: if not dialog_confirmed:
# dresse le liste des semestres de la meme formation et version # dresse le liste des semestres de la meme formation et version
sem = sco_formsemestre.get_formsemestre(formsemestre_id) formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
F = sco_formations.formation_list(args={"formation_id": sem["formation_id"]})[0]
othersems = sco_formsemestre.do_formsemestre_list( othersems = sco_formsemestre.do_formsemestre_list(
args={ args={
"formation_id": F["formation_id"], "formation_id": formsemestre.formation.id,
"version": F["version"], "version": formsemestre.formation.version,
"etat": "1", "etat": "1",
}, },
) )
@ -1265,28 +1264,48 @@ def formsemestre_associate_new_version(
) )
return scu.confirm_dialog( return scu.confirm_dialog(
"""<h2>Associer à une nouvelle version de formation non verrouillée ?</h2> f"""<h2>Associer à une nouvelle version de formation non verrouillée ?</h2>
<p>Le programme pédagogique ("formation") va être dupliqué pour que vous puissiez le modifier sans affecter les autres semestres. Les autres paramètres (étudiants, notes...) du semestre seront inchangés.</p> <p class="help">Le programme pédagogique ("formation") va être dupliqué
<p>Veillez à ne pas abuser de cette possibilité, car créer trop de versions de formations va vous compliquer la gestion (à vous de garder trace des différences et à ne pas vous tromper par la suite...). pour que vous puissiez le modifier sans affecter les autres
semestres. Les autres paramètres (étudiants, notes...) du
semestre seront inchangés.
</p> </p>
<div class="othersemlist"><p>Si vous voulez associer aussi d'autres semestres à la nouvelle version, cochez-les:</p>""" <p class="help">Veillez à ne pas abuser de cette possibilité, car créer
trop de versions de formations va vous compliquer la gestion
(à vous de garder trace des différences et à ne pas vous
tromper par la suite...).
</p>
<p class="help">Si vous souhaitez créer un programme pour de futurs semestres,
utilisez plutôt <a class="stdlink" href="{
url_for('notes.formation_create_new_version',
scodoc_dept=g.scodoc_dept, formation_id=formsemestre.formation.id
)}">Créer une nouvelle version</a>.
</p>
<div class="othersemlist">
<p>Si vous voulez associer aussi d'autres semestres à la nouvelle
version, cochez-les:
</p>"""
+ "".join(H) + "".join(H)
+ "</div>", + "</div>",
OK="Associer ces semestres à une nouvelle version", OK="Associer ces semestres à une nouvelle version",
dest_url="", dest_url="",
cancel_url="formsemestre_status?formsemestre_id=%s" % formsemestre_id, cancel_url=url_for(
"notes.formsemestre_status",
scodoc_dept=g.scodoc_dept,
formsemestre_id=formsemestre_id,
),
parameters={"formsemestre_id": formsemestre_id}, parameters={"formsemestre_id": formsemestre_id},
) )
else: else:
do_formsemestres_associate_new_version( do_formsemestres_associate_new_version(
[formsemestre_id] + other_formsemestre_ids [formsemestre_id] + other_formsemestre_ids
) )
flash("Semestre associé à une nouvelle version de la formation")
return flask.redirect( return flask.redirect(
url_for( url_for(
"notes.formsemestre_status", "notes.formsemestre_status",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre_id,
head_message="Formation dupliquée",
) )
) )
@ -1365,31 +1384,34 @@ def _reassociate_moduleimpls(cnx, formsemestre_id, ues_old2new, modules_old2new)
def formsemestre_delete(formsemestre_id): def formsemestre_delete(formsemestre_id):
"""Delete a formsemestre (affiche avertissements)""" """Delete a formsemestre (affiche avertissements)"""
sem = sco_formsemestre.get_formsemestre(formsemestre_id, raise_soft_exc=True) formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
F = sco_formations.formation_list(args={"formation_id": sem["formation_id"]})[0]
H = [ H = [
html_sco_header.html_sem_header("Suppression du semestre"), html_sco_header.html_sem_header("Suppression du semestre"),
"""<div class="ue_warning"><span>Attention !</span> """<div class="ue_warning"><span>Attention !</span>
<p class="help">A n'utiliser qu'en cas d'erreur lors de la saisie d'une formation. Normalement, <p class="help">A n'utiliser qu'en cas d'erreur lors de la saisie d'une formation. Normalement,
<b>un semestre ne doit jamais être supprimé</b> (on perd la mémoire des notes et de tous les événements liés à ce semestre !).</p> <b>un semestre ne doit jamais être supprimé</b>
(on perd la mémoire des notes et de tous les événements liés à ce semestre !).
</p>
<p class="help">Tous les modules de ce semestre seront supprimés. Ceci n'est possible que <p class="help">Tous les modules de ce semestre seront supprimés.
si :</p> Ceci n'est possible que si :
</p>
<ol> <ol>
<li>aucune décision de jury n'a été entrée dans ce semestre;</li> <li>aucune décision de jury n'a été entrée dans ce semestre;</li>
<li>et aucun étudiant de ce semestre ne le compense avec un autre semestre.</li> <li>et aucun étudiant de ce semestre ne le compense avec un autre semestre.</li>
</ol></div>""", </ol>
</div>""",
] ]
evals = sco_evaluation_db.do_evaluation_list_in_formsemestre(formsemestre_id) evals = sco_evaluation_db.do_evaluation_list_in_formsemestre(formsemestre_id)
if evals: if evals:
H.append( H.append(
"""<p class="warning">Attention: il y a %d évaluations dans ce semestre (sa suppression entrainera l'effacement définif des notes) !</p>""" f"""<p class="warning">Attention: il y a {len(evals)} évaluations
% len(evals) dans ce semestre
(sa suppression entrainera l'effacement définif des notes) !</p>"""
) )
submit_label = ( submit_label = (
"Confirmer la suppression (du semestre et des %d évaluations !)" f"Confirmer la suppression (du semestre et des {len(evals)} évaluations !)"
% len(evals)
) )
else: else:
submit_label = "Confirmer la suppression du semestre" submit_label = "Confirmer la suppression du semestre"
@ -1397,7 +1419,7 @@ def formsemestre_delete(formsemestre_id):
request.base_url, request.base_url,
scu.get_request_args(), scu.get_request_args(),
(("formsemestre_id", {"input_type": "hidden"}),), (("formsemestre_id", {"input_type": "hidden"}),),
initvalues=F, initvalues=formsemestre.to_dict(),
submitlabel=submit_label, submitlabel=submit_label,
cancelbutton="Annuler", cancelbutton="Annuler",
) )
@ -1411,9 +1433,11 @@ def formsemestre_delete(formsemestre_id):
return "\n".join(H) + html_sco_header.sco_footer() return "\n".join(H) + html_sco_header.sco_footer()
elif tf[0] == -1: # cancel elif tf[0] == -1: # cancel
return flask.redirect( return flask.redirect(
scu.NotesURL() url_for(
+ "/formsemestre_status?formsemestre_id=" "notes.formsemestre_status",
+ str(formsemestre_id) scodoc_dept=g.scodoc_dept,
formsemestre_id=formsemestre_id,
)
) )
else: else:
return flask.redirect( return flask.redirect(

View File

@ -770,13 +770,13 @@ def formsemestre_description(
# genere liste html pour accès aux groupes de ce semestre # genere liste html pour accès aux groupes de ce semestre
def _make_listes_sem(sem, with_absences=True): def _make_listes_sem(formsemestre: FormSemestre, with_absences=True):
# construit l'URL "destination" # construit l'URL "destination"
# (a laquelle on revient apres saisie absences) # (a laquelle on revient apres saisie absences)
destination = url_for( destination = url_for(
"notes.formsemestre_status", "notes.formsemestre_status",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
formsemestre_id=sem["formsemestre_id"], formsemestre_id=formsemestre.id,
) )
# #
H = [] H = []
@ -786,15 +786,16 @@ def _make_listes_sem(sem, with_absences=True):
# #
H.append( H.append(
'<h3>Listes de %(titre)s <span class="infostitresem">(%(mois_debut)s - %(mois_fin)s)</span></h3>' f"""<h3>Listes de {formsemestre.titre}
% sem <span class="infostitresem">({formsemestre.mois_debut()} - {formsemestre.mois_fin()})</span></h3>"""
) )
formsemestre_id = sem["formsemestre_id"]
weekday = datetime.datetime.today().weekday() weekday = datetime.datetime.today().weekday()
try: try:
if with_absences: if with_absences:
first_monday = sco_abs.ddmmyyyy(sem["date_debut"]).prev_monday() first_monday = sco_abs.ddmmyyyy(
formsemestre.date_debut.strftime("%d/%m/%Y")
).prev_monday()
form_abs_tmpl = f""" form_abs_tmpl = f"""
<td> <td>
<a href="%(url_etat)s">absences</a> <a href="%(url_etat)s">absences</a>
@ -803,7 +804,8 @@ def _make_listes_sem(sem, with_absences=True):
<form action="{url_for( <form action="{url_for(
"absences.SignaleAbsenceGrSemestre", scodoc_dept=g.scodoc_dept "absences.SignaleAbsenceGrSemestre", scodoc_dept=g.scodoc_dept
)}" method="get"> )}" method="get">
<input type="hidden" name="datefin" value="{sem['date_fin']}"/> <input type="hidden" name="datefin" value="{
formsemestre.date_fin.strftime("%d/%m/%Y")}"/>
<input type="hidden" name="group_ids" value="%(group_id)s"/> <input type="hidden" name="group_ids" value="%(group_id)s"/>
<input type="hidden" name="destination" value="{destination}"/> <input type="hidden" name="destination" value="{destination}"/>
<input type="submit" value="Saisir abs des" /> <input type="submit" value="Saisir abs des" />
@ -811,7 +813,9 @@ def _make_listes_sem(sem, with_absences=True):
""" """
date = first_monday date = first_monday
for idx, jour in enumerate(sco_abs.day_names()): for idx, jour in enumerate(sco_abs.day_names()):
form_abs_tmpl += f"""<option value="{date}" {'selected' if idx == weekday else ''}>{jour}s</option>""" form_abs_tmpl += f"""<option value="{date}" {
'selected' if idx == weekday else ''
}>{jour}s</option>"""
date = date.next_day() date = date.next_day()
form_abs_tmpl += f""" form_abs_tmpl += f"""
</select> </select>
@ -828,7 +832,7 @@ def _make_listes_sem(sem, with_absences=True):
# #
H.append('<div id="grouplists">') H.append('<div id="grouplists">')
# Genere liste pour chaque partition (categorie de groupes) # Genere liste pour chaque partition (categorie de groupes)
for partition in sco_groups.get_partitions_list(sem["formsemestre_id"]): for partition in sco_groups.get_partitions_list(formsemestre.id):
if not partition["partition_name"]: if not partition["partition_name"]:
H.append("<h4>Tous les étudiants</h4>") H.append("<h4>Tous les étudiants</h4>")
else: else:
@ -841,8 +845,8 @@ def _make_listes_sem(sem, with_absences=True):
group["url_etat"] = url_for( group["url_etat"] = url_for(
"absences.EtatAbsencesGr", "absences.EtatAbsencesGr",
group_ids=group["group_id"], group_ids=group["group_id"],
debut=sem["date_debut"], debut=formsemestre.date_debut.strftime("%d/%m/%Y"),
fin=sem["date_fin"], fin=formsemestre.date_fin.strftime("%d/%m/%Y"),
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
) )
if group["group_name"]: if group["group_name"]:
@ -872,7 +876,7 @@ def _make_listes_sem(sem, with_absences=True):
H.append("</table>") H.append("</table>")
else: else:
H.append('<p class="help indent">Aucun groupe dans cette partition') H.append('<p class="help indent">Aucun groupe dans cette partition')
if sco_groups.sco_permissions_check.can_change_groups(formsemestre_id): if sco_groups.sco_permissions_check.can_change_groups(formsemestre.id):
H.append( H.append(
f""" (<a href="{url_for("scolar.affect_groups", f""" (<a href="{url_for("scolar.affect_groups",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
@ -880,12 +884,12 @@ def _make_listes_sem(sem, with_absences=True):
}" class="stdlink">créer</a>)""" }" class="stdlink">créer</a>)"""
) )
H.append("</p>") H.append("</p>")
if sco_groups.sco_permissions_check.can_change_groups(formsemestre_id): if sco_groups.sco_permissions_check.can_change_groups(formsemestre.id):
H.append( H.append(
f"""<h4><a f"""<h4><a
href="{ href="{
url_for("scolar.edit_partition_form", url_for("scolar.edit_partition_form",
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre.id,
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
) )
}">Ajouter une partition</a></h4>""" }">Ajouter une partition</a></h4>"""
@ -1004,25 +1008,21 @@ Il y a des notes en attente ! Le classement des étudiants n'a qu'une valeur ind
def formsemestre_status(formsemestre_id=None): def formsemestre_status(formsemestre_id=None):
"""Tableau de bord semestre HTML""" """Tableau de bord semestre HTML"""
# porté du DTML # porté du DTML
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
sem = sco_formsemestre.get_formsemestre(formsemestre_id, raise_soft_exc=True)
modimpls = sco_moduleimpl.moduleimpl_withmodule_list( modimpls = sco_moduleimpl.moduleimpl_withmodule_list(
formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
) )
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
nt = res_sem.load_formsemestre_results(formsemestre) nt = res_sem.load_formsemestre_results(formsemestre)
# Construit la liste de tous les enseignants de ce semestre: # Construit la liste de tous les enseignants de ce semestre:
mails_enseignants = set( mails_enseignants = set(u.email for u in formsemestre.responsables)
[sco_users.user_info(ens_id)["email"] for ens_id in sem["responsables"]]
)
for modimpl in modimpls: for modimpl in modimpls:
mails_enseignants.add(sco_users.user_info(modimpl["responsable_id"])["email"]) mails_enseignants.add(sco_users.user_info(modimpl["responsable_id"])["email"])
mails_enseignants |= set( mails_enseignants |= set(
[sco_users.user_info(m["ens_id"])["email"] for m in modimpl["ens"]] [sco_users.user_info(m["ens_id"])["email"] for m in modimpl["ens"]]
) )
can_edit = sco_formsemestre_edit.can_edit_sem(formsemestre_id, sem=sem) can_edit = formsemestre.can_be_edited_by(current_user)
use_ue_coefs = sco_preferences.get_preference("use_ue_coefs", formsemestre_id) use_ue_coefs = sco_preferences.get_preference("use_ue_coefs", formsemestre_id)
H = [ H = [
@ -1033,7 +1033,9 @@ def formsemestre_status(formsemestre_id=None):
formsemestre_status_head( formsemestre_status_head(
formsemestre_id=formsemestre_id, page_title="Tableau de bord" formsemestre_id=formsemestre_id, page_title="Tableau de bord"
), ),
"""<p><b style="font-size: 130%">Tableau de bord: </b><span class="help">cliquez sur un module pour saisir des notes</span></p>""", """<p><b style="font-size: 130%">Tableau de bord: </b>
<span class="help">cliquez sur un module pour saisir des notes</span>
</p>""",
] ]
if nt.expr_diagnostics: if nt.expr_diagnostics:
@ -1051,28 +1053,29 @@ def formsemestre_status(formsemestre_id=None):
if m["module"]["module_type"] not in (ModuleType.RESSOURCE, ModuleType.SAE) if m["module"]["module_type"] not in (ModuleType.RESSOURCE, ModuleType.SAE)
] ]
H += [ H += [
""" f"""
<div class="tableau_modules"> <div class="tableau_modules">
""", {_TABLEAU_MODULES_HEAD}
_TABLEAU_MODULES_HEAD, <tr class="formsemestre_status_cat">
f"""<tr class="formsemestre_status_cat">
<td colspan="5"> <td colspan="5">
<span class="status_module_cat">Ressources</span> <span class="status_module_cat">Ressources</span>
</td></tr>""", </td>
formsemestre_tableau_modules( </tr>
{formsemestre_tableau_modules(
ressources, nt, formsemestre_id, can_edit=can_edit, show_ues=False ressources, nt, formsemestre_id, can_edit=can_edit, show_ues=False
), )}
f"""<tr class="formsemestre_status_cat"> <tr class="formsemestre_status_cat">
<td colspan="5"> <td colspan="5">
<span class="status_module_cat">SAÉs</span> <span class="status_module_cat">SAÉs</span>
</td></tr>""", </td>
</tr>""",
formsemestre_tableau_modules( formsemestre_tableau_modules(
saes, nt, formsemestre_id, can_edit=can_edit, show_ues=False saes, nt, formsemestre_id, can_edit=can_edit, show_ues=False
), ),
] ]
if autres: if autres:
H += [ H += [
f"""<tr class="formsemestre_status_cat"> """<tr class="formsemestre_status_cat">
<td colspan="5"> <td colspan="5">
<span class="status_module_cat">Autres modules</span> <span class="status_module_cat">Autres modules</span>
</td></tr>""", </td></tr>""",
@ -1106,7 +1109,7 @@ def formsemestre_status(formsemestre_id=None):
# --- LISTE DES ETUDIANTS # --- LISTE DES ETUDIANTS
H += [ H += [
'<div id="groupes">', '<div id="groupes">',
_make_listes_sem(sem), _make_listes_sem(formsemestre),
"</div>", "</div>",
] ]
# --- Lien mail enseignants: # --- Lien mail enseignants:

View File

@ -48,13 +48,11 @@ Opérations:
import datetime import datetime
from flask import request from flask import request
from app.models import FormSemestre
from app.scodoc.intervals import intervalmap from app.scodoc.intervals import intervalmap
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc import sco_evaluations
from app.scodoc import sco_evaluation_db from app.scodoc import sco_evaluation_db
from app.scodoc import sco_formsemestre
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.scodoc import sco_users from app.scodoc import sco_users
@ -179,9 +177,10 @@ def formsemestre_list_saisies_notes(formsemestre_id, format="html"):
"""Table listant toutes les opérations de saisies de notes, dans toutes """Table listant toutes les opérations de saisies de notes, dans toutes
les évaluations du semestre. les évaluations du semestre.
""" """
sem = sco_formsemestre.get_formsemestre(formsemestre_id, raise_soft_exc=True) formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
rows = ndb.SimpleDictFetch( rows = ndb.SimpleDictFetch(
"""SELECT i.nom, i.prenom, code_nip, n.*, mod.titre, e.description, e.jour, u.user_name, e.id as evaluation_id """SELECT i.nom, i.prenom, code_nip, n.*, mod.titre, e.description, e.jour,
u.user_name, e.id as evaluation_id
FROM notes_notes n, notes_evaluation e, notes_moduleimpl mi, FROM notes_notes n, notes_evaluation e, notes_moduleimpl mi,
notes_modules mod, identite i, "user" u notes_modules mod, identite i, "user" u
WHERE mi.id = e.moduleimpl_id WHERE mi.id = e.moduleimpl_id
@ -194,7 +193,7 @@ def formsemestre_list_saisies_notes(formsemestre_id, format="html"):
""", """,
{"formsemestre_id": formsemestre_id}, {"formsemestre_id": formsemestre_id},
) )
# Formatte les notes # Formate les notes
keep_numeric = format in scu.FORMATS_NUMERIQUES keep_numeric = format in scu.FORMATS_NUMERIQUES
for row in rows: for row in rows:
row["value"] = scu.fmt_note(row["value"], keep_numeric=keep_numeric) row["value"] = scu.fmt_note(row["value"], keep_numeric=keep_numeric)
@ -228,16 +227,14 @@ def formsemestre_list_saisies_notes(formsemestre_id, format="html"):
titles=titles, titles=titles,
columns_ids=columns_ids, columns_ids=columns_ids,
rows=rows, rows=rows,
html_title="<h2>Saisies de notes dans %s</h2>" % sem["titreannee"], html_title=f"<h2>Saisies de notes dans {formsemestre.titreannee()}</h2>",
html_class="table_leftalign table_coldate gt_table_searchable", html_class="table_leftalign table_coldate gt_table_searchable",
html_class_ignore_default=True, html_class_ignore_default=True,
html_sortable=True, html_sortable=True,
caption="Saisies de notes dans %s" % sem["titreannee"], caption=f"Saisies de notes dans {formsemestre.titreannee()}",
preferences=sco_preferences.SemPreferences(formsemestre_id), preferences=sco_preferences.SemPreferences(formsemestre_id),
base_url="%s?formsemestre_id=%s" % (request.base_url, formsemestre_id), base_url="%s?formsemestre_id=%s" % (request.base_url, formsemestre_id),
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()
+ "",
) )
return tab.make_page(format=format) return tab.make_page(format=format)