1
0
forked from ScoDoc/ScoDoc

Divers correctifs et modernisation du code (commence #381)

This commit is contained in:
Emmanuel Viennet 2022-09-03 11:41:56 +02:00
parent 71a15fed2f
commit 227b94ac6a
20 changed files with 103 additions and 93 deletions

View File

@ -289,7 +289,7 @@ def formsemestre_programme(formsemestre_id: int):
def formsemestre_etudiants( def formsemestre_etudiants(
formsemestre_id: int, with_query: bool = False, long: bool = False formsemestre_id: int, with_query: bool = False, long: bool = False
): ):
"""Etudiants d'un formsemestre.""" """Étudiants d'un formsemestre."""
query = FormSemestre.query.filter_by(id=formsemestre_id) query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept: if g.scodoc_dept:
query = query.filter_by(dept_id=g.scodoc_dept_id) query = query.filter_by(dept_id=g.scodoc_dept_id)

View File

@ -134,7 +134,7 @@ def etud_in_group(group_id: int):
@scodoc @scodoc
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
def etud_in_group_query(group_id: int): def etud_in_group_query(group_id: int):
"""Etudiants du groupe, filtrés par état""" """Étudiants du groupe, filtrés par état"""
etat = request.args.get("etat") etat = request.args.get("etat")
if etat not in {None, scu.INSCRIT, scu.DEMISSION, scu.DEF}: if etat not in {None, scu.INSCRIT, scu.DEMISSION, scu.DEF}:
return json_error(404, "etat: valeur invalide") return json_error(404, "etat: valeur invalide")

View File

@ -66,7 +66,7 @@ class Identite(db.Model):
@classmethod @classmethod
def from_request(cls, etudid=None, code_nip=None): def from_request(cls, etudid=None, code_nip=None):
"""Etudiant à partir de l'etudid ou du code_nip, soit """Étudiant à partir de l'etudid ou du code_nip, soit
passés en argument soit retrouvés directement dans la requête web. passés en argument soit retrouvés directement dans la requête web.
Erreur 404 si inexistant. Erreur 404 si inexistant.
""" """

View File

@ -241,7 +241,7 @@ VOID_APO_RES = dict(N="", B="", J="", R="", M="")
class ApoEtud(dict): class ApoEtud(dict):
"""Etudiant Apogee:""" """Étudiant Apogee:"""
def __init__( def __init__(
self, self,

View File

@ -143,7 +143,7 @@ def formsemestre_bulletinetud_dict(formsemestre_id, etudid, version="long"):
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
if not nt.get_etud_etat(etudid): if not nt.get_etud_etat(etudid):
raise ScoValueError("Etudiant non inscrit à ce semestre") raise ScoValueError("Étudiant non inscrit à ce semestre")
I = scu.DictDefault(defaultvalue="") I = scu.DictDefault(defaultvalue="")
I["etudid"] = etudid I["etudid"] = etudid
I["formsemestre_id"] = formsemestre_id I["formsemestre_id"] = formsemestre_id

View File

@ -191,7 +191,7 @@ def apo_semset_maq_status(
"notes.view_scodoc_etuds", "notes.view_scodoc_etuds",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
semset_id=semset_id, semset_id=semset_id,
title="Etudiants ScoDoc non listés dans les maquettes Apogée chargées", title="Étudiants ScoDoc non listés dans les maquettes Apogée chargées",
nip_list=",".join(nips_no_apo), nip_list=",".join(nips_no_apo),
) )
H.append( H.append(
@ -204,7 +204,7 @@ def apo_semset_maq_status(
"notes.view_apo_etuds", "notes.view_apo_etuds",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
semset_id=semset_id, semset_id=semset_id,
title="Etudiants présents dans maquettes Apogée mais pas dans les semestres ScoDoc", title="Étudiants présents dans maquettes Apogée mais pas dans les semestres ScoDoc",
nip_list=",".join(nips_no_sco), nip_list=",".join(nips_no_sco),
) )
H.append( H.append(
@ -747,7 +747,7 @@ def view_apo_csv(etape_apo="", semset_id="", format="html"):
base_url="%s?etape_apo=%s&semset_id=%s" base_url="%s?etape_apo=%s&semset_id=%s"
% (request.base_url, etape_apo, semset_id), % (request.base_url, etape_apo, semset_id),
filename="students_" + etape_apo, filename="students_" + etape_apo,
caption="Etudiants Apogée en " + etape_apo, caption="Étudiants Apogée en " + etape_apo,
preferences=sco_preferences.SemPreferences(), preferences=sco_preferences.SemPreferences(),
) )

View File

@ -211,7 +211,7 @@ def etud_sort_key(etud: dict) -> tuple:
""" """
return ( return (
scu.sanitize_string( scu.sanitize_string(
etud["nom_usuel"] or etud["nom"] or "", remove_spaces=False etud.get("nom_usuel") or etud["nom"] or "", remove_spaces=False
).lower(), ).lower(),
scu.sanitize_string(etud["prenom"] or "", remove_spaces=False).lower(), scu.sanitize_string(etud["prenom"] or "", remove_spaces=False).lower(),
) )

View File

@ -185,7 +185,7 @@ def search_etud_in_dept(expnom=""):
tab = GenTable( tab = GenTable(
columns_ids=("nomprenom", "code_nip", "inscription", "groupes"), columns_ids=("nomprenom", "code_nip", "inscription", "groupes"),
titles={ titles={
"nomprenom": "Etudiant", "nomprenom": "Étudiant",
"code_nip": "NIP", "code_nip": "NIP",
"inscription": "Inscription", "inscription": "Inscription",
"groupes": "Groupes", "groupes": "Groupes",
@ -335,7 +335,7 @@ def table_etud_in_accessible_depts(expnom=None):
e["_nomprenom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"]) e["_nomprenom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"])
tab = GenTable( tab = GenTable(
titles={"nomprenom": "Etudiants en " + dept_id}, titles={"nomprenom": "Étudiants en " + dept_id},
columns_ids=("nomprenom",), columns_ids=("nomprenom",),
rows=etuds, rows=etuds,
html_sortable=True, html_sortable=True,

View File

@ -741,7 +741,7 @@ def do_formsemestre_createwithmodules(edit=False):
if ndb.DateDMYtoISO(tf[2]["date_debut"]) > ndb.DateDMYtoISO(tf[2]["date_fin"]): if ndb.DateDMYtoISO(tf[2]["date_debut"]) > ndb.DateDMYtoISO(tf[2]["date_fin"]):
msg = '<ul class="tf-msg"><li class="tf-msg">Dates de début et fin incompatibles !</li></ul>' msg = '<ul class="tf-msg"><li class="tf-msg">Dates de début et fin incompatibles !</li></ul>'
if sco_preferences.get_preference("always_require_apo_sem_codes") and not any( if sco_preferences.get_preference("always_require_apo_sem_codes") and not any(
[tf[2]["etape_apo" + str(n)] for n in range(1, scu.EDIT_NB_ETAPES + 1)] [tf[2]["etape_apo" + str(n)] for n in range(0, scu.EDIT_NB_ETAPES + 1)]
): ):
msg = '<ul class="tf-msg"><li class="tf-msg">Code étape Apogée manquant</li></ul>' msg = '<ul class="tf-msg"><li class="tf-msg">Code étape Apogée manquant</li></ul>'

View File

@ -90,8 +90,8 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
f"""<h2>Enregistrement d'une inscription antérieure dans un autre f"""<h2>Enregistrement d'une inscription antérieure dans un autre
établissement</h2> établissement</h2>
<p class="help"> <p class="help">
Cette opération crée un semestre extérieur ("ancien") et y inscrit Cette opération crée un semestre extérieur ("ancien") de la même
juste cet étudiant. formation que le semestre courant, et y inscrit juste cet étudiant.
La décision de jury peut ensuite y être saisie. La décision de jury peut ensuite y être saisie.
</p> </p>
<p class="help"> <p class="help">
@ -128,7 +128,11 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
""" """
) )
if not semestre_ids: if not semestre_ids:
H.append("""<p class="warning">pas de semestres extérieurs possibles</p>""") H.append(
f"""<p class="warning">pas de semestres extérieurs possibles
(indices entre {min_semestre_id} et {max_semestre_id}, semestre courant.)
</p>"""
)
return "\n".join(H) + F return "\n".join(H) + F
# Formulaire # Formulaire
semestre_ids_list = sorted(semestre_ids) semestre_ids_list = sorted(semestre_ids)
@ -150,7 +154,8 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
{ {
"size": 40, "size": 40,
"title": "Nom de ce semestre extérieur", "title": "Nom de ce semestre extérieur",
"explanation": """par exemple: établissement. N'indiquez pas les dates, ni le semestre, ni la modalité dans "explanation": """par exemple: établissement.
N'indiquez pas les dates, ni le semestre, ni la modalité dans
le titre: ils seront automatiquement ajoutés""", le titre: ils seront automatiquement ajoutés""",
}, },
), ),
@ -211,6 +216,7 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
) )
) )
else: else:
# Le semestre extérieur est créé dans la même formation que le semestre courant
tf[2]["formation_id"] = orig_sem["formation_id"] tf[2]["formation_id"] = orig_sem["formation_id"]
formsemestre_ext_create(etudid, tf[2]) formsemestre_ext_create(etudid, tf[2])
return flask.redirect( return flask.redirect(

View File

@ -30,12 +30,13 @@
import time import time
import flask import flask
from flask import url_for, g, request from flask import flash, url_for, g, request
from app.comp import res_sem from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import FormSemestre from app.models import FormSemestre
from app.models.groups import GroupDescr, Partition from app.models.etudiants import Identite
from app.models.groups import GroupDescr
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app import log from app import log
from app.scodoc.scolog import logdb from app.scodoc.scolog import logdb
@ -85,12 +86,12 @@ def do_formsemestre_inscription_listinscrits(formsemestre_id):
def do_formsemestre_inscription_create(args, method=None): def do_formsemestre_inscription_create(args, method=None):
"create a formsemestre_inscription (and sco event)" "create a formsemestre_inscription (and sco event)"
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
log("do_formsemestre_inscription_create: args=%s" % str(args)) log(f"do_formsemestre_inscription_create: args={args}")
sems = sco_formsemestre.do_formsemestre_list( sems = sco_formsemestre.do_formsemestre_list(
{"formsemestre_id": args["formsemestre_id"]} {"formsemestre_id": args["formsemestre_id"]}
) )
if len(sems) != 1: if len(sems) != 1:
raise ScoValueError("code de semestre invalide: %s" % args["formsemestre_id"]) raise ScoValueError(f"code de semestre invalide: {args['formsemestre_id']}")
sem = sems[0] sem = sems[0]
# check lock # check lock
if not sem["etat"]: if not sem["etat"]:
@ -112,13 +113,11 @@ def do_formsemestre_inscription_create(args, method=None):
cnx, cnx,
method=method, method=method,
etudid=args["etudid"], etudid=args["etudid"],
msg="inscription en semestre %s" % args["formsemestre_id"], msg=f"inscription en semestre {args['formsemestre_id']}",
commit=False, commit=False,
) )
# #
sco_cache.invalidate_formsemestre( sco_cache.invalidate_formsemestre(formsemestre_id=args["formsemestre_id"])
formsemestre_id=args["formsemestre_id"]
) # > inscription au semestre
return r return r
@ -127,9 +126,7 @@ def do_formsemestre_inscription_delete(oid, formsemestre_id=None):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
_formsemestre_inscriptionEditor.delete(cnx, oid) _formsemestre_inscriptionEditor.delete(cnx, oid)
sco_cache.invalidate_formsemestre( sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
formsemestre_id=formsemestre_id
) # > desinscription du semestre
def do_formsemestre_demission( def do_formsemestre_demission(
@ -183,25 +180,26 @@ def do_formsemestre_desinscription(etudid, formsemestre_id):
""" """
from app.scodoc import sco_formsemestre_edit from app.scodoc import sco_formsemestre_edit
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
# -- check lock
if not sem["etat"]:
raise ScoValueError("desinscription impossible: semestre verrouille")
# -- Si decisions de jury, desinscription interdite
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
etud = Identite.query.get_or_404(etudid)
# -- check lock
if not formsemestre.etat:
raise ScoValueError("désinscription impossible: semestre verrouille")
# -- Si decisions de jury, désinscription interdite
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
if nt.etud_has_decision(etudid): if nt.etud_has_decision(etudid):
raise ScoValueError( raise ScoValueError(
"desinscription impossible: l'étudiant a une décision de jury (la supprimer avant si nécessaire)" """désinscription impossible: l'étudiant {etud.nomprenom} a
une décision de jury (la supprimer avant si nécessaire)"""
) )
insem = do_formsemestre_inscription_list( insem = do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id, "etudid": etudid} args={"formsemestre_id": formsemestre_id, "etudid": etudid}
) )
if not insem: if not insem:
raise ScoValueError("%s n'est pas inscrit au semestre !" % etudid) raise ScoValueError(f"{etud.nomprenom} n'est pas inscrit au semestre !")
insem = insem[0] insem = insem[0]
# -- desinscription de tous les modules # -- desinscription de tous les modules
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
@ -221,21 +219,22 @@ def do_formsemestre_desinscription(etudid, formsemestre_id):
sco_moduleimpl.do_moduleimpl_inscription_delete( sco_moduleimpl.do_moduleimpl_inscription_delete(
moduleimpl_inscription_id, formsemestre_id=formsemestre_id moduleimpl_inscription_id, formsemestre_id=formsemestre_id
) )
# -- desincription du semestre # -- désincription du semestre
do_formsemestre_inscription_delete( do_formsemestre_inscription_delete(
insem["formsemestre_inscription_id"], formsemestre_id=formsemestre_id insem["formsemestre_inscription_id"], formsemestre_id=formsemestre_id
) )
# --- Semestre extérieur # --- Semestre extérieur
if sem["modalite"] == "EXT": if formsemestre.modalite == "EXT":
inscrits = do_formsemestre_inscription_list( inscrits = do_formsemestre_inscription_list(
args={"formsemestre_id": formsemestre_id} args={"formsemestre_id": formsemestre_id}
) )
nbinscrits = len(inscrits) nbinscrits = len(inscrits)
if nbinscrits == 0: if nbinscrits == 0:
log( log(
"do_formsemestre_desinscription: suppression du semestre extérieur %s" f"""do_formsemestre_desinscription:
% formsemestre_id suppression du semestre extérieur {formsemestre}"""
) )
flash("Semestre exterieur supprimé")
sco_formsemestre_edit.do_formsemestre_delete(formsemestre_id) sco_formsemestre_edit.do_formsemestre_delete(formsemestre_id)
logdb( logdb(

View File

@ -322,7 +322,7 @@ def formsemestre_validation_etud_form(
# Décisions possibles # Décisions possibles
rows_assidu = decisions_possible_rows( rows_assidu = decisions_possible_rows(
Se, True, subtitle="Etudiant assidu:", trclass="sfv_ass" Se, True, subtitle="Étudiant assidu:", trclass="sfv_ass"
) )
rows_non_assidu = decisions_possible_rows( rows_non_assidu = decisions_possible_rows(
Se, False, subtitle="Si problème d'assiduité:", trclass="sfv_pbass" Se, False, subtitle="Si problème d'assiduité:", trclass="sfv_pbass"

View File

@ -213,7 +213,7 @@ def sco_import_generate_excel_sample(
else: else:
lines = [[]] # empty content, titles only lines = [[]] # empty content, titles only
return sco_excel.excel_simple_table( return sco_excel.excel_simple_table(
titles=titles, titles_styles=titles_styles, sheet_name="Etudiants", lines=lines titles=titles, titles_styles=titles_styles, sheet_name="Étudiants", lines=lines
) )

View File

@ -115,7 +115,7 @@ def list_authorized_etuds_by_sem(sem, delai=274, ignore_jury=False):
def list_inscrits(formsemestre_id, with_dems=False): def list_inscrits(formsemestre_id, with_dems=False):
"""Etudiants déjà inscrits à ce semestre """Étudiants déjà inscrits à ce semestre
{ etudid : etud } { etudid : etud }
""" """
if not with_dems: if not with_dems:

View File

@ -46,11 +46,11 @@ from app.scodoc import htmlutils
from app.scodoc import sco_cache from app.scodoc import sco_cache
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_formsemestre 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
from app.scodoc import sco_etud
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_permissions import Permission from app.scodoc.sco_permissions import Permission
@ -106,14 +106,13 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
etuds_info = sco_etud.get_etud_info(etudid=ins["etudid"], filled=1) etuds_info = sco_etud.get_etud_info(etudid=ins["etudid"], filled=1)
if not etuds_info: if not etuds_info:
log( log(
"moduleimpl_inscriptions_edit: incoherency for etudid=%s !" f"""moduleimpl_inscriptions_edit: inconsistency for etudid={ins['etudid']} !"""
% ins["etudid"]
) )
raise ScoValueError( raise ScoValueError(
"Etudiant %s inscrit mais inconnu dans la base !!!!!" % ins["etudid"] f"""Étudiant {ins['etudid']} inscrit mais inconnu dans la base !"""
) )
ins["etud"] = etuds_info[0] ins["etud"] = etuds_info[0]
inscrits.sort(key=lambda x: x["etud"]["nom"]) 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=M["moduleimpl_id"] moduleimpl_id=M["moduleimpl_id"]
) )
@ -144,24 +143,20 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
</script>""" </script>"""
) )
H.append("""<form method="post" id="mi_form" action="%s">""" % request.base_url)
H.append( H.append(
""" f"""<form method="post" id="mi_form" action="{request.base_url}">
<input type="hidden" name="moduleimpl_id" value="%(moduleimpl_id)s"/> <input type="hidden" name="moduleimpl_id" value="{M['moduleimpl_id']}"/>
<input type="submit" name="submitted" value="Appliquer les modifications"/><p></p> <input type="submit" name="submitted" value="Appliquer les modifications"/>
""" <p></p>
% M <table><tr>
) { _make_menu(partitions, "Ajouter", "true") }
H.append("<table><tr>") { _make_menu(partitions, "Enlever", "false")}
H.append(_make_menu(partitions, "Ajouter", "true")) </tr></table>
H.append(_make_menu(partitions, "Enlever", "false"))
H.append("</tr></table>")
H.append(
"""
<p><br/></p> <p><br/></p>
<table class="sortable" id="mi_table"><tr> <table class="sortable" id="mi_table">
<th>Nom</th>""" <tr>
% sem <th>Nom</th>
"""
) )
for partition in partitions: for partition in partitions:
if partition["partition_name"]: if partition["partition_name"]:
@ -201,14 +196,20 @@ def moduleimpl_inscriptions_edit(moduleimpl_id, etuds=[], submitted=False):
gr_name = group["group_name"] gr_name = group["group_name"]
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("<td>%s</td>" % gr_name) H.append(f"<td>{gr_name}</td>")
H.append("""</table></form>""") H.append("""</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, etuds, reset=True
) )
return flask.redirect("moduleimpl_status?moduleimpl_id=%s" % (moduleimpl_id)) return flask.redirect(
url_for(
"notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept,
moduleimpl_id=moduleimpl_id,
)
)
# #
H.append(footer) H.append(footer)
return "\n".join(H) return "\n".join(H)

View File

@ -162,7 +162,7 @@ def ficheEtud(etudid=None):
etuds = sco_etud.etudident_list(cnx, args) etuds = sco_etud.etudident_list(cnx, args)
if not etuds: if not etuds:
log(f"ficheEtud: etudid={etudid!r} request.args={request.args!r}") log(f"ficheEtud: etudid={etudid!r} request.args={request.args!r}")
raise ScoValueError("Etudiant inexistant !") raise ScoValueError("Étudiant inexistant !")
etud = etuds[0] etud = etuds[0]
etudid = etud["etudid"] etudid = etud["etudid"]
sco_etud.fill_etuds_info([etud]) sco_etud.fill_etuds_info([etud])
@ -573,7 +573,7 @@ def menus_etud(etudid):
}, },
] ]
return htmlutils.make_menu("Etudiant", menuEtud, alone=True) return htmlutils.make_menu("Étudiant", menuEtud, alone=True)
def etud_info_html(etudid, with_photo="1", debug=False): def etud_info_html(etudid, with_photo="1", debug=False):

View File

@ -447,7 +447,7 @@ def list_synch(sem, anneeapogee=None):
"etuds": set_to_sorted_list(a_importer, is_inscrit=True, etud_apo=True), "etuds": set_to_sorted_list(a_importer, is_inscrit=True, etud_apo=True),
"infos": { "infos": {
"id": "etuds_a_importer", "id": "etuds_a_importer",
"title": "Etudiants dans Apogée à importer", "title": "Étudiants dans Apogée à importer",
"help": """Ces étudiants sont inscrits dans cette étape Apogée mais ne sont pas connus par ScoDoc: "help": """Ces étudiants sont inscrits dans cette étape Apogée mais ne sont pas connus par ScoDoc:
cocher les noms à importer et inscrire puis appuyer sur le bouton "Appliquer".""", cocher les noms à importer et inscrire puis appuyer sur le bouton "Appliquer".""",
"title_target": "", "title_target": "",
@ -461,7 +461,7 @@ def list_synch(sem, anneeapogee=None):
"etuds": set_to_sorted_list(etuds_noninscrits, is_inscrit=True), "etuds": set_to_sorted_list(etuds_noninscrits, is_inscrit=True),
"infos": { "infos": {
"id": "etuds_noninscrits", "id": "etuds_noninscrits",
"title": "Etudiants non inscrits dans ce semestre", "title": "Étudiants non inscrits dans ce semestre",
"help": """Ces étudiants sont déjà connus par ScoDoc, sont inscrits dans cette étape Apogée mais ne sont pas inscrits à ce semestre ScoDoc. Cochez les étudiants à inscrire.""", "help": """Ces étudiants sont déjà connus par ScoDoc, sont inscrits dans cette étape Apogée mais ne sont pas inscrits à ce semestre ScoDoc. Cochez les étudiants à inscrire.""",
"comment": """ dans ScoDoc et Apogée, <br/>mais pas inscrits "comment": """ dans ScoDoc et Apogée, <br/>mais pas inscrits
dans ce semestre""", dans ce semestre""",
@ -475,7 +475,7 @@ def list_synch(sem, anneeapogee=None):
"etuds": set_to_sorted_list(etuds_nonapogee, is_inscrit=True), "etuds": set_to_sorted_list(etuds_nonapogee, is_inscrit=True),
"infos": { "infos": {
"id": "etuds_nonapogee", "id": "etuds_nonapogee",
"title": "Etudiants ScoDoc inconnus dans cette étape Apogée", "title": "Étudiants ScoDoc inconnus dans cette étape Apogée",
"help": """Ces étudiants sont inscrits dans ce semestre ScoDoc, ont un code NIP, mais ne sont pas inscrits dans cette étape Apogée. Soit ils sont en retard pour leur inscription, soit il s'agit d'une erreur: vérifiez avec le service Scolarité de votre établissement. Autre possibilité: votre code étape semestre (%s) est incorrect ou vous n'avez pas choisi la bonne année d'inscription.""" "help": """Ces étudiants sont inscrits dans ce semestre ScoDoc, ont un code NIP, mais ne sont pas inscrits dans cette étape Apogée. Soit ils sont en retard pour leur inscription, soit il s'agit d'une erreur: vérifiez avec le service Scolarité de votre établissement. Autre possibilité: votre code étape semestre (%s) est incorrect ou vous n'avez pas choisi la bonne année d'inscription."""
% sem["etape_apo_str"], % sem["etape_apo_str"],
"comment": " à vérifier avec la Scolarité", "comment": " à vérifier avec la Scolarité",
@ -489,7 +489,7 @@ def list_synch(sem, anneeapogee=None):
"etuds": list(inscrits_without_key.values()), "etuds": list(inscrits_without_key.values()),
"infos": { "infos": {
"id": "inscrits_without_key", "id": "inscrits_without_key",
"title": "Etudiants ScoDoc sans clé Apogée (NIP)", "title": "Étudiants ScoDoc sans clé Apogée (NIP)",
"help": """Ces étudiants sont inscrits dans ce semestre ScoDoc, mais n'ont pas de code NIP: on ne peut pas les mettre en correspondance avec Apogée. Utiliser le lien 'Changer les données identité' dans le menu 'Etudiant' sur leur fiche pour ajouter cette information.""", "help": """Ces étudiants sont inscrits dans ce semestre ScoDoc, mais n'ont pas de code NIP: on ne peut pas les mettre en correspondance avec Apogée. Utiliser le lien 'Changer les données identité' dans le menu 'Etudiant' sur leur fiche pour ajouter cette information.""",
"title_target": "", "title_target": "",
"with_checkbox": True, "with_checkbox": True,
@ -501,7 +501,7 @@ def list_synch(sem, anneeapogee=None):
"etuds": set_to_sorted_list(etuds_ok, is_inscrit=True), "etuds": set_to_sorted_list(etuds_ok, is_inscrit=True),
"infos": { "infos": {
"id": "etuds_ok", "id": "etuds_ok",
"title": "Etudiants dans Apogée et déjà inscrits", "title": "Étudiants dans Apogée et déjà inscrits",
"help": """Ces etudiants sont inscrits dans le semestre ScoDoc et sont présents dans Apogée: "help": """Ces etudiants sont inscrits dans le semestre ScoDoc et sont présents dans Apogée:
tout est donc correct. Décocher les étudiants que vous souhaitez désinscrire.""", tout est donc correct. Décocher les étudiants que vous souhaitez désinscrire.""",
"title_target": "", "title_target": "",

View File

@ -503,7 +503,7 @@ def photos_import_files_form(group_ids=()):
html_sco_header.sco_header(page_title="Import des photos des étudiants"), html_sco_header.sco_header(page_title="Import des photos des étudiants"),
f"""<h2 class="formsemestre">Téléchargement des photos des étudiants</h2> f"""<h2 class="formsemestre">Téléchargement des photos des étudiants</h2>
<p><b>Vous pouvez aussi charger les photos individuellement via la fiche <p><b>Vous pouvez aussi charger les photos individuellement via la fiche
de chaque étudiant (menu "Etudiant" / "Changer la photo").</b> de chaque étudiant (menu "Étudiant" / "Changer la photo").</b>
</p> </p>
<p class="help">Cette page permet de charger en une seule fois les photos <p class="help">Cette page permet de charger en une seule fois les photos
de plusieurs étudiants.<br/> de plusieurs étudiants.<br/>

View File

@ -1491,7 +1491,7 @@ def do_formsemestre_inscription_listinscrits(formsemestre_id, format=None):
@permission_required(Permission.ScoImplement) @permission_required(Permission.ScoImplement)
@scodoc7func @scodoc7func
def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False): def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False):
"""desinscrit l'etudiant de ce semestre (et donc de tous les modules). """désinscrit l'etudiant de ce semestre (et donc de tous les modules).
A n'utiliser qu'en cas d'erreur de saisie. A n'utiliser qu'en cas d'erreur de saisie.
S'il s'agit d'un semestre extérieur et qu'il n'y a plus d'inscrit, S'il s'agit d'un semestre extérieur et qu'il n'y a plus d'inscrit,
le semestre sera supprimé. le semestre sera supprimé.
@ -1506,13 +1506,15 @@ def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False)
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
if nt.etud_has_decision(etudid): if nt.etud_has_decision(etudid):
raise ScoValueError( raise ScoValueError(
"""Désinscription impossible: l'étudiant a une décision de jury f"""Désinscription impossible: l'étudiant a une décision de jury
(la supprimer avant si nécessaire: (la supprimer avant si nécessaire:
<a href="formsemestre_validation_suppress_etud?etudid=%s&formsemestre_id=%s"> <a href="{
supprimer décision jury</a> url_for("notes.formsemestre_validation_suppress_etud",
scodoc_dept=g.scodoc_dept, etudid=etudid,
formsemestre_id=formsemestre_id)
}">supprimer décision jury</a>
) )
""" """
% (etudid, formsemestre_id)
) )
if not dialog_confirmed: if not dialog_confirmed:
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
@ -1542,14 +1544,18 @@ def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False)
) )
nbinscrits = len(inscrits) nbinscrits = len(inscrits)
if nbinscrits <= 1: if nbinscrits <= 1:
msg_ext = """<p class="warning">Attention: le semestre extérieur sera supprimé msg_ext = """<p class="warning">Attention: le semestre extérieur
car il n'a pas d'autre étudiant inscrit. sera supprimé car il n'a pas d'autre étudiant inscrit.
</p> </p>
""" """
return scu.confirm_dialog( return scu.confirm_dialog(
"""<h2>Confirmer la demande de desinscription ?</h2>""" + msg_ext, """<h2>Confirmer la demande de désinscription ?</h2>""" + msg_ext,
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={"etudid": etudid, "formsemestre_id": formsemestre_id}, parameters={"etudid": etudid, "formsemestre_id": formsemestre_id},
) )
@ -1557,11 +1563,9 @@ def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False)
etudid, formsemestre_id etudid, formsemestre_id
) )
return ( flash("Étudiant désinscrit")
html_sco_header.sco_header() return redirect(
+ '<p>Etudiant désinscrit !</p><p><a class="stdlink" href="%s">retour à la fiche</a>' url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
+ html_sco_header.sco_footer()
) )

