Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
3 changed files with 59 additions and 23 deletions
Showing only changes of commit fbff151be0 - Show all commits

View File

@ -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).
"""

View File

@ -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"""<form action="{ url_for("scolar.search_etud_in_dept", scodoc_dept=g.scodoc_dept) }" method="POST">
f"""<form action="{
url_for("scolar.search_etud_in_dept", scodoc_dept=g.scodoc_dept)
}" method="POST">
<b>{title}</b>
<input type="text" name="expnom" class="in-expnom" width="12" spellcheck="false" value="">
<input type="submit" value="Chercher">
@ -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('<h2 style="color: red;">Aucun résultat pour "%s".</h2>' % expnom)
H.append(f'<h2 style="color: red;">Aucun résultat pour "{expnom}".</h2>')
H.append(
"""<p class="help">La recherche porte sur tout ou partie du NOM ou du NIP de l'étudiant. Saisir au moins deux caractères.</p>"""
"""<p class="help">La recherche porte sur tout ou partie du NOM ou du NIP
de l'étudiant. Saisir au moins deux caractères.</p>"""
)
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.
"""

View File

@ -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