diff --git a/app/models/etudiants.py b/app/models/etudiants.py index 61fd3e238..7ee87d418 100644 --- a/app/models/etudiants.py +++ b/app/models/etudiants.py @@ -551,7 +551,7 @@ class Identite(models.ScoDocModel): .all() ) - def inscription_courante(self): + def inscription_courante(self) -> "FormSemestreInscription | None": """La première inscription à un formsemestre _actuellement_ en cours. None s'il n'y en a pas (ou plus, ou pas encore). """ diff --git a/app/scodoc/sco_find_etud.py b/app/scodoc/sco_find_etud.py index d86f4dee0..eeb5c6d7b 100644 --- a/app/scodoc/sco_find_etud.py +++ b/app/scodoc/sco_find_etud.py @@ -32,8 +32,7 @@ from flask import url_for, g, request from flask_login import current_user import app -from app.models import Departement -import app.scodoc.sco_utils as scu +from app.models import Departement, Identite import app.scodoc.notesdb as ndb from app.scodoc.gen_tables import GenTable from app.scodoc import html_sco_header @@ -55,7 +54,9 @@ def form_search_etud( "form recherche par nom" H = [] H.append( - f"""
+ f""" {title} @@ -100,9 +101,9 @@ def form_search_etud( return "\n".join(H) -def search_etuds_infos_from_exp(expnom: str = "") -> list[dict]: +def search_etuds_infos_from_exp(expnom: str = "") -> list[Identite]: """Cherche étudiants, expnom peut être, dans cet ordre: - un etudid (int), un code NIP, ou le début d'un nom. + un etudid (int), un code NIP, ou une partie d'un nom (case insensitive). """ if not isinstance(expnom, int) and len(expnom) <= 1: return [] # si expnom est trop court, n'affiche rien @@ -111,13 +112,22 @@ def search_etuds_infos_from_exp(expnom: str = "") -> list[dict]: except ValueError: etudid = None if etudid is not None: - etuds = sco_etud.get_etud_info(filled=True, etudid=expnom) - if len(etuds) == 1: - return etuds + etud = Identite.query.filter_by(dept_id=g.scodoc_dept_id, id=etudid).first() + if etud: + return [etud] expnom_str = str(expnom) if scu.is_valid_code_nip(expnom_str): - return search_etuds_infos(code_nip=expnom_str) - return search_etuds_infos(expnom=expnom_str) + etuds = Identite.query.filter_by( + dept_id=g.scodoc_dept_id, code_nip=expnom_str + ).all() + if etuds: + return etuds + + return ( + Identite.query.filter_by(dept_id=g.scodoc_dept_id) + .filter(Identite.nom.op("~*")(expnom_str)) + .all() + ) def search_etud_in_dept(expnom=""): @@ -152,7 +162,7 @@ def search_etud_in_dept(expnom=""): if len(etuds) == 1: # va directement a la fiche - url_args["etudid"] = etuds[0]["etudid"] + url_args["etudid"] = etuds[0].id return flask.redirect(url_for(endpoint, **url_args)) H = [ @@ -179,14 +189,39 @@ def search_etud_in_dept(expnom=""): ) if len(etuds) > 0: # Choix dans la liste des résultats: + rows = [] + e: Identite for e in etuds: - url_args["etudid"] = e["etudid"] + url_args["etudid"] = e.id target = url_for(endpoint, **url_args) - e["_nomprenom_target"] = target - e["inscription_target"] = target - e["_nomprenom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"]) - sco_groups.etud_add_group_infos( - e, e["cursem"]["formsemestre_id"] if e["cursem"] else None + cur_inscription = e.inscription_courante() + inscription = ( + e.inscription_descr().get("inscription_str", "") + if cur_inscription + else "" + ) + groupes = ( + ", ".join( + gr.group_name + for gr in sco_groups.get_etud_formsemestre_groups( + e, cur_inscription.formsemestre + ) + ) + if cur_inscription + else "" + ) + + rows.append( + { + "code_nip": e.code_nip or "", + "etudid": e.id, + "inscription": inscription, + "inscription_target": target, + "groupes": groupes, + "nomprenom": e.nomprenom, + "_nomprenom_target": target, + "_nomprenom_td_attrs": f'id="{e.id}" class="etudinfo"', + } ) tab = GenTable( @@ -197,7 +232,7 @@ def search_etud_in_dept(expnom=""): "inscription": "Inscription", "groupes": "Groupes", }, - rows=etuds, + rows=rows, html_sortable=True, html_class="table_leftalign", preferences=sco_preferences.SemPreferences(), @@ -213,15 +248,16 @@ def search_etud_in_dept(expnom=""): ) ) else: - H.append('

Aucun résultat pour "%s".

' % expnom) + H.append(f'

Aucun résultat pour "{expnom}".

') H.append( - """

La recherche porte sur tout ou partie du NOM ou du NIP de l'étudiant. Saisir au moins deux caractères.

""" + """

La recherche porte sur tout ou partie du NOM ou du NIP + de l'étudiant. Saisir au moins deux caractères.

""" ) return "\n".join(H) + html_sco_header.sco_footer() # Was chercheEtudsInfo() -def search_etuds_infos(expnom=None, code_nip=None): +def search_etuds_infos(expnom=None, code_nip=None) -> list[dict]: """recherche les étudiants correspondants à expnom ou au code_nip et ramene liste de mappings utilisables en DTML. """ diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index 614d2852b..4178c0de3 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -843,7 +843,7 @@ FORBIDDEN_CHARS_EXP = re.compile(r"[*\|~\(\)\\]") ALPHANUM_EXP = re.compile(r"^[\w-]+$", re.UNICODE) -def is_valid_code_nip(s: str) -> bool: +def is_valid_code_nip(s: str) -> bool | None: """True si s peut être un code NIP: au moins 6 chiffres décimaux""" if not s: return False