View File

@ -1708,7 +1708,7 @@ def etudident_delete(etudid, dialog_confirmed=False):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
etuds = sco_etud.etudident_list(cnx, {"etudid": etudid}) etuds = sco_etud.etudident_list(cnx, {"etudid": etudid})
if not etuds: if not etuds:
raise ScoValueError("Etudiant inexistant !") raise ScoValueError("Étudiant inexistant !")
else: else:
etud = etuds[0] etud = etuds[0]
sco_etud.fill_etuds_info([etud]) sco_etud.fill_etuds_info([etud])
@ -1789,7 +1789,7 @@ def check_group_apogee(group_id, etat=None, fix=False, fixmail=False):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
H = [ H = [
html_sco_header.html_sem_header( html_sco_header.html_sem_header(
"Etudiants du %s" % (group["group_name"] or "semestre") "Étudiants du %s" % (group["group_name"] or "semestre")
), ),
'<table class="sortable" id="listegroupe">', '<table class="sortable" id="listegroupe">',
"<tr><th>Nom</th><th>Nom usuel</th><th>Prénom</th><th>Mail</th><th>NIP (ScoDoc)</th><th>Apogée</th></tr>", "<tr><th>Nom</th><th>Nom usuel</th><th>Prénom</th><th>Mail</th><th>NIP (ScoDoc)</th><th>Apogée</th></tr>",