Améliore moduleimpl_inscriptions_edit. Closes #843

This commit is contained in:
Emmanuel Viennet 2024-01-16 11:11:00 +01:00
parent 4babffd022
commit e3fc13f215
5 changed files with 72 additions and 53 deletions

View File

@ -187,7 +187,7 @@ class FormSemestre(db.Model):
def get_formsemestre( def get_formsemestre(
cls, formsemestre_id: int | str, dept_id: int = None cls, formsemestre_id: int | str, dept_id: int = None
) -> "FormSemestre": ) -> "FormSemestre":
""" "FormSemestre ou 404, cherche uniquement dans le département spécifié ou le courant""" """FormSemestre ou 404, cherche uniquement dans le département spécifié ou le courant"""
if not isinstance(formsemestre_id, int): if not isinstance(formsemestre_id, int):
try: try:
formsemestre_id = int(formsemestre_id) formsemestre_id = int(formsemestre_id)

View File

@ -2,6 +2,7 @@
"""ScoDoc models: moduleimpls """ScoDoc models: moduleimpls
""" """
import pandas as pd import pandas as pd
from flask import abort, g
from flask_sqlalchemy.query import Query from flask_sqlalchemy.query import Query
from app import db from app import db
@ -82,6 +83,23 @@ class ModuleImpl(db.Model):
df_cache.EvaluationsPoidsCache.set(self.id, evaluations_poids) df_cache.EvaluationsPoidsCache.set(self.id, evaluations_poids)
return evaluations_poids return evaluations_poids
@classmethod
def get_modimpl(cls, moduleimpl_id: int | str, dept_id: int = None) -> "ModuleImpl":
"""FormSemestre ou 404, cherche uniquement dans le département spécifié ou le courant."""
from app.models.formsemestre import FormSemestre
if not isinstance(moduleimpl_id, int):
try:
moduleimpl_id = int(moduleimpl_id)
except (TypeError, ValueError):
abort(404, "moduleimpl_id invalide")
if g.scodoc_dept:
dept_id = dept_id if dept_id is not None else g.scodoc_dept_id
query = cls.query.filter_by(id=moduleimpl_id)
if dept_id is not None:
query = query.join(FormSemestre).filter_by(dept_id=dept_id)
return query.first_or_404()
def invalidate_evaluations_poids(self): def invalidate_evaluations_poids(self):
"""Invalide poids cachés""" """Invalide poids cachés"""
df_cache.EvaluationsPoidsCache.delete(self.id) df_cache.EvaluationsPoidsCache.delete(self.id)

View File

@ -40,6 +40,7 @@ from app.comp.res_compat import NotesTableCompat
from app.models import ( from app.models import (
FormSemestre, FormSemestre,
Identite, Identite,
ModuleImpl,
Partition, Partition,
ScolarFormSemestreValidation, ScolarFormSemestreValidation,
UniteEns, UniteEns,
@ -52,7 +53,6 @@ from app.scodoc import codes_cursus
from app.scodoc import sco_edit_module from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue from app.scodoc import sco_edit_ue
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc import sco_moduleimpl from app.scodoc import sco_moduleimpl
@ -63,7 +63,9 @@ import app.scodoc.sco_utils as scu
from app.tables import list_etuds from app.tables import list_etuds
def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False): def moduleimpl_inscriptions_edit(
moduleimpl_id, etudids: list[int] | None = None, submitted=False
):
"""Formulaire inscription des etudiants a ce module """Formulaire inscription des etudiants a ce module
* Gestion des inscriptions * Gestion des inscriptions
Nom TD TA TP (triable) Nom TD TA TP (triable)
@ -75,12 +77,12 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
* Si pas les droits: idem en readonly * Si pas les droits: idem en readonly
""" """
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)[0] etudids = etudids or []
formsemestre_id = M["formsemestre_id"] modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
mod = sco_edit_module.module_list(args={"module_id": M["module_id"]})[0] module = modimpl.module
sem = sco_formsemestre.get_formsemestre(formsemestre_id) formsemestre = modimpl.formsemestre
# -- check lock # -- check lock
if not sem["etat"]: if not formsemestre.etat:
raise ScoValueError("opération impossible: semestre verrouille") raise ScoValueError("opération impossible: semestre verrouille")
header = html_sco_header.sco_header( header = html_sco_header.sco_header(
page_title="Inscription au module", page_title="Inscription au module",
@ -90,25 +92,23 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
footer = html_sco_header.sco_footer() footer = html_sco_header.sco_footer()
H = [ H = [
header, header,
"""<h2>Inscriptions au module <a href="moduleimpl_status?moduleimpl_id=%s">%s</a> (%s)</a></h2> f"""<h2>Inscriptions au module <a class="stdlink" href="{
url_for("notes.moduleimpl_status", scodoc_dept=g.scodoc_dept,
moduleimpl_id=moduleimpl_id)
}">{module.titre or "(module sans titre)"}</a> ({module.code})</a></h2>
<p class="help">Cette page permet d'éditer les étudiants inscrits à ce module <p class="help">Cette page permet d'éditer les étudiants inscrits à ce module
(ils doivent évidemment être inscrits au semestre). (ils doivent évidemment être inscrits au semestre).
Les étudiants cochés sont (ou seront) inscrits. Vous pouvez facilement inscrire ou Les étudiants cochés sont (ou seront) inscrits. Vous pouvez inscrire ou
désinscrire tous les étudiants d'un groupe à l'aide des menus "Ajouter" et "Enlever". désinscrire tous les étudiants d'un groupe à l'aide des menus "Ajouter" et "Enlever".
</p> </p>
<p class="help">Aucune modification n'est prise en compte tant que l'on n'appuie pas sur le bouton <p class="help">Aucune modification n'est prise en compte tant que l'on n'appuie pas
"Appliquer les modifications". sur le bouton "Appliquer les modifications".
</p> </p>
""" """,
% (
moduleimpl_id,
mod["titre"] or "(module sans titre)",
mod["code"] or "(module sans code)",
),
] ]
# Liste des inscrits à ce semestre # Liste des inscrits à ce semestre
inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits( inscrits = sco_formsemestre_inscriptions.do_formsemestre_inscription_listinscrits(
formsemestre_id formsemestre.id
) )
for ins in inscrits: for ins in inscrits:
etuds_info = sco_etud.get_etud_info(etudid=ins["etudid"], filled=1) etuds_info = sco_etud.get_etud_info(etudid=ins["etudid"], filled=1)
@ -121,12 +121,10 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
) )
ins["etud"] = etuds_info[0] ins["etud"] = etuds_info[0]
inscrits.sort(key=lambda inscr: sco_etud.etud_sort_key(inscr["etud"])) inscrits.sort(key=lambda inscr: sco_etud.etud_sort_key(inscr["etud"]))
in_m = sco_moduleimpl.do_moduleimpl_inscription_list( in_m = sco_moduleimpl.do_moduleimpl_inscription_list(moduleimpl_id=modimpl.id)
moduleimpl_id=M["moduleimpl_id"] in_module = {x["etudid"] for x in in_m}
)
in_module = set([x["etudid"] for x in in_m])
# #
partitions = sco_groups.get_partitions_list(formsemestre_id) partitions = sco_groups.get_partitions_list(formsemestre.id)
# #
if not submitted: if not submitted:
H.append( H.append(
@ -149,27 +147,32 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
} }
} }
</script>""" </script>
<style>
table.mi_table td, table.mi_table th {
text-align: left;
}
</style>
"""
) )
H.append( H.append(
f"""<form method="post" id="mi_form" action="{request.base_url}"> f"""<form method="post" id="mi_form" action="{request.base_url}">
<input type="hidden" name="moduleimpl_id" value="{M['moduleimpl_id']}"/> <input type="hidden" name="moduleimpl_id" value="{modimpl.id}"/>
<input type="submit" name="submitted" value="Appliquer les modifications"/> <input type="submit" name="submitted" value="Appliquer les modifications"/>
<p></p> <div>
<table><tr>
{ _make_menu(partitions, "Ajouter", "true") } { _make_menu(partitions, "Ajouter", "true") }
{ _make_menu(partitions, "Enlever", "false")} { _make_menu(partitions, "Enlever", "false")}
</tr></table> </div>
<p><br></p> <table class="gt_table mi_table">
<table class="sortable" id="mi_table"> <thead>
<tr> <tr>
<th>Nom</th> <th class="etud">Nom</th>
""" """
) )
for partition in partitions: for partition in partitions:
if partition["partition_name"]: if partition["partition_name"]:
H.append("<th>%s</th>" % partition["partition_name"]) H.append(f"<th>{partition['partition_name']}</th>")
H.append("</tr>") H.append("</tr></thead><tbody>")
for ins in inscrits: for ins in inscrits:
etud = ins["etud"] etud = ins["etud"]
@ -178,24 +181,20 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
else: else:
checked = "" checked = ""
H.append( H.append(
"""<tr><td><input type="checkbox" name="etuds:list" value="%s" %s>""" f"""<tr><td class="etud"><input type="checkbox" name="etudids:list" value="{etud['etudid']}" {checked}>"""
% (etud["etudid"], checked)
) )
H.append( H.append(
"""<a class="discretelink etudinfo" href="%s" id="%s">%s</a>""" f"""<a class="discretelink etudinfo" href="{
% (
url_for( url_for(
"scolar.ficheEtud", "scolar.ficheEtud",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
etudid=etud["etudid"], etudid=etud["etudid"],
),
etud["etudid"],
etud["nomprenom"],
) )
}" id="{etud['etudid']}">{etud['nomprenom']}</a>"""
) )
H.append("""</input></td>""") H.append("""</input></td>""")
groups = sco_groups.get_etud_groups(etud["etudid"], formsemestre_id) groups = sco_groups.get_etud_groups(etud["etudid"], formsemestre.id)
for partition in partitions: for partition in partitions:
if partition["partition_name"]: if partition["partition_name"]:
gr_name = "" gr_name = ""
@ -205,11 +204,11 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
break break
# gr_name == '' si etud non inscrit dans un groupe de cette partition # gr_name == '' si etud non inscrit dans un groupe de cette partition
H.append(f"<td>{gr_name}</td>") H.append(f"<td>{gr_name}</td>")
H.append("""</table></form>""") H.append("""</tbody></table></form>""")
else: # SUBMISSION else: # SUBMISSION
# inscrit a ce module tous les etuds selectionnes # inscrit a ce module tous les etuds selectionnes
sco_moduleimpl.do_moduleimpl_inscrit_etuds( sco_moduleimpl.do_moduleimpl_inscrit_etuds(
moduleimpl_id, formsemestre_id, etuds, reset=True moduleimpl_id, formsemestre.id, etudids, reset=True
) )
return flask.redirect( return flask.redirect(
url_for( url_for(
@ -225,10 +224,10 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
def _make_menu(partitions: list[dict], title="", check="true") -> str: def _make_menu(partitions: list[dict], title="", check="true") -> str:
"""Menu with list of all groups""" """Menu with list of all groups"""
items = [{"title": "Tous", "attr": "onclick=\"group_select('', -1, %s)\"" % check}] items = [{"title": "Tous", "attr": f"onclick=\"group_select('', -1, {check})\""}]
p_idx = 0 p_idx = 0
for partition in partitions: for partition in partitions:
if partition["partition_name"] != None: if partition["partition_name"] is not None:
p_idx += 1 p_idx += 1
for group in sco_groups.get_partition_groups(partition): for group in sco_groups.get_partition_groups(partition):
items.append( items.append(
@ -240,9 +239,9 @@ def _make_menu(partitions: list[dict], title="", check="true") -> str:
} }
) )
return ( return (
'<td class="inscr_addremove_menu">' '<div class="inscr_addremove_menu">'
+ htmlutils.make_menu(title, items, alone=True) + htmlutils.make_menu(title, items, alone=True)
+ "</td>" + "</div>"
) )

View File

@ -1736,7 +1736,9 @@ formsemestre_page_title .lock img {
width: 200px !important; width: 200px !important;
} }
span.inscr_addremove_menu { div.inscr_addremove_menu {
display: inline-block;
margin: 8px 0px;
width: 150px; width: 150px;
} }

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.6.78" SCOVERSION = "9.6.79"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"