forked from ScoDoc/ScoDoc
RGPD: protection optionnelle des données perso étudiantes (ViewEtudData) sur fiche_etud
This commit is contained in:
parent
7659bcb488
commit
9c1c316f14
@ -66,7 +66,7 @@ def _news_delete_jury_etud(etud: Identite):
|
||||
"génère news sur effacement décision"
|
||||
# n'utilise pas g.scodoc_dept, pas toujours dispo en mode API
|
||||
url = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=etud.departement.acronym, etudid=etud.id
|
||||
"scolar.fiche_etud", scodoc_dept=etud.departement.acronym, etudid=etud.id
|
||||
)
|
||||
ScolarNews.add(
|
||||
typ=ScolarNews.NEWS_JURY,
|
||||
|
@ -154,7 +154,7 @@ def pvjury_table_but(
|
||||
"_nom_target_attrs": f'class="etudinfo" id="{etud.id}"',
|
||||
"_nom_td_attrs": f'id="{etud.id}" class="etudinfo"',
|
||||
"_nom_target": url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud.id,
|
||||
),
|
||||
|
@ -447,7 +447,7 @@ def jury_but_semestriel(
|
||||
<div class="nom_etud">{etud.nomprenom}</div>
|
||||
</div>
|
||||
<div class="bull_photo"><a href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -234,7 +234,7 @@ class ResultatsSemestreClassic(NotesTableCompat):
|
||||
raise ScoValueError(
|
||||
f"""<div class="scovalueerror"><p>Coefficient de l'UE capitalisée {ue.acronyme}
|
||||
impossible à déterminer pour l'étudiant <a href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}" class="discretelink">{etud.nom_disp()}</a></p>
|
||||
<p>Il faut <a href="{
|
||||
url_for("notes.formsemestre_edit_uecoefs", scodoc_dept=g.scodoc_dept,
|
||||
|
@ -119,6 +119,9 @@ class Identite(models.ScoDocModel):
|
||||
"Justificatif", back_populates="etudiant", lazy="dynamic", cascade="all, delete"
|
||||
)
|
||||
|
||||
# Champs "protégés" par ViewEtudData (RGPD)
|
||||
protected_attrs = {"boursier"}
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"<Etud {self.id}/{self.departement.acronym} {self.nom!r} {self.prenom!r}>"
|
||||
@ -176,7 +179,7 @@ class Identite(models.ScoDocModel):
|
||||
def url_fiche(self) -> str:
|
||||
"url de la fiche étudiant"
|
||||
return url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=self.departement.acronym, etudid=self.id
|
||||
"scolar.fiche_etud", scodoc_dept=self.departement.acronym, etudid=self.id
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -433,9 +436,10 @@ class Identite(models.ScoDocModel):
|
||||
"prenom_etat_civil": self.prenom_etat_civil,
|
||||
}
|
||||
|
||||
def to_dict_scodoc7(self) -> dict:
|
||||
def to_dict_scodoc7(self, restrict=False) -> dict:
|
||||
"""Représentation dictionnaire,
|
||||
compatible ScoDoc7 mais sans infos admission
|
||||
compatible ScoDoc7 mais sans infos admission.
|
||||
Si restrict, cache les infos "personnelles" si pas permission ViewEtudData
|
||||
"""
|
||||
e_dict = self.__dict__.copy() # dict(self.__dict__)
|
||||
e_dict.pop("_sa_instance_state", None)
|
||||
@ -446,7 +450,7 @@ class Identite(models.ScoDocModel):
|
||||
e_dict["nomprenom"] = self.nomprenom
|
||||
adresse = self.adresses.first()
|
||||
if adresse:
|
||||
e_dict.update(adresse.to_dict())
|
||||
e_dict.update(adresse.to_dict(restrict=restrict))
|
||||
return {k: v or "" for k, v in e_dict.items()} # convert_null_outputs_to_empty
|
||||
|
||||
def to_dict_bul(self, include_urls=True):
|
||||
@ -481,7 +485,7 @@ class Identite(models.ScoDocModel):
|
||||
if include_urls and has_request_context():
|
||||
# test request context so we can use this func in tests under the flask shell
|
||||
d["fiche_url"] = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=self.id
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=self.id
|
||||
)
|
||||
d["photo_url"] = sco_photos.get_etud_photo_url(self.id)
|
||||
adresse = self.adresses.first()
|
||||
@ -825,12 +829,25 @@ class Adresse(models.ScoDocModel):
|
||||
)
|
||||
description = db.Column(db.Text)
|
||||
|
||||
def to_dict(self, convert_nulls_to_str=False):
|
||||
"""Représentation dictionnaire,"""
|
||||
# Champs "protégés" par ViewEtudData (RGPD)
|
||||
protected_attrs = {
|
||||
"emailperso",
|
||||
"domicile",
|
||||
"codepostaldomicile",
|
||||
"villedomicile",
|
||||
"telephone",
|
||||
"telephonemobile",
|
||||
"fax",
|
||||
}
|
||||
|
||||
def to_dict(self, convert_nulls_to_str=False, restrict=False):
|
||||
"""Représentation dictionnaire. Si restrict, filtre les champs protégés (RGPD)."""
|
||||
e = dict(self.__dict__)
|
||||
e.pop("_sa_instance_state", None)
|
||||
if convert_nulls_to_str:
|
||||
return {k: e[k] or "" for k in e}
|
||||
e = {k: v or "" for k, v in e.items()}
|
||||
if restrict:
|
||||
e = {k: v for (k, v) in e.items() if k not in self.protected_attrs}
|
||||
return e
|
||||
|
||||
|
||||
@ -885,12 +902,16 @@ class Admission(models.ScoDocModel):
|
||||
# classement (1..Ngr) par le jury dans le groupe APB
|
||||
apb_classement_gr = db.Column(db.Integer)
|
||||
|
||||
# Tous les champs sont "protégés" par ViewEtudData (RGPD)
|
||||
# sauf:
|
||||
not_protected_attrs = {"bac", "specialite", "anne_bac"}
|
||||
|
||||
def get_bac(self) -> Baccalaureat:
|
||||
"Le bac. utiliser bac.abbrev() pour avoir une chaine de caractères."
|
||||
return Baccalaureat(self.bac, specialite=self.specialite)
|
||||
|
||||
def to_dict(self, no_nulls=False):
|
||||
"""Représentation dictionnaire,"""
|
||||
def to_dict(self, no_nulls=False, restrict=False):
|
||||
"""Représentation dictionnaire. Si restrict, filtre les champs protégés (RGPD)."""
|
||||
d = dict(self.__dict__)
|
||||
d.pop("_sa_instance_state", None)
|
||||
if no_nulls:
|
||||
@ -905,6 +926,8 @@ class Admission(models.ScoDocModel):
|
||||
d[key] = 0
|
||||
elif isinstance(col_type, sqlalchemy.Boolean):
|
||||
d[key] = False
|
||||
if restrict:
|
||||
d = {k: v for (k, v) in d.items() if k in self.not_protected_attrs}
|
||||
return d
|
||||
|
||||
@classmethod
|
||||
|
@ -455,7 +455,9 @@ class JuryPE(object):
|
||||
|
||||
reponse = False
|
||||
etud = self.get_cache_etudInfo_d_un_etudiant(etudid)
|
||||
(_, parcours) = sco_report.get_code_cursus_etud(etud)
|
||||
(_, parcours) = sco_report.get_code_cursus_etud(
|
||||
etud["etudid"], sems=etud["sems"]
|
||||
)
|
||||
if (
|
||||
len(codes_cursus.CODES_SEM_REO & set(parcours.values())) > 0
|
||||
): # Eliminé car NAR apparait dans le parcours
|
||||
@ -527,7 +529,7 @@ class JuryPE(object):
|
||||
|
||||
etud = self.get_cache_etudInfo_d_un_etudiant(etudid)
|
||||
(code, parcours) = sco_report.get_code_cursus_etud(
|
||||
etud
|
||||
etud["etudid"], sems=etud["sems"]
|
||||
) # description = '1234:A', parcours = {1:ADM, 2:NAR, ...}
|
||||
sonDernierSemestreValide = max(
|
||||
[
|
||||
|
@ -107,7 +107,7 @@ def sidebar(etudid: int = None):
|
||||
etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
|
||||
params.update(etud)
|
||||
params["fiche_url"] = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
)
|
||||
# compte les absences du semestre en cours
|
||||
H.append(
|
||||
|
@ -129,7 +129,7 @@ def table_billets(
|
||||
] = f'id="{billet.etudiant.id}" class="etudinfo"'
|
||||
if with_links:
|
||||
billet_dict["_nomprenom_target"] = url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=billet_dict["etudid"],
|
||||
)
|
||||
|
@ -34,7 +34,7 @@ Il suffit d'appeler abs_notify() après chaque ajout d'absence.
|
||||
import datetime
|
||||
from typing import Optional
|
||||
|
||||
from flask import current_app, g, url_for
|
||||
from flask import g, url_for
|
||||
from flask_mail import Message
|
||||
|
||||
from app import db
|
||||
@ -42,6 +42,7 @@ from app import email
|
||||
from app import log
|
||||
from app.auth.models import User
|
||||
from app.models.absences import AbsenceNotification
|
||||
from app.models.etudiants import Identite
|
||||
from app.models.events import Scolog
|
||||
from app.models.formsemestre import FormSemestre
|
||||
import app.scodoc.notesdb as ndb
|
||||
@ -175,9 +176,15 @@ def abs_notify_get_destinations(
|
||||
if prefs["abs_notify_email"]:
|
||||
destinations.append(prefs["abs_notify_email"])
|
||||
if prefs["abs_notify_etud"]:
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
if etud["email_default"]:
|
||||
destinations.append(etud["email_default"])
|
||||
etud = Identite.get_etud(etudid)
|
||||
adresse = etud.adresses.first()
|
||||
if adresse:
|
||||
# Mail à utiliser pour les envois vers l'étudiant:
|
||||
# choix qui pourrait être controlé par une preference
|
||||
# ici priorité au mail institutionnel:
|
||||
email_default = adresse.email or adresse.emailperso
|
||||
if email_default:
|
||||
destinations.append(email_default)
|
||||
|
||||
# Notification (à chaque fois) des resp. de modules ayant des évaluations
|
||||
# à cette date
|
||||
@ -271,7 +278,7 @@ def abs_notification_message(
|
||||
values["nbabsjust"] = nbabsjust
|
||||
values["nbabsnonjust"] = nbabs - nbabsjust
|
||||
values["url_ficheetud"] = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid, _external=True
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid, _external=True
|
||||
)
|
||||
|
||||
template = prefs["abs_notification_mail_tmpl"]
|
||||
|
@ -177,7 +177,7 @@ def etud_upload_file_form(etudid):
|
||||
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
else:
|
||||
data = tf[2]["datafile"].read()
|
||||
@ -188,7 +188,7 @@ def etud_upload_file_form(etudid):
|
||||
etud_archive_id, data, filename, description=descr
|
||||
)
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
|
||||
|
||||
@ -228,7 +228,7 @@ def etud_delete_archive(etudid, archive_name, dialog_confirmed=False):
|
||||
),
|
||||
dest_url="",
|
||||
cancel_url=url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etudid,
|
||||
head_message="annulation",
|
||||
@ -239,7 +239,7 @@ def etud_delete_archive(etudid, archive_name, dialog_confirmed=False):
|
||||
ETUDS_ARCHIVER.delete_archive(archive_id, dept_id=etud["dept_id"])
|
||||
flash("Archive supprimée")
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
|
||||
|
||||
|
@ -39,7 +39,6 @@ from app import log
|
||||
from app.scodoc.scolog import logdb
|
||||
from app.scodoc import sco_cache, sco_etud
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formations
|
||||
from app.scodoc.codes_cursus import (
|
||||
CMP,
|
||||
ADC,
|
||||
|
@ -134,10 +134,10 @@ def table_debouche_etudids(etudids, keep_numeric=True):
|
||||
"nom": etud["nom"],
|
||||
"prenom": etud["prenom"],
|
||||
"_nom_target": url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
),
|
||||
"_prenom_target": url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
),
|
||||
"_nom_td_attrs": 'id="%s" class="etudinfo"' % (etud["etudid"]),
|
||||
# 'debouche' : etud['debouche'],
|
||||
|
@ -542,7 +542,9 @@ def view_scodoc_etuds(semset_id, title="", nip_list="", fmt="html"):
|
||||
etuds = [sco_etud.get_etud_info(code_nip=nip, filled=True)[0] for nip in nips]
|
||||
|
||||
for e in etuds:
|
||||
tgt = url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=e["etudid"])
|
||||
tgt = url_for(
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=e["etudid"]
|
||||
)
|
||||
e["_nom_target"] = tgt
|
||||
e["_prenom_target"] = tgt
|
||||
e["_nom_td_attrs"] = f"""id="{e['etudid']}" class="etudinfo" """
|
||||
@ -770,7 +772,7 @@ def view_apo_csv(etape_apo="", semset_id="", fmt="html"):
|
||||
e["in_scodoc_str"] = {True: "oui", False: "non"}[e["in_scodoc"]]
|
||||
if e["in_scodoc"]:
|
||||
e["_in_scodoc_str_target"] = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, code_nip=e["nip"]
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=e["etudid"]
|
||||
)
|
||||
e.update(sco_etud.get_etud_info(code_nip=e["nip"], filled=True)[0])
|
||||
e["_nom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"],)
|
||||
|
@ -692,7 +692,7 @@ class EtapeBilan:
|
||||
@staticmethod
|
||||
def link_etu(etudid, nom):
|
||||
return '<a class="stdlink" href="%s">%s</a>' % (
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
nom,
|
||||
)
|
||||
|
||||
|
@ -64,7 +64,7 @@ def format_etud_ident(etud: dict):
|
||||
|
||||
Note: par rapport à Identite.to_dict_bul(),
|
||||
ajoute les champs:
|
||||
'email_default', 'nom_disp', 'nom_usuel', 'civilite_etat_civil_str', 'ne', 'civilite_str'
|
||||
'nom_disp', 'nom_usuel', 'civilite_etat_civil_str', 'ne', 'civilite_str'
|
||||
"""
|
||||
etud["nom"] = format_nom(etud["nom"])
|
||||
if "nom_usuel" in etud:
|
||||
@ -98,10 +98,6 @@ def format_etud_ident(etud: dict):
|
||||
etud["ne"] = "e"
|
||||
else: # 'X'
|
||||
etud["ne"] = "(e)"
|
||||
# Mail à utiliser pour les envois vers l'étudiant:
|
||||
# choix qui pourrait être controé par une preference
|
||||
# ici priorité au mail institutionnel:
|
||||
etud["email_default"] = etud.get("email", "") or etud.get("emailperso", "")
|
||||
|
||||
|
||||
def force_uppercase(s):
|
||||
@ -117,36 +113,6 @@ def _format_etat_civil(etud: dict) -> str:
|
||||
return etud["nomprenom"]
|
||||
|
||||
|
||||
def format_lycee(nomlycee):
|
||||
nomlycee = nomlycee.strip()
|
||||
s = nomlycee.lower()
|
||||
if s[:5] == "lycee" or s[:5] == "lycée":
|
||||
return nomlycee[5:]
|
||||
else:
|
||||
return nomlycee
|
||||
|
||||
|
||||
def format_telephone(n):
|
||||
if n is None:
|
||||
return ""
|
||||
if len(n) < 7:
|
||||
return n
|
||||
else:
|
||||
n = n.replace(" ", "").replace(".", "")
|
||||
i = 0
|
||||
r = ""
|
||||
j = len(n) - 1
|
||||
while j >= 0:
|
||||
r = n[j] + r
|
||||
if i % 2 == 1 and j != 0:
|
||||
r = " " + r
|
||||
i += 1
|
||||
j -= 1
|
||||
if len(r) == 13 and r[0] != "0":
|
||||
r = "0" + r
|
||||
return r
|
||||
|
||||
|
||||
def format_pays(s):
|
||||
"laisse le pays seulement si != FRANCE"
|
||||
if s.upper() != "FRANCE":
|
||||
@ -283,14 +249,14 @@ def _check_duplicate_code(cnx, args, code_name, disable_notify=False, edit=True)
|
||||
listh.append(
|
||||
f"""Autre étudiant: <a href="{
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=e["etudid"]
|
||||
)}">{e['nom']} {e['prenom']}</a>"""
|
||||
)
|
||||
if etudid:
|
||||
OK = "retour à la fiche étudiant"
|
||||
dest_endpoint = "scolar.ficheEtud"
|
||||
dest_endpoint = "scolar.fiche_etud"
|
||||
parameters = {"etudid": etudid}
|
||||
else:
|
||||
if "tf_submitted" in args:
|
||||
@ -619,7 +585,7 @@ def create_etud(cnx, args: dict = None):
|
||||
etud_dict = etudident_list(cnx, {"etudid": etudid})[0]
|
||||
fill_etuds_info([etud_dict])
|
||||
etud_dict["url"] = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
)
|
||||
ScolarNews.add(
|
||||
typ=ScolarNews.NEWS_INSCR,
|
||||
@ -724,19 +690,28 @@ def get_etablissements():
|
||||
|
||||
|
||||
def get_lycee_infos(codelycee):
|
||||
E = get_etablissements()
|
||||
return E.get(codelycee, None)
|
||||
etablissements = get_etablissements()
|
||||
return etablissements.get(codelycee, None)
|
||||
|
||||
|
||||
def format_lycee_from_code(codelycee):
|
||||
def format_lycee_from_code(codelycee: str) -> str:
|
||||
"Description lycee à partir du code"
|
||||
E = get_etablissements()
|
||||
if codelycee in E:
|
||||
e = E[codelycee]
|
||||
etablissements = get_etablissements()
|
||||
if codelycee in etablissements:
|
||||
e = etablissements[codelycee]
|
||||
nomlycee = e["name"]
|
||||
return "%s (%s)" % (nomlycee, e["commune"])
|
||||
return f"{nomlycee} ({e['commune']})"
|
||||
return f"{codelycee} (établissement inconnu)"
|
||||
|
||||
|
||||
def format_lycee(nomlycee: str) -> str:
|
||||
"mise en forme nom de lycée"
|
||||
nomlycee = nomlycee.strip()
|
||||
s = nomlycee.lower()
|
||||
if s[:5] == "lycee" or s[:5] == "lycée":
|
||||
return nomlycee[5:]
|
||||
else:
|
||||
return "%s (établissement inconnu)" % codelycee
|
||||
return nomlycee
|
||||
|
||||
|
||||
def etud_add_lycee_infos(etud):
|
||||
@ -821,36 +796,6 @@ def fill_etuds_info(etuds: list[dict], add_admission=True):
|
||||
# nettoyage champs souvent vides
|
||||
etud["codepostallycee"] = etud.get("codepostallycee", "") or ""
|
||||
etud["nomlycee"] = etud.get("nomlycee", "") or ""
|
||||
if etud.get("nomlycee"):
|
||||
etud["ilycee"] = "Lycée " + format_lycee(etud["nomlycee"])
|
||||
if etud["villelycee"]:
|
||||
etud["ilycee"] += " (%s)" % etud.get("villelycee", "")
|
||||
etud["ilycee"] += "<br>"
|
||||
else:
|
||||
if etud.get("codelycee"):
|
||||
etud["ilycee"] = format_lycee_from_code(etud["codelycee"])
|
||||
else:
|
||||
etud["ilycee"] = ""
|
||||
rap = ""
|
||||
if etud.get("rapporteur") or etud.get("commentaire"):
|
||||
rap = "Note du rapporteur"
|
||||
if etud.get("rapporteur"):
|
||||
rap += " (%s)" % etud["rapporteur"]
|
||||
rap += ": "
|
||||
if etud.get("commentaire"):
|
||||
rap += "<em>%s</em>" % etud["commentaire"]
|
||||
etud["rap"] = rap
|
||||
|
||||
if etud.get("telephone"):
|
||||
etud["telephonestr"] = "<b>Tél.:</b> " + format_telephone(etud["telephone"])
|
||||
else:
|
||||
etud["telephonestr"] = ""
|
||||
if etud.get("telephonemobile"):
|
||||
etud["telephonemobilestr"] = "<b>Mobile:</b> " + format_telephone(
|
||||
etud["telephonemobile"]
|
||||
)
|
||||
else:
|
||||
etud["telephonemobilestr"] = ""
|
||||
|
||||
|
||||
def etud_inscriptions_infos(etudid: int, ne="") -> dict:
|
||||
|
@ -156,7 +156,7 @@ def evaluation_check_absences_html(
|
||||
H.append(
|
||||
f"""<li><a class="discretelink" href="{
|
||||
url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
)
|
||||
}">{etud.nomprenom}</a>"""
|
||||
)
|
||||
|
@ -173,9 +173,10 @@ def _build_results_list(dpv_by_sem, etuds_infos):
|
||||
"nom_usuel": etud["nom_usuel"],
|
||||
"prenom": etud["prenom"],
|
||||
"civilite_str": etud["civilite_str"],
|
||||
"_nom_target": "%s"
|
||||
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
"_nom_td_attrs": 'id="%s" class="etudinfo"' % etudid,
|
||||
"_nom_target": url_for(
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
),
|
||||
"_nom_td_attrs": f'id="{etudid}" class="etudinfo"',
|
||||
"bac": bac.abbrev(),
|
||||
"parcours": dec["parcours"],
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ def search_etud_in_dept(expnom=""):
|
||||
if "dest_url" in vals:
|
||||
endpoint = vals["dest_url"]
|
||||
else:
|
||||
endpoint = "scolar.ficheEtud"
|
||||
endpoint = "scolar.fiche_etud"
|
||||
if "parameters_keys" in vals:
|
||||
for key in vals["parameters_keys"].split(","):
|
||||
url_args[key] = vals[key]
|
||||
@ -328,8 +328,9 @@ def table_etud_in_accessible_depts(expnom=None):
|
||||
"""
|
||||
result, accessible_depts = search_etud_in_accessible_depts(expnom=expnom)
|
||||
H = [
|
||||
"""<div class="table_etud_in_accessible_depts">""",
|
||||
"""<h3>Recherche multi-département de "<tt>%s</tt>"</h3>""" % expnom,
|
||||
f"""<div class="table_etud_in_accessible_depts">
|
||||
<h3>Recherche multi-département de "<tt>{expnom}</tt>"</h3>
|
||||
""",
|
||||
]
|
||||
for etuds in result:
|
||||
if etuds:
|
||||
@ -337,9 +338,9 @@ def table_etud_in_accessible_depts(expnom=None):
|
||||
# H.append('<h3>Département %s</h3>' % DeptId)
|
||||
for e in etuds:
|
||||
e["_nomprenom_target"] = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=dept_id, etudid=e["etudid"]
|
||||
"scolar.fiche_etud", scodoc_dept=dept_id, etudid=e["etudid"]
|
||||
)
|
||||
e["_nomprenom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"])
|
||||
e["_nomprenom_td_attrs"] = f"""id="{e['etudid']}" class="etudinfo" """
|
||||
|
||||
tab = GenTable(
|
||||
titles={"nomprenom": "Étudiants en " + dept_id},
|
||||
|
@ -102,7 +102,7 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
|
||||
scodoc_dept=g.scodoc_dept, etudid=etudid, only_ext=1) }">
|
||||
inscrire à un autre semestre</a>"
|
||||
</p>
|
||||
<h3><a href="{ url_for('scolar.ficheEtud',
|
||||
<h3><a href="{ url_for('scolar.fiche_etud',
|
||||
scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}" class="stdlink">Étudiant {etud.nomprenom}</a></h3>
|
||||
""",
|
||||
@ -221,7 +221,7 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
|
||||
tf[2]["formation_id"] = orig_sem["formation_id"]
|
||||
formsemestre_ext_create(etudid, tf[2])
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
|
||||
|
||||
|
@ -400,7 +400,7 @@ def formsemestre_inscription_with_modules_form(etudid, only_ext=False):
|
||||
H.append("<p>aucune session de formation !</p>")
|
||||
H.append(
|
||||
f"""<h3>ou</h3> <a class="stdlink" href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">retour à la fiche de {etud.nomprenom}</a>"""
|
||||
)
|
||||
return "\n".join(H) + footer
|
||||
@ -440,7 +440,7 @@ def formsemestre_inscription_with_modules(
|
||||
dans le semestre {formsemestre.titre_mois()}
|
||||
</p>
|
||||
<ul>
|
||||
<li><a href="{url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
<li><a href="{url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}" class="stdlink">retour à la fiche de {etud.nomprenom}</a>
|
||||
</li>
|
||||
<li><a href="{url_for(
|
||||
@ -501,7 +501,7 @@ def formsemestre_inscription_with_modules(
|
||||
method="formsemestre_inscription_with_modules",
|
||||
)
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
else:
|
||||
# formulaire choix groupe
|
||||
@ -656,7 +656,7 @@ function chkbx_select(field_id, state) {
|
||||
return "\n".join(H) + "\n" + tf[1] + footer
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
else:
|
||||
# Inscriptions aux modules choisis
|
||||
@ -697,7 +697,7 @@ function chkbx_select(field_id, state) {
|
||||
"""<h3>Aucune modification à effectuer</h3>
|
||||
<p><a class="stdlink" href="%s">retour à la fiche étudiant</a></p>
|
||||
"""
|
||||
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
% url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
return "\n".join(H) + footer
|
||||
|
||||
@ -755,7 +755,7 @@ function chkbx_select(field_id, state) {
|
||||
etudid,
|
||||
modulesimpls_ainscrire,
|
||||
modulesimpls_adesinscrire,
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
)
|
||||
)
|
||||
return "\n".join(H) + footer
|
||||
@ -820,7 +820,7 @@ def do_moduleimpl_incription_options(
|
||||
<p><a class="stdlink" href="%s">
|
||||
Retour à la fiche étudiant</a></p>
|
||||
"""
|
||||
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
% url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
return "\n".join(H)
|
||||
@ -885,7 +885,7 @@ def formsemestre_inscrits_ailleurs(formsemestre_id):
|
||||
'<li><a href="%s" class="discretelink">%s</a> : '
|
||||
% (
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud["etudid"],
|
||||
),
|
||||
|
@ -1457,7 +1457,7 @@ def formsemestre_warning_etuds_sans_note(
|
||||
noms = ", ".join(
|
||||
[
|
||||
f"""<a href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}" class="discretelink">{etud.nomprenom}</a>"""
|
||||
for etud in etuds
|
||||
]
|
||||
@ -1519,13 +1519,13 @@ def formsemestre_note_etuds_sans_notes(
|
||||
a déjà des notes"""
|
||||
)
|
||||
return redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
else:
|
||||
noms = "</li><li>".join(
|
||||
[
|
||||
f"""<a href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}" class="discretelink">{etud.nomprenom}</a>"""
|
||||
for etud in etuds
|
||||
]
|
||||
|
@ -117,8 +117,8 @@ def formsemestre_validation_etud_form(
|
||||
if read_only:
|
||||
check = True
|
||||
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
|
||||
etud_d = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
Se = sco_cursus.get_situation_etud_cursus(etud_d, formsemestre_id)
|
||||
if not Se.sem["etat"]:
|
||||
raise ScoValueError("validation: semestre verrouille")
|
||||
|
||||
@ -132,7 +132,7 @@ def formsemestre_validation_etud_form(
|
||||
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title=f"Parcours {etud['nomprenom']}",
|
||||
page_title=f"Parcours {etud.nomprenom}",
|
||||
javascripts=["js/recap_parcours.js"],
|
||||
)
|
||||
]
|
||||
@ -177,26 +177,22 @@ def formsemestre_validation_etud_form(
|
||||
H.append('<table style="width: 100%"><tr><td>')
|
||||
if not check:
|
||||
H.append(
|
||||
'<h2 class="formsemestre">%s: validation %s%s</h2>Parcours: %s'
|
||||
% (
|
||||
etud["nomprenom"],
|
||||
Se.parcours.SESSION_NAME_A,
|
||||
Se.parcours.SESSION_NAME,
|
||||
Se.get_cursus_descr(),
|
||||
)
|
||||
f"""<h2 class="formsemestre">{etud.nomprenom}: validation {
|
||||
Se.parcours.SESSION_NAME_A}{Se.parcours.SESSION_NAME
|
||||
}</h2>Parcours: {Se.get_cursus_descr()}
|
||||
"""
|
||||
)
|
||||
else:
|
||||
H.append(
|
||||
'<h2 class="formsemestre">Parcours de %s</h2>%s'
|
||||
% (etud["nomprenom"], Se.get_cursus_descr())
|
||||
f"""<h2 class="formsemestre">Parcours de {etud.nomprenom}</h2>{Se.get_cursus_descr()}"""
|
||||
)
|
||||
|
||||
H.append(
|
||||
'</td><td style="text-align: right;"><a href="%s">%s</a></td></tr></table>'
|
||||
% (
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
sco_photos.etud_photo_html(etud, title="fiche de %s" % etud["nom"]),
|
||||
)
|
||||
f"""</td><td style="text-align: right;"><a href="{
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a></td></tr>
|
||||
</table>
|
||||
"""
|
||||
)
|
||||
|
||||
etud_etat = nt.get_etud_etat(etudid)
|
||||
@ -210,7 +206,7 @@ def formsemestre_validation_etud_form(
|
||||
<div class="warning">
|
||||
Impossible de statuer sur cet étudiant:
|
||||
il est démissionnaire ou défaillant (voir <a href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">sa fiche</a>)
|
||||
</div>
|
||||
"""
|
||||
@ -289,7 +285,7 @@ def formsemestre_validation_etud_form(
|
||||
etudid=etudid, origin_formsemestre_id=formsemestre_id
|
||||
).all()
|
||||
if autorisations:
|
||||
H.append(". Autorisé%s à s'inscrire en " % etud["ne"])
|
||||
H.append(f". Autorisé{etud.e} à s'inscrire en ")
|
||||
H.append(", ".join([f"S{aut.semestre_id}" for aut in autorisations]) + ".")
|
||||
H.append("</p>")
|
||||
|
||||
|
@ -561,7 +561,7 @@ def groups_table(
|
||||
else:
|
||||
etud["_emailperso_target"] = ""
|
||||
fiche_url = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
|
||||
)
|
||||
etud["_nom_disp_target"] = fiche_url
|
||||
etud["_nom_disp_order"] = etud_sort_key(etud)
|
||||
@ -829,7 +829,9 @@ def groups_table(
|
||||
etud, groups_infos.formsemestre_id
|
||||
)
|
||||
m["parcours"] = Se.get_cursus_descr()
|
||||
m["code_cursus"], _ = sco_report.get_code_cursus_etud(etud)
|
||||
m["code_cursus"], _ = sco_report.get_code_cursus_etud(
|
||||
etud["etudid"], sems=etud["sems"]
|
||||
)
|
||||
rows = [[m.get(k, "") for k in keys] for m in groups_infos.members]
|
||||
title = "etudiants_%s" % groups_infos.groups_filename
|
||||
xls = sco_excel.excel_simple_table(titles=titles, lines=rows, sheet_name=title)
|
||||
|
@ -669,7 +669,7 @@ def etuds_select_boxes(
|
||||
elink = """<a class="discretelink %s" href="%s">%s</a>""" % (
|
||||
c,
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud["etudid"],
|
||||
),
|
||||
|
@ -143,7 +143,9 @@ def _table_etuds_lycees(etuds, group_lycees, title, preferences, no_links=False)
|
||||
if not no_links:
|
||||
for etud in etuds:
|
||||
fiche_url = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud["etudid"],
|
||||
)
|
||||
etud["_nom_target"] = fiche_url
|
||||
etud["_prenom_target"] = fiche_url
|
||||
@ -232,7 +234,7 @@ def js_coords_lycees(etuds_by_lycee):
|
||||
'<a class="discretelink" href="%s" title="">%s</a>'
|
||||
% (
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=e["etudid"],
|
||||
),
|
||||
|
@ -186,7 +186,7 @@ def moduleimpl_inscriptions_edit(
|
||||
H.append(
|
||||
f"""<a class="discretelink etudinfo" href="{
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud["etudid"],
|
||||
)
|
||||
@ -421,7 +421,7 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
|
||||
H.append(
|
||||
f"""<li class="etud"><a class="discretelink" href="{
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud["etudid"],
|
||||
)
|
||||
@ -542,7 +542,7 @@ def _list_but_ue_inscriptions(res: NotesTableCompat, read_only: bool = True) ->
|
||||
H.append(
|
||||
f"""<tr><td><a class="discretelink etudinfo" id={etud.id}
|
||||
href="{url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud.id,
|
||||
)}"
|
||||
@ -694,7 +694,7 @@ def _fmt_etud_set(etudids, max_list_size=7) -> str:
|
||||
[
|
||||
f"""<a class="discretelink" href="{
|
||||
url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||
)
|
||||
}">{etud.nomprenom}</a>"""
|
||||
for etud in sorted(etuds, key=attrgetter("sort_key"))
|
||||
|
@ -25,38 +25,37 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""ScoDoc ficheEtud
|
||||
"""ScoDoc fiche_etud
|
||||
|
||||
Fiche description d'un étudiant et de son parcours
|
||||
|
||||
"""
|
||||
from flask import abort, url_for, g, render_template, request
|
||||
from flask import url_for, g, render_template, request
|
||||
from flask_login import current_user
|
||||
import sqlalchemy as sa
|
||||
|
||||
from app import db, log
|
||||
from app import log
|
||||
from app.auth.models import User
|
||||
from app.but import cursus_but
|
||||
from app.models.etudiants import make_etud_args
|
||||
from app.models import Identite, FormSemestre, ScoDocSiteConfig
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import htmlutils
|
||||
from app.scodoc import sco_archives_etud
|
||||
from app.scodoc import sco_bac
|
||||
from app.scodoc import codes_cursus
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formsemestre_status
|
||||
from app.scodoc import sco_groups
|
||||
from app.scodoc import sco_cursus
|
||||
from app.scodoc import sco_permissions_check
|
||||
from app.scodoc import sco_photos
|
||||
from app.scodoc import sco_users
|
||||
from app.scodoc import sco_report
|
||||
from app.scodoc import sco_etud
|
||||
from app.models import Adresse, EtudAnnotation, FormSemestre, Identite, ScoDocSiteConfig
|
||||
from app.scodoc import (
|
||||
codes_cursus,
|
||||
html_sco_header,
|
||||
htmlutils,
|
||||
sco_archives_etud,
|
||||
sco_bac,
|
||||
sco_cursus,
|
||||
sco_etud,
|
||||
sco_formsemestre_status,
|
||||
sco_groups,
|
||||
sco_permissions_check,
|
||||
sco_report,
|
||||
)
|
||||
from app.scodoc.sco_bulletins import etud_descr_situation_semestre
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc.sco_formsemestre_validation import formsemestre_recap_parcours_table
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
|
||||
|
||||
def _menu_scolarite(
|
||||
@ -157,29 +156,18 @@ def _menu_scolarite(
|
||||
)
|
||||
|
||||
|
||||
def ficheEtud(etudid=None):
|
||||
def fiche_etud(etudid=None):
|
||||
"fiche d'informations sur un etudiant"
|
||||
authuser = current_user
|
||||
cnx = ndb.GetDBConnexion()
|
||||
if etudid:
|
||||
try: # pour les bookmarks avec d'anciens ids...
|
||||
etudid = int(etudid)
|
||||
except ValueError:
|
||||
raise ScoValueError("id invalide !") from ValueError
|
||||
restrict_etud_data = not current_user.has_permission(Permission.ViewEtudData)
|
||||
try:
|
||||
etud = Identite.get_etud(etudid)
|
||||
except Exception as exc:
|
||||
log(f"fiche_etud: etudid={etudid!r} request.args={request.args!r}")
|
||||
raise ScoValueError("Étudiant inexistant !") from exc
|
||||
# la sidebar est differente s'il y a ou pas un etudid
|
||||
# voir html_sidebar.sidebar()
|
||||
g.etudid = etudid
|
||||
args = make_etud_args(etudid=etudid)
|
||||
etuds = sco_etud.etudident_list(cnx, args)
|
||||
if not etuds:
|
||||
log(f"ficheEtud: etudid={etudid!r} request.args={request.args!r}")
|
||||
raise ScoValueError("Étudiant inexistant !")
|
||||
etud_ = etuds[0] # transition: etud_ à éliminer et remplacer par etud
|
||||
etudid = etud_["etudid"]
|
||||
etud = Identite.get_etud(etudid)
|
||||
sco_etud.fill_etuds_info([etud_])
|
||||
#
|
||||
info = etud_
|
||||
info = etud.to_dict_scodoc7(restrict=restrict_etud_data)
|
||||
if etud.prenom_etat_civil:
|
||||
info["etat_civil"] = (
|
||||
"<h3>Etat-civil: "
|
||||
@ -193,45 +181,24 @@ def ficheEtud(etudid=None):
|
||||
else:
|
||||
info["etat_civil"] = ""
|
||||
info["ScoURL"] = scu.ScoURL()
|
||||
info["authuser"] = authuser
|
||||
info["authuser"] = current_user
|
||||
if restrict_etud_data:
|
||||
info["info_naissance"] = ""
|
||||
adresse = None
|
||||
else:
|
||||
info["info_naissance"] = info["date_naissance"]
|
||||
if info["lieu_naissance"]:
|
||||
info["info_naissance"] += " à " + info["lieu_naissance"]
|
||||
if info["dept_naissance"]:
|
||||
info["info_naissance"] += f" ({info['dept_naissance']})"
|
||||
info["etudfoto"] = sco_photos.etud_photo_html(etud_)
|
||||
if (
|
||||
(not info["domicile"])
|
||||
and (not info["codepostaldomicile"])
|
||||
and (not info["villedomicile"])
|
||||
):
|
||||
info["domicile"] = "<em>inconnue</em>"
|
||||
if info["paysdomicile"]:
|
||||
pays = sco_etud.format_pays(info["paysdomicile"])
|
||||
if pays:
|
||||
info["paysdomicile"] = "(%s)" % pays
|
||||
else:
|
||||
info["paysdomicile"] = ""
|
||||
if info["telephone"] or info["telephonemobile"]:
|
||||
info["telephones"] = "<br>%s %s" % (
|
||||
info["telephonestr"],
|
||||
info["telephonemobilestr"],
|
||||
)
|
||||
else:
|
||||
info["telephones"] = ""
|
||||
# e-mail:
|
||||
if info["email_default"]:
|
||||
info["emaillink"] = ", ".join(
|
||||
[
|
||||
'<a class="stdlink" href="mailto:%s">%s</a>' % (m, m)
|
||||
for m in [etud_["email"], etud_["emailperso"]]
|
||||
if m
|
||||
]
|
||||
)
|
||||
else:
|
||||
info["emaillink"] = "<em>(pas d'adresse e-mail)</em>"
|
||||
adresse = etud.adresses.first()
|
||||
info.update(_format_adresse(adresse))
|
||||
|
||||
info.update(etud.inscription_descr())
|
||||
info["etudfoto"] = etud.photo_html()
|
||||
|
||||
# Champ dépendant des permissions:
|
||||
if authuser.has_permission(Permission.EtudChangeAdr):
|
||||
if current_user.has_permission(Permission.EtudChangeAdr):
|
||||
info[
|
||||
"modifadresse"
|
||||
] = f"""<a class="stdlink" href="{
|
||||
@ -242,36 +209,32 @@ def ficheEtud(etudid=None):
|
||||
info["modifadresse"] = ""
|
||||
|
||||
# Groupes:
|
||||
inscription_courante = etud.inscription_courante()
|
||||
sco_groups.etud_add_group_infos(
|
||||
info,
|
||||
info["cursem"]["formsemestre_id"] if info["cursem"] else None,
|
||||
inscription_courante.formsemestre.id if inscription_courante else None,
|
||||
only_to_show=True,
|
||||
)
|
||||
# Parcours de l'étudiant
|
||||
if info["sems"]:
|
||||
info["last_formsemestre_id"] = info["sems"][0]["formsemestre_id"]
|
||||
else:
|
||||
info["last_formsemestre_id"] = ""
|
||||
sem_info = {}
|
||||
for sem in info["sems"]:
|
||||
formsemestre: FormSemestre = db.session.get(
|
||||
FormSemestre, sem["formsemestre_id"]
|
||||
inscriptions = etud.inscriptions()
|
||||
info["last_formsemestre_id"] = (
|
||||
inscriptions[0].formsemestre.id if inscriptions else ""
|
||||
)
|
||||
if sem["ins"]["etat"] != scu.INSCRIT:
|
||||
|
||||
sem_info = {}
|
||||
for inscription in inscriptions:
|
||||
formsemestre = inscription.formsemestre
|
||||
if inscription.etat != scu.INSCRIT:
|
||||
descr, _ = etud_descr_situation_semestre(
|
||||
etudid,
|
||||
formsemestre,
|
||||
info["ne"],
|
||||
etud.e,
|
||||
show_date_inscr=False,
|
||||
)
|
||||
grlink = f"""<span class="fontred">{descr["situation"]}</span>"""
|
||||
else:
|
||||
e = {"etudid": etudid}
|
||||
sco_groups.etud_add_group_infos(
|
||||
e,
|
||||
sem["formsemestre_id"],
|
||||
only_to_show=True,
|
||||
)
|
||||
sco_groups.etud_add_group_infos(e, formsemestre.id, only_to_show=True)
|
||||
|
||||
grlinks = []
|
||||
for partition in e["partitions"].values():
|
||||
@ -289,16 +252,16 @@ def ficheEtud(etudid=None):
|
||||
)
|
||||
grlink = ", ".join(grlinks)
|
||||
# infos ajoutées au semestre dans le parcours (groupe, menu)
|
||||
menu = _menu_scolarite(authuser, formsemestre, etudid, sem["ins"]["etat"])
|
||||
menu = _menu_scolarite(current_user, formsemestre, etudid, inscription.etat)
|
||||
if menu:
|
||||
sem_info[sem["formsemestre_id"]] = (
|
||||
sem_info[formsemestre.id] = (
|
||||
"<table><tr><td>" + grlink + "</td><td>" + menu + "</td></tr></table>"
|
||||
)
|
||||
else:
|
||||
sem_info[sem["formsemestre_id"]] = grlink
|
||||
sem_info[formsemestre.id] = grlink
|
||||
|
||||
if info["sems"]:
|
||||
Se = sco_cursus.get_situation_etud_cursus(etud_, info["last_formsemestre_id"])
|
||||
if inscriptions:
|
||||
Se = sco_cursus.get_situation_etud_cursus(info, info["last_formsemestre_id"])
|
||||
info["liste_inscriptions"] = formsemestre_recap_parcours_table(
|
||||
Se,
|
||||
etudid,
|
||||
@ -318,20 +281,19 @@ def ficheEtud(etudid=None):
|
||||
</span>
|
||||
"""
|
||||
)
|
||||
last_formsemestre: FormSemestre = db.session.get(
|
||||
FormSemestre, info["sems"][0]["formsemestre_id"]
|
||||
)
|
||||
last_formsemestre: FormSemestre = inscriptions[0].formsemestre
|
||||
if last_formsemestre.formation.is_apc() and last_formsemestre.semestre_id > 2:
|
||||
info[
|
||||
"link_bul_pdf"
|
||||
] += f"""
|
||||
<span class="link_bul_pdf">
|
||||
<a class="stdlink" href="{
|
||||
url_for("notes.validation_rcues", scodoc_dept=g.scodoc_dept, etudid=etudid, formsemestre_id=last_formsemestre.id)
|
||||
url_for("notes.validation_rcues",
|
||||
scodoc_dept=g.scodoc_dept, etudid=etudid, formsemestre_id=last_formsemestre.id)
|
||||
}">Visualiser les compétences BUT</a>
|
||||
</span>
|
||||
"""
|
||||
if authuser.has_permission(Permission.EtudInscrit):
|
||||
if current_user.has_permission(Permission.EtudInscrit):
|
||||
info[
|
||||
"link_inscrire_ailleurs"
|
||||
] = f"""<span class="link_bul_pdf"><a class="stdlink" href="{
|
||||
@ -348,8 +310,8 @@ def ficheEtud(etudid=None):
|
||||
info["link_inscrire_ailleurs"] = ""
|
||||
else:
|
||||
# non inscrit
|
||||
l = [f"""<p><b>Étudiant{info["ne"]} non inscrit{info["ne"]}"""]
|
||||
if authuser.has_permission(Permission.EtudInscrit):
|
||||
l = [f"""<p><b>Étudiant{etud.e} non inscrit{etud.e}"""]
|
||||
if current_user.has_permission(Permission.EtudInscrit):
|
||||
l.append(
|
||||
f"""<a href="{
|
||||
url_for("notes.formsemestre_inscription_with_modules_form",
|
||||
@ -362,44 +324,50 @@ def ficheEtud(etudid=None):
|
||||
info["link_inscrire_ailleurs"] = ""
|
||||
|
||||
# Liste des annotations
|
||||
alist = []
|
||||
annos = sco_etud.etud_annotations_list(cnx, args={"etudid": etudid})
|
||||
for a in annos:
|
||||
if not sco_permissions_check.can_suppress_annotation(a["id"]):
|
||||
a["dellink"] = ""
|
||||
else:
|
||||
a["dellink"] = (
|
||||
'<td class="annodel"><a href="doSuppressAnnotation?etudid=%s&annotation_id=%s">%s</a></td>'
|
||||
% (
|
||||
etudid,
|
||||
a["id"],
|
||||
annotations_list = []
|
||||
annotations = EtudAnnotation.query.filter_by(etudid=etud.id).order_by(
|
||||
sa.desc(EtudAnnotation.date)
|
||||
)
|
||||
for annot in annotations:
|
||||
del_link = (
|
||||
f"""<td class="annodel"><a href="{
|
||||
url_for("scolar.doSuppressAnnotation",
|
||||
scodoc_dept=g.scodoc_dept, etudid=etudid, annotation_id=annot.id)}">{
|
||||
scu.icontag(
|
||||
"delete_img",
|
||||
border="0",
|
||||
alt="suppress",
|
||||
title="Supprimer cette annotation",
|
||||
),
|
||||
)
|
||||
}</a></td>"""
|
||||
if sco_permissions_check.can_suppress_annotation(annot.id)
|
||||
else ""
|
||||
)
|
||||
author = sco_users.user_info(a["author"])
|
||||
alist.append(
|
||||
f"""<tr><td><span class="annodate">Le {a['date']} par {author['prenomnom']} :
|
||||
</span><span class="annoc">{a['comment']}</span></td>{a['dellink']}</tr>
|
||||
|
||||
author = User.query.filter_by(user_name=annot.author).first()
|
||||
annotations_list.append(
|
||||
f"""<tr><td><span class="annodate">Le {annot.date.strftime("%d/%m/%Y") if annot.date else "?"}
|
||||
par {author.get_prenomnom() if author else "?"} :
|
||||
</span><span class="annoc">{annot.comment or ""}</span></td>{del_link}</tr>
|
||||
"""
|
||||
)
|
||||
info["liste_annotations"] = "\n".join(alist)
|
||||
info["liste_annotations"] = "\n".join(annotations_list)
|
||||
# fiche admission
|
||||
has_adm_notes = (
|
||||
info["math"] or info["physique"] or info["anglais"] or info["francais"]
|
||||
infos_admission = _infos_admission(etud, restrict_etud_data)
|
||||
has_adm_notes = any(
|
||||
infos_admission[k] for k in ("math", "physique", "anglais", "francais")
|
||||
)
|
||||
has_bac_info = any(
|
||||
infos_admission[k]
|
||||
for k in (
|
||||
"bac_specialite",
|
||||
"annee_bac",
|
||||
"rapporteur",
|
||||
"commentaire",
|
||||
"classement",
|
||||
"type_admission",
|
||||
"rap",
|
||||
)
|
||||
has_bac_info = (
|
||||
info["bac"]
|
||||
or info["specialite"]
|
||||
or info["annee_bac"]
|
||||
or info["rapporteur"]
|
||||
or info["commentaire"]
|
||||
or info["classement"]
|
||||
or info["type_admission"]
|
||||
)
|
||||
if has_bac_info or has_adm_notes:
|
||||
adm_tmpl = """<!-- Donnees admission -->
|
||||
@ -411,7 +379,7 @@ def ficheEtud(etudid=None):
|
||||
<tr><th>Bac</th><th>Année</th><th>Rg</th>
|
||||
<th>Math</th><th>Physique</th><th>Anglais</th><th>Français</th></tr>
|
||||
<tr>
|
||||
<td>%(bac)s (%(specialite)s)</td>
|
||||
<td>%(bac_specialite)s</td>
|
||||
<td>%(annee_bac)s </td>
|
||||
<td>%(classement)s</td>
|
||||
<td>%(math)s</td><td>%(physique)s</td><td>%(anglais)s</td><td>%(francais)s</td>
|
||||
@ -419,22 +387,22 @@ def ficheEtud(etudid=None):
|
||||
</table>
|
||||
"""
|
||||
adm_tmpl += """
|
||||
<div>Bac %(bac)s (%(specialite)s) obtenu en %(annee_bac)s </div>
|
||||
<div class="ilycee">%(ilycee)s</div>"""
|
||||
if info["type_admission"] or info["classement"]:
|
||||
<div>Bac %(bac_specialite)s obtenu en %(annee_bac)s </div>
|
||||
<div class="info_lycee">%(info_lycee)s</div>"""
|
||||
if infos_admission["type_admission"] or infos_admission["classement"]:
|
||||
adm_tmpl += """<div class="vadmission">"""
|
||||
if info["type_admission"]:
|
||||
if infos_admission["type_admission"]:
|
||||
adm_tmpl += """<span>Voie d'admission: <span class="etud_type_admission">%(type_admission)s</span></span> """
|
||||
if info["classement"]:
|
||||
if infos_admission["classement"]:
|
||||
adm_tmpl += """<span>Rang admission: <span class="etud_type_admission">%(classement)s</span></span>"""
|
||||
if info["type_admission"] or info["classement"]:
|
||||
if infos_admission["type_admission"] or infos_admission["classement"]:
|
||||
adm_tmpl += "</div>"
|
||||
if info["rap"]:
|
||||
if infos_admission["rap"]:
|
||||
adm_tmpl += """<div class="note_rapporteur">%(rap)s</div>"""
|
||||
adm_tmpl += """</div>"""
|
||||
else:
|
||||
adm_tmpl = "" # pas de boite "info admission"
|
||||
info["adm_data"] = adm_tmpl % info
|
||||
info["adm_data"] = adm_tmpl % infos_admission
|
||||
|
||||
# Fichiers archivés:
|
||||
info["fichiers_archive_htm"] = (
|
||||
@ -455,18 +423,16 @@ def ficheEtud(etudid=None):
|
||||
if has_debouche:
|
||||
info[
|
||||
"debouche_html"
|
||||
] = """<div id="fichedebouche" data-readonly="%s" data-etudid="%s">
|
||||
] = f"""<div id="fichedebouche"
|
||||
data-readonly="{suivi_readonly}"
|
||||
data-etudid="{info['etudid']}">
|
||||
<span class="debouche_tit">Devenir:</span>
|
||||
<div><form>
|
||||
<ul class="listdebouches">
|
||||
%s
|
||||
{link_add_suivi}
|
||||
</ul>
|
||||
</form></div>
|
||||
</div>""" % (
|
||||
suivi_readonly,
|
||||
info["etudid"],
|
||||
link_add_suivi,
|
||||
)
|
||||
</div>"""
|
||||
else:
|
||||
info["debouche_html"] = "" # pas de boite "devenir"
|
||||
#
|
||||
@ -492,20 +458,14 @@ def ficheEtud(etudid=None):
|
||||
else:
|
||||
info["groupes_row"] = ""
|
||||
info["menus_etud"] = menus_etud(etudid)
|
||||
if info["boursier"]:
|
||||
if info["boursier"] and not restrict_etud_data:
|
||||
info["bourse_span"] = """<span class="boursier">boursier</span>"""
|
||||
else:
|
||||
info["bourse_span"] = ""
|
||||
|
||||
# raccordement provisoire pour juillet 2022, avant refonte complète de cette fiche...
|
||||
# info["but_infos_mkup"] = jury_but_view.infos_fiche_etud_html(etudid)
|
||||
|
||||
# XXX dev
|
||||
info["but_cursus_mkup"] = ""
|
||||
if info["sems"]:
|
||||
last_sem = FormSemestre.query.get_or_404(info["sems"][0]["formsemestre_id"])
|
||||
if last_sem.formation.is_apc():
|
||||
but_cursus = cursus_but.EtudCursusBUT(etud, last_sem.formation)
|
||||
# Liens vers compétences BUT
|
||||
if last_formsemestre and last_formsemestre.formation.is_apc():
|
||||
but_cursus = cursus_but.EtudCursusBUT(etud, last_formsemestre.formation)
|
||||
info[
|
||||
"but_cursus_mkup"
|
||||
] = f"""
|
||||
@ -516,46 +476,74 @@ def ficheEtud(etudid=None):
|
||||
scu=scu,
|
||||
)}
|
||||
<div class="link_validation_rcues">
|
||||
<a href="{url_for("notes.validation_rcues",
|
||||
<a class="stdlink" href="{url_for("notes.validation_rcues",
|
||||
scodoc_dept=g.scodoc_dept, etudid=etudid,
|
||||
formsemestre_id=last_formsemestre.id)}"
|
||||
title="Visualiser les compétences BUT"
|
||||
>
|
||||
<img src="/ScoDoc/static/icons/parcours-but.png" alt="validation_rcues" height="100px"/>
|
||||
<div>Compétences BUT</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
else:
|
||||
info["but_cursus_mkup"] = ""
|
||||
|
||||
tmpl = """<div class="menus_etud">%(menus_etud)s</div>
|
||||
<div class="ficheEtud" id="ficheEtud"><table>
|
||||
<tr><td>
|
||||
<h2>%(nomprenom)s (%(inscription)s)</h2>
|
||||
%(etat_civil)s
|
||||
<span>%(emaillink)s</span>
|
||||
</td><td class="photocell">
|
||||
<a href="etud_photo_orig_page?etudid=%(etudid)s">%(etudfoto)s</a>
|
||||
</td></tr></table>
|
||||
adresse_template = (
|
||||
""
|
||||
if restrict_etud_data
|
||||
else """
|
||||
<!-- Adresse -->
|
||||
<div class="ficheadresse" id="ficheadresse">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="fichetitre2">Adresse :</td>
|
||||
<td> %(domicile)s %(codepostaldomicile)s %(villedomicile)s %(paysdomicile)s
|
||||
%(modifadresse)s
|
||||
%(telephones)s
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
"""
|
||||
)
|
||||
|
||||
info_naissance = (
|
||||
f"""<tr><td class="fichetitre2">Né{etud.e} le :</td><td>{info["info_naissance"]}</td></tr>"""
|
||||
if info["info_naissance"]
|
||||
else ""
|
||||
)
|
||||
situation_template = (
|
||||
f"""
|
||||
<div class="fichesituation">
|
||||
<div class="fichetablesitu">
|
||||
<table>
|
||||
<tr><td class="fichetitre2">Situation :</td><td>%(situation)s %(bourse_span)s</td></tr>
|
||||
%(groupes_row)s
|
||||
<tr><td class="fichetitre2">Né%(ne)s le :</td><td>%(info_naissance)s</td></tr>
|
||||
{info_naissance}
|
||||
</table>
|
||||
"""
|
||||
+ adresse_template
|
||||
+ """
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
<!-- Adresse -->
|
||||
<div class="ficheadresse" id="ficheadresse">
|
||||
<table><tr>
|
||||
<td class="fichetitre2">Adresse :</td><td> %(domicile)s %(codepostaldomicile)s %(villedomicile)s %(paysdomicile)s
|
||||
%(modifadresse)s
|
||||
%(telephones)s
|
||||
tmpl = (
|
||||
"""<div class="menus_etud">%(menus_etud)s</div>
|
||||
<div class="fiche_etud" id="fiche_etud"><table>
|
||||
<tr><td>
|
||||
<h2>%(nomprenom)s (%(inscription)s)</h2>
|
||||
%(etat_civil)s
|
||||
<span>%(email_link)s</span>
|
||||
</td><td class="photocell">
|
||||
<a href="etud_photo_orig_page?etudid=%(etudid)s">%(etudfoto)s</a>
|
||||
</td></tr></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
+ situation_template
|
||||
+ """
|
||||
|
||||
%(inscriptions_mkup)s
|
||||
|
||||
@ -595,8 +583,9 @@ def ficheEtud(etudid=None):
|
||||
|
||||
</div>
|
||||
"""
|
||||
)
|
||||
header = html_sco_header.sco_header(
|
||||
page_title="Fiche étudiant %(prenom)s %(nom)s" % info,
|
||||
page_title=f"Fiche étudiant {etud.nomprenom}",
|
||||
cssstyles=[
|
||||
"libjs/jQuery-tagEditor/jquery.tag-editor.css",
|
||||
"css/jury_but.css",
|
||||
@ -614,6 +603,92 @@ def ficheEtud(etudid=None):
|
||||
return header + tmpl % info + html_sco_header.sco_footer()
|
||||
|
||||
|
||||
def _format_adresse(adresse: Adresse | None) -> dict:
|
||||
"""{ "telephonestr" : ..., "telephonemobilestr" : ... } (formats html)"""
|
||||
d = {
|
||||
"telephonestr": ("<b>Tél.:</b> " + scu.format_telephone(adresse.telephone))
|
||||
if (adresse and adresse.telephone)
|
||||
else "",
|
||||
"telephonemobilestr": (
|
||||
"<b>Mobile:</b> " + scu.format_telephone(adresse.telephonemobile)
|
||||
)
|
||||
if (adresse and adresse.telephonemobile)
|
||||
else "",
|
||||
# e-mail:
|
||||
"email_link": ", ".join(
|
||||
[
|
||||
f"""<a class="stdlink" href="mailto:{m}">{m}</a>"""
|
||||
for m in [adresse.email, adresse.emailperso]
|
||||
if m
|
||||
]
|
||||
)
|
||||
if adresse and (adresse.email or adresse.emailperso)
|
||||
else "",
|
||||
"domicile": (adresse.domicile or "")
|
||||
if adresse
|
||||
and (adresse.domicile or adresse.codepostaldomicile or adresse.villedomicile)
|
||||
else "<em>inconnue</em>",
|
||||
"paysdomicile": f"{sco_etud.format_pays(adresse.paysdomicile)}"
|
||||
if adresse and adresse.paysdomicile
|
||||
else "",
|
||||
}
|
||||
d["telephones"] = (
|
||||
f"<br>{d['telephonestr']} {d['telephonemobilestr']}"
|
||||
if adresse and (adresse.telephone or adresse.telephonemobile)
|
||||
else ""
|
||||
)
|
||||
return d
|
||||
|
||||
|
||||
def _infos_admission(etud: Identite, restrict_etud_data: bool) -> dict:
|
||||
"""dict with adminission data, restricted or not"""
|
||||
# info sur rapporteur et son commentaire
|
||||
rap = ""
|
||||
if not restrict_etud_data:
|
||||
if etud.admission.rapporteur or etud.admission.commentaire:
|
||||
rap = "Note du rapporteur"
|
||||
if etud.admission.rapporteur:
|
||||
rap += f" ({etud.admission.rapporteur})"
|
||||
rap += ": "
|
||||
if etud.admission.commentaire:
|
||||
rap += f"<em>{etud.admission.commentaire}</em>"
|
||||
# nom du lycée
|
||||
if restrict_etud_data:
|
||||
info_lycee = ""
|
||||
elif etud.admission.nomlycee:
|
||||
info_lycee = "Lycée " + sco_etud.format_lycee(etud.admission.nomlycee)
|
||||
if etud.admission.villelycee:
|
||||
info_lycee += f" ({etud.admission.villelycee})"
|
||||
info_lycee += "<br>"
|
||||
elif etud.admission.codelycee:
|
||||
info_lycee = sco_etud.format_lycee_from_code(etud.admission.codelycee)
|
||||
else:
|
||||
info_lycee = ""
|
||||
|
||||
return {
|
||||
# infos accessibles à tous:
|
||||
"bac_specialite": f"{etud.admission.bac or ''}{(' '+(etud.admission.specialite or '')) if etud.admission.specialite else ''}",
|
||||
"annee_bac": etud.admission.annee_bac or "",
|
||||
# infos protégées par ViewEtudData:
|
||||
"info_lycee": info_lycee,
|
||||
"rapporteur": etud.admission.rapporteur if not restrict_etud_data else "",
|
||||
"rap": rap,
|
||||
"commentaire": (etud.admission.commentaire or "")
|
||||
if not restrict_etud_data
|
||||
else "",
|
||||
"classement": (etud.admission.classement or "")
|
||||
if not restrict_etud_data
|
||||
else "",
|
||||
"type_admission": (etud.admission.type_admission or "")
|
||||
if not restrict_etud_data
|
||||
else "",
|
||||
"math": (etud.admission.math or "") if not restrict_etud_data else "",
|
||||
"physique": (etud.admission.physique or "") if not restrict_etud_data else "",
|
||||
"anglais": (etud.admission.anglais or "") if not restrict_etud_data else "",
|
||||
"francais": (etud.admission.francais or "") if not restrict_etud_data else "",
|
||||
}
|
||||
|
||||
|
||||
def menus_etud(etudid):
|
||||
"""Menu etudiant (operations sur l'etudiant)"""
|
||||
authuser = current_user
|
||||
@ -623,7 +698,7 @@ def menus_etud(etudid):
|
||||
menuEtud = [
|
||||
{
|
||||
"title": etud["nomprenom"],
|
||||
"endpoint": "scolar.ficheEtud",
|
||||
"endpoint": "scolar.fiche_etud",
|
||||
"args": {"etudid": etud["etudid"]},
|
||||
"enabled": True,
|
||||
"helpmsg": "Fiche étudiant",
|
||||
@ -671,36 +746,33 @@ def etud_info_html(etudid, with_photo="1", debug=False):
|
||||
"""
|
||||
formsemestre_id = sco_formsemestre_status.retreive_formsemestre_from_request()
|
||||
with_photo = int(with_photo)
|
||||
etuds = sco_etud.get_etud_info(filled=True)
|
||||
if etuds:
|
||||
etud = etuds[0]
|
||||
else:
|
||||
abort(404, "etudiant inconnu")
|
||||
photo_html = sco_photos.etud_photo_html(etud, title="fiche de " + etud["nom"])
|
||||
# experimental: may be too slow to be here
|
||||
code_cursus, _ = sco_report.get_code_cursus_etud(etud, prefix="S", separator=", ")
|
||||
etud = Identite.get_etud(etudid)
|
||||
|
||||
bac = sco_bac.Baccalaureat(etud["bac"], etud["specialite"])
|
||||
photo_html = etud.photo_html(etud, title="fiche de " + etud.nomprenom)
|
||||
code_cursus, _ = sco_report.get_code_cursus_etud(
|
||||
etud, formsemestres=etud.get_formsemestres(), prefix="S", separator=", "
|
||||
)
|
||||
bac = sco_bac.Baccalaureat(etud.admission.bac, etud.admission.specialite)
|
||||
bac_abbrev = bac.abbrev()
|
||||
H = f"""<div class="etud_info_div">
|
||||
<div class="eid_left">
|
||||
<div class="eid_nom"><div><a class="stdlink" target="_blank" href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">{etud["nomprenom"]}</a></div></div>
|
||||
<div class="eid_info eid_bac">Bac: <span class="eid_bac">{bac_abbrev}</span></div>
|
||||
<div class="eid_info eid_parcours">{code_cursus}</div>
|
||||
"""
|
||||
|
||||
# Informations sur l'etudiant dans le semestre courant:
|
||||
sem = None
|
||||
formsemestre = None
|
||||
if formsemestre_id: # un semestre est spécifié par la page
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
elif etud["cursem"]: # le semestre "en cours" pour l'étudiant
|
||||
sem = etud["cursem"]
|
||||
if sem:
|
||||
groups = sco_groups.get_etud_groups(etudid, formsemestre_id)
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
elif inscription_courante: # le semestre "en cours" pour l'étudiant
|
||||
formsemestre = inscription_courante.formsemestre
|
||||
if formsemestre:
|
||||
groups = sco_groups.get_etud_groups(etudid, formsemestre.id)
|
||||
grc = sco_groups.listgroups_abbrev(groups)
|
||||
H += f"""<div class="eid_info">En <b>S{sem["semestre_id"]}</b>: {grc}</div>"""
|
||||
H += f"""<div class="eid_info">En <b>S{formsemestre.semestre_id}</b>: {grc}</div>"""
|
||||
H += "</div>" # fin partie gauche (eid_left)
|
||||
if with_photo:
|
||||
H += '<span class="eid_right">' + photo_html + "</span>"
|
||||
|
@ -55,6 +55,7 @@ _SCO_PERMISSIONS = (
|
||||
"Exporter les données de l'application relations entreprises",
|
||||
),
|
||||
(1 << 29, "UsersChangeCASId", "Paramétrer l'id CAS"),
|
||||
(1 << 30, "ViewEtudData", "Accéder aux données personnelles des étudiants"),
|
||||
#
|
||||
# XXX inutilisée ? (1 << 40, "EtudChangePhoto", "Modifier la photo d'un étudiant"),
|
||||
# Permissions du module Assiduité)
|
||||
|
@ -187,7 +187,7 @@ def formsemestre_poursuite_report(formsemestre_id, fmt="html"):
|
||||
ids = []
|
||||
for etud in etuds:
|
||||
fiche_url = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
|
||||
)
|
||||
etud["_nom_target"] = fiche_url
|
||||
etud["_prenom_target"] = fiche_url
|
||||
|
@ -144,7 +144,7 @@ def pvjury_table(
|
||||
"code_nip": e["identite"]["code_nip"],
|
||||
"nomprenom": e["identite"]["nomprenom"],
|
||||
"_nomprenom_target": url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=e["identite"]["etudid"],
|
||||
),
|
||||
@ -351,7 +351,7 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid
|
||||
# PV pour ce seul étudiant:
|
||||
etud = Identite.get_etud(etudid)
|
||||
etuddescr = f"""<a class="discretelink" href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">{etud.nomprenom}</a>"""
|
||||
etudids = [etudid]
|
||||
else:
|
||||
|
@ -1017,34 +1017,60 @@ EXP_LIC = re.compile(r"licence", re.I)
|
||||
EXP_LPRO = re.compile(r"professionnelle", re.I)
|
||||
|
||||
|
||||
def _codesem(sem, short=True, prefix=""):
|
||||
def _code_sem(
|
||||
semestre_id: int, titre: str, mois_debut: int, short=True, prefix=""
|
||||
) -> str:
|
||||
"code semestre: S1 ou S1d"
|
||||
idx = sem["semestre_id"]
|
||||
idx = semestre_id
|
||||
# semestre décalé ?
|
||||
# les semestres pairs normaux commencent entre janvier et mars
|
||||
# les impairs normaux entre aout et decembre
|
||||
d = ""
|
||||
if idx and idx > 0 and sem["date_debut"]:
|
||||
mois_debut = int(sem["date_debut"].split("/")[1])
|
||||
if idx > 0:
|
||||
if (idx % 2 and mois_debut < 3) or (idx % 2 == 0 and mois_debut >= 8):
|
||||
d = "d"
|
||||
if idx == -1:
|
||||
if short:
|
||||
idx = "Autre "
|
||||
else:
|
||||
idx = sem["titre"] + " "
|
||||
idx = titre + " "
|
||||
idx = EXP_LPRO.sub("pro.", idx)
|
||||
idx = EXP_LIC.sub("Lic.", idx)
|
||||
prefix = "" # indique titre au lieu de Sn
|
||||
return "%s%s%s" % (prefix, idx, d)
|
||||
return prefix + str(idx) + d
|
||||
|
||||
|
||||
def get_code_cursus_etud(etud, prefix="", separator=""):
|
||||
def _code_sem_formsemestre(formsemestre: FormSemestre, short=True, prefix="") -> str:
|
||||
"code semestre: S1 ou S1d"
|
||||
titre = formsemestre.titre
|
||||
mois_debut = formsemestre.date_debut.month
|
||||
semestre_id = formsemestre.semestre_id
|
||||
return _code_sem(semestre_id, titre, mois_debut, short=short, prefix=prefix)
|
||||
|
||||
|
||||
def _code_sem_dict(sem, short=True, prefix="") -> str:
|
||||
"code semestre: S1 ou S1d, à parit d'un dict (sem ScoDoc 7)"
|
||||
titre = sem["titre"]
|
||||
mois_debut = int(sem["date_debut"].split("/")[1]) if sem["date_debut"] else 0
|
||||
semestre_id = sem["semestre_id"]
|
||||
return _code_sem(semestre_id, titre, mois_debut, short=short, prefix=prefix)
|
||||
|
||||
|
||||
def get_code_cursus_etud(
|
||||
etudid: int,
|
||||
sems: list[dict] = None,
|
||||
formsemestres: list[FormSemestre] | None = None,
|
||||
prefix="",
|
||||
separator="",
|
||||
) -> tuple[str, dict]:
|
||||
"""calcule un code de cursus (parcours) pour un etudiant
|
||||
exemples:
|
||||
1234A pour un etudiant ayant effectué S1, S2, S3, S4 puis diplome
|
||||
12D pour un étudiant en S1, S2 puis démission en S2
|
||||
12R pour un etudiant en S1, S2 réorienté en fin de S2
|
||||
|
||||
On peut passer soir la liste des semestres dict (anciennes fonctions ScoDoc7)
|
||||
soit la liste des FormSemestre.
|
||||
Construit aussi un dict: { semestre_id : decision_jury | None }
|
||||
"""
|
||||
# Nota: approche plus moderne:
|
||||
@ -1054,31 +1080,37 @@ def get_code_cursus_etud(etud, prefix="", separator=""):
|
||||
#
|
||||
p = []
|
||||
decisions_jury = {}
|
||||
# élimine les semestres spéciaux hors cursus (LP en 1 sem., ...)
|
||||
sems = [s for s in etud["sems"] if s["semestre_id"] >= 0]
|
||||
i = len(sems) - 1
|
||||
while i >= 0:
|
||||
s = sems[i] # 'sems' est a l'envers, du plus recent au plus ancien
|
||||
s_formsemestre = FormSemestre.query.get_or_404(s["formsemestre_id"])
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(s_formsemestre)
|
||||
|
||||
p.append(_codesem(s, prefix=prefix))
|
||||
if formsemestres is None:
|
||||
formsemestres = [
|
||||
FormSemestre.query.get_or_404(s["formsemestre_id"]) for s in (sems or [])
|
||||
]
|
||||
|
||||
# élimine les semestres spéciaux hors cursus (LP en 1 sem., ...)
|
||||
formsemestres = [s for s in formsemestres if s.semestre_id >= 0]
|
||||
i = len(formsemestres) - 1
|
||||
while i >= 0:
|
||||
# 'sems' est a l'envers, du plus recent au plus ancien
|
||||
formsemestre = formsemestres[i]
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
|
||||
p.append(_code_sem_formsemestre(formsemestre, prefix=prefix))
|
||||
# code decisions jury de chaque semestre:
|
||||
if nt.get_etud_etat(etud["etudid"]) == "D":
|
||||
decisions_jury[s["semestre_id"]] = "DEM"
|
||||
if nt.get_etud_etat(etudid) == "D":
|
||||
decisions_jury[formsemestre.semestre_id] = "DEM"
|
||||
else:
|
||||
dec = nt.get_etud_decision_sem(etud["etudid"])
|
||||
dec = nt.get_etud_decision_sem(etudid)
|
||||
if not dec:
|
||||
decisions_jury[s["semestre_id"]] = ""
|
||||
decisions_jury[formsemestre.semestre_id] = ""
|
||||
else:
|
||||
decisions_jury[s["semestre_id"]] = dec["code"]
|
||||
decisions_jury[formsemestre.semestre_id] = dec["code"]
|
||||
# code etat dans le code_cursus sur dernier semestre seulement
|
||||
if i == 0:
|
||||
# Démission
|
||||
if nt.get_etud_etat(etud["etudid"]) == "D":
|
||||
if nt.get_etud_etat(etudid) == "D":
|
||||
p.append(":D")
|
||||
else:
|
||||
dec = nt.get_etud_decision_sem(etud["etudid"])
|
||||
dec = nt.get_etud_decision_sem(etudid)
|
||||
if dec and dec["code"] in codes_cursus.CODES_SEM_REO:
|
||||
p.append(":R")
|
||||
if (
|
||||
@ -1176,14 +1208,16 @@ def table_suivi_cursus(formsemestre_id, only_primo=False, grouped_parcours=True)
|
||||
) = tsp_etud_list(formsemestre_id, only_primo=only_primo)
|
||||
codes_etuds = collections.defaultdict(list)
|
||||
for etud in etuds:
|
||||
etud["code_cursus"], etud["decisions_jury"] = get_code_cursus_etud(etud)
|
||||
etud["code_cursus"], etud["decisions_jury"] = get_code_cursus_etud(
|
||||
etud["etudid"], sems=etud["sems"]
|
||||
)
|
||||
codes_etuds[etud["code_cursus"]].append(etud)
|
||||
fiche_url = url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
|
||||
)
|
||||
etud["_nom_target"] = fiche_url
|
||||
etud["_prenom_target"] = fiche_url
|
||||
etud["_nom_td_attrs"] = 'id="%s" class="etudinfo"' % (etud["etudid"])
|
||||
etud["_nom_td_attrs"] = f'''id="{etud['etudid']}" class="etudinfo"'''
|
||||
|
||||
titles = {
|
||||
"parcours": "Code cursus",
|
||||
@ -1461,7 +1495,7 @@ def graph_cursus(
|
||||
else:
|
||||
modalite = ""
|
||||
label = "%s%s\\n%d/%s - %d/%s\\n%d" % (
|
||||
_codesem(s, short=False, prefix="S"),
|
||||
_code_sem_dict(s, short=False, prefix="S"),
|
||||
modalite,
|
||||
s["mois_debut_ord"],
|
||||
s["annee_debut"][2:],
|
||||
|
@ -13,8 +13,9 @@ SCO_ROLES_DEFAULTS = {
|
||||
p.EnsView,
|
||||
p.EtudAddAnnotations,
|
||||
p.Observateur,
|
||||
p.UsersView,
|
||||
p.ScoView,
|
||||
p.ViewEtudData,
|
||||
p.UsersView,
|
||||
),
|
||||
"Secr": (
|
||||
p.AbsAddBillet,
|
||||
@ -23,8 +24,9 @@ SCO_ROLES_DEFAULTS = {
|
||||
p.EtudAddAnnotations,
|
||||
p.EtudChangeAdr,
|
||||
p.Observateur,
|
||||
p.UsersView,
|
||||
p.ScoView,
|
||||
p.UsersView,
|
||||
p.ViewEtudData,
|
||||
),
|
||||
# Admin est le chef du département, pas le "super admin"
|
||||
# on doit donc lister toutes ses permissions:
|
||||
@ -44,9 +46,10 @@ SCO_ROLES_DEFAULTS = {
|
||||
p.EtudInscrit,
|
||||
p.EditFormSemestre,
|
||||
p.Observateur,
|
||||
p.ScoView,
|
||||
p.UsersAdmin,
|
||||
p.UsersView,
|
||||
p.ScoView,
|
||||
p.ViewEtudData,
|
||||
),
|
||||
# Rôles pour l'application relations entreprises
|
||||
# ObservateurEntreprise est un observateur de l'application entreprise
|
||||
@ -57,7 +60,8 @@ SCO_ROLES_DEFAULTS = {
|
||||
p.RelationsEntrepEdit,
|
||||
p.RelationsEntrepViewCorrs,
|
||||
),
|
||||
# AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application)
|
||||
# AdminEntreprise est un admin de l'application entreprise
|
||||
# (toutes les actions possibles de l'application)
|
||||
"AdminEntreprise": (
|
||||
p.RelationsEntrepView,
|
||||
p.RelationsEntrepEdit,
|
||||
|
@ -156,7 +156,7 @@ def trombino_html(groups_infos):
|
||||
'<a href="%s">%s</a>'
|
||||
% (
|
||||
url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=t["etudid"]
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=t["etudid"]
|
||||
),
|
||||
foto,
|
||||
)
|
||||
|
@ -431,7 +431,7 @@ APO_MISSING_CODE_STR = "----" # shown in HTML pages in place of missing code Ap
|
||||
EDIT_NB_ETAPES = 6 # Nombre max de codes étapes / semestre presentés dans l'UI
|
||||
|
||||
IT_SITUATION_MISSING_STR = (
|
||||
"____" # shown on ficheEtud (devenir) in place of empty situation
|
||||
"____" # shown on fiche_etud (devenir) in place of empty situation
|
||||
)
|
||||
|
||||
RANG_ATTENTE_STR = "(attente)" # rang affiché sur bulletins quand notes en attente
|
||||
@ -1285,6 +1285,27 @@ def format_prenom(s):
|
||||
return " ".join(r)
|
||||
|
||||
|
||||
def format_telephone(n: str | None) -> str:
|
||||
"Format a phone number for display"
|
||||
if n is None:
|
||||
return ""
|
||||
if len(n) < 7:
|
||||
return n
|
||||
n = n.replace(" ", "").replace(".", "")
|
||||
i = 0
|
||||
r = ""
|
||||
j = len(n) - 1
|
||||
while j >= 0:
|
||||
r = n[j] + r
|
||||
if i % 2 == 1 and j != 0:
|
||||
r = " " + r
|
||||
i += 1
|
||||
j -= 1
|
||||
if len(r) == 13 and r[0] != "0":
|
||||
r = "0" + r
|
||||
return r
|
||||
|
||||
|
||||
#
|
||||
def timedate_human_repr():
|
||||
"representation du temps courant pour utilisateur"
|
||||
|
@ -724,7 +724,7 @@ div.scoinfos {
|
||||
|
||||
/* ----- fiches etudiants ------ */
|
||||
|
||||
div.ficheEtud {
|
||||
div.fiche_etud {
|
||||
background-color: #f5edc8;
|
||||
/* rgb(255,240,128); */
|
||||
border: 1px solid gray;
|
||||
@ -739,7 +739,7 @@ div.menus_etud {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
div.ficheEtud h2 {
|
||||
div.fiche_etud h2 {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
@ -925,7 +925,7 @@ td.fichetitre2 {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.ficheEtud span.boursier {
|
||||
.fiche_etud span.boursier {
|
||||
background-color: red;
|
||||
color: white;
|
||||
margin-left: 12px;
|
||||
@ -963,6 +963,7 @@ div.section_but {
|
||||
|
||||
div.section_but > div.link_validation_rcues {
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ficheannotations {
|
||||
|
@ -7,7 +7,7 @@
|
||||
{% if not is_apc %}
|
||||
<h2><a class="discretelink" href="{{
|
||||
url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id,
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id,
|
||||
)}}">{{etud.nomprenom}}</a></h2>
|
||||
{% endif %}
|
||||
<form name="f" method="GET" action="{{request.base_url}}">
|
||||
@ -81,7 +81,7 @@
|
||||
</div>
|
||||
{% if not is_apc %}
|
||||
<div class="bull_photo"><a href="{{
|
||||
url_for('scolar.ficheEtud', scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for('scolar.fiche_etud', scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}}">{{etud.photo_html(title="fiche de " + etud["nom"])|safe}}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -183,7 +183,7 @@
|
||||
<td>{{ (stage_apprentissage.date_fin-stage_apprentissage.date_debut).days//7 }} semaines</td>
|
||||
<td>{{ stage_apprentissage.type_offre }}</td>
|
||||
<td><a
|
||||
href="{{ url_for('scolar.ficheEtud', scodoc_dept=etudiant.dept_id|get_dept_acronym, etudid=stage_apprentissage.etudid) }}">{{
|
||||
href="{{ url_for('scolar.fiche_etud', scodoc_dept=etudiant.dept_id|get_dept_acronym, etudid=stage_apprentissage.etudid) }}">{{
|
||||
etudiant.nom|format_nom }} {{ etudiant.prenom|format_prenom }}</a></td>
|
||||
<td>{% if stage_apprentissage.formation_text %}{{ stage_apprentissage.formation_text }}{% endif %}</td>
|
||||
<td>{{ stage_apprentissage.notes }}</td>
|
||||
|
@ -165,7 +165,7 @@ span.calendarEdit {
|
||||
etudiants.forEach(etudiant => {
|
||||
output += `
|
||||
<div data-etudid="${etudiant.etudid}" >
|
||||
<div class=nom data-etudid="${etudiant.etudid}" data-nom="${etudiant.nom_disp}" data-prenom="${etudiant.prenom}"><a href="ficheEtud?etudid=${etudiant.etudid}">${etudiant.nom_disp} ${etudiant.prenom}</a><div class=small>${etudiant.bac}</div></div>
|
||||
<div class=nom data-etudid="${etudiant.etudid}" data-nom="${etudiant.nom_disp}" data-prenom="${etudiant.prenom}"><a href="fiche_etud?etudid=${etudiant.etudid}">${etudiant.nom_disp} ${etudiant.prenom}</a><div class=small>${etudiant.bac}</div></div>
|
||||
${(() => {
|
||||
let output = "<div class=grpPartitions>";
|
||||
arrayPartitions.forEach((partition) => {
|
||||
|
@ -51,7 +51,7 @@
|
||||
<div class="etud-insidebar">
|
||||
{% if sco.etud %}
|
||||
<h2 id="insidebar-etud"><a href="{{url_for(
|
||||
'scolar.ficheEtud', scodoc_dept=g.scodoc_dept, etudid=sco.etud.id )}}" class="sidebar">
|
||||
'scolar.fiche_etud', scodoc_dept=g.scodoc_dept, etudid=sco.etud.id )}}" class="sidebar">
|
||||
<span class="fontred">{{sco.etud.nomprenom}}</span></a>
|
||||
</h2>
|
||||
<b>Absences</b>
|
||||
|
@ -358,7 +358,7 @@ def process_billet_absence_form(billet_id: int):
|
||||
page_title=f"Traitement billet d'absence de {etud.nomprenom}",
|
||||
),
|
||||
f"""<h2>Traitement du billet {billet.id} : <a class="discretelink" href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}">{etud.nomprenom}</a></h2>
|
||||
""",
|
||||
]
|
||||
|
@ -1193,7 +1193,7 @@ def view_module_abs(moduleimpl_id, fmt="html"):
|
||||
"nojust": nb_abs - nb_abs_just,
|
||||
"total": nb_abs,
|
||||
"_nomprenom_target": url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||
),
|
||||
}
|
||||
)
|
||||
@ -1492,7 +1492,7 @@ def formsemestre_desinscription(etudid, formsemestre_id, dialog_confirmed=False)
|
||||
|
||||
flash("Étudiant désinscrit")
|
||||
return redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
|
||||
|
||||
@ -2371,13 +2371,13 @@ def formsemestre_validation_but(
|
||||
<div class="nom_etud">{etud.nomprenom}</div>
|
||||
</div>
|
||||
<div class="bull_photo"><a href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="warning">Impossible de statuer sur cet étudiant:
|
||||
il est démissionnaire ou défaillant (voir <a class="stdlink" href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">sa fiche</a>)
|
||||
</div>
|
||||
</div>
|
||||
@ -2450,7 +2450,7 @@ def formsemestre_validation_but(
|
||||
<div class="nom_etud">{etud.nomprenom}</div>
|
||||
</div>
|
||||
<div class="bull_photo"><a href="{
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -2725,7 +2725,7 @@ def formsemestre_validation_suppress_etud(
|
||||
etud = Identite.get_etud(etudid)
|
||||
if formsemestre.formation.is_apc():
|
||||
next_url = url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etudid,
|
||||
)
|
||||
@ -2915,7 +2915,7 @@ def erase_decisions_annee_formation(etudid: int, formation_id: int, annee: int):
|
||||
flash("Décisions de jury effacées")
|
||||
return redirect(
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud.id,
|
||||
)
|
||||
@ -2931,7 +2931,7 @@ def erase_decisions_annee_formation(etudid: int, formation_id: int, annee: int):
|
||||
"jury/erase_decisions_annee_formation.j2",
|
||||
annee=annee,
|
||||
cancel_url=url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||
),
|
||||
etud=etud,
|
||||
formation=formation,
|
||||
|
@ -328,7 +328,7 @@ def showEtudLog(etudid, fmt="html"):
|
||||
filename="log_" + scu.make_filename(etud["nomprenom"]),
|
||||
html_next_section=f"""
|
||||
<ul><li>
|
||||
<a href="{url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)}">
|
||||
<a href="{url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)}">
|
||||
fiche de {etud['nomprenom']}</a></li>
|
||||
</ul>""",
|
||||
preferences=sco_preferences.SemPreferences(),
|
||||
@ -625,7 +625,7 @@ def etud_info(etudid=None, fmt="xml"):
|
||||
|
||||
|
||||
# -------------------------- FICHE ETUDIANT --------------------------
|
||||
sco_publish("/ficheEtud", sco_page_etud.ficheEtud, Permission.ScoView)
|
||||
sco_publish("/fiche_etud", sco_page_etud.fiche_etud, Permission.ScoView)
|
||||
|
||||
sco_publish(
|
||||
"/etud_upload_file_form",
|
||||
@ -720,7 +720,7 @@ def doAddAnnotation(etudid, comment):
|
||||
)
|
||||
logdb(cnx, method="addAnnotation", etudid=etudid)
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
|
||||
|
||||
@ -745,7 +745,7 @@ def doSuppressAnnotation(etudid, annotation_id):
|
||||
flash("Annotation supprimée")
|
||||
return flask.redirect(
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etudid,
|
||||
)
|
||||
@ -809,7 +809,7 @@ def form_change_coordonnees(etudid):
|
||||
initvalues=adr,
|
||||
submitlabel="Valider le formulaire",
|
||||
)
|
||||
dest_url = url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
dest_url = url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
if tf[0] == 0:
|
||||
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||
elif tf[0] == -1:
|
||||
@ -1009,7 +1009,7 @@ def etud_photo_orig_page(etudid=None):
|
||||
html_sco_header.sco_header(page_title=etud["nomprenom"]),
|
||||
"<h2>%s</h2>" % etud["nomprenom"],
|
||||
'<div><a href="%s">'
|
||||
% url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
% url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
sco_photos.etud_photo_orig_html(etud),
|
||||
"</a></div>",
|
||||
html_sco_header.sco_footer(),
|
||||
@ -1053,7 +1053,7 @@ def form_change_photo(etudid=None):
|
||||
submitlabel="Valider",
|
||||
cancelbutton="Annuler",
|
||||
)
|
||||
dest_url = url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
dest_url = url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
if tf[0] == 0:
|
||||
return (
|
||||
"\n".join(H)
|
||||
@ -1092,7 +1092,7 @@ def form_suppress_photo(etudid=None, dialog_confirmed=False):
|
||||
f"<p>Confirmer la suppression de la photo de {etud.nom_disp()} ?</p>",
|
||||
dest_url="",
|
||||
cancel_url=url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||
),
|
||||
parameters={"etudid": etud.id},
|
||||
)
|
||||
@ -1100,7 +1100,7 @@ def form_suppress_photo(etudid=None, dialog_confirmed=False):
|
||||
sco_photos.suppress_photo(etud)
|
||||
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
)
|
||||
|
||||
|
||||
@ -1229,7 +1229,7 @@ def _do_dem_or_def_etud(
|
||||
)
|
||||
if redirect:
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
|
||||
|
||||
@ -1301,7 +1301,7 @@ def _do_cancel_dem_or_def(
|
||||
f"<p>Confirmer l'annulation de la {operation_name} ?</p>",
|
||||
dest_url="",
|
||||
cancel_url=url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
),
|
||||
parameters={"etudid": etudid, "formsemestre_id": formsemestre_id},
|
||||
)
|
||||
@ -1325,7 +1325,7 @@ def _do_cancel_dem_or_def(
|
||||
|
||||
flash(f"{operation_name} annulée.")
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
|
||||
|
||||
@ -1784,7 +1784,7 @@ def _etudident_create_or_edit_form(edit):
|
||||
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
|
||||
#
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
)
|
||||
|
||||
|
||||
@ -1802,7 +1802,7 @@ def etud_copy_in_other_dept(etudid: int):
|
||||
action = request.form.get("action")
|
||||
if action == "cancel":
|
||||
return flask.redirect(
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
)
|
||||
try:
|
||||
formsemestre_id = int(request.form.get("formsemestre_id"))
|
||||
@ -1833,7 +1833,7 @@ def etud_copy_in_other_dept(etudid: int):
|
||||
# Attention, ce redirect change de département !
|
||||
return flask.redirect(
|
||||
url_for(
|
||||
"scolar.ficheEtud",
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=formsemestre.departement.acronym,
|
||||
etudid=new_etud.id,
|
||||
)
|
||||
@ -1881,12 +1881,12 @@ def etudident_delete(etudid: int = -1, dialog_confirmed=False):
|
||||
d'un semestre ! (pour cela, passez par sa fiche, menu associé au semestre)</p>
|
||||
|
||||
<p><a class="stdlink" href="{url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
)}">Vérifier la fiche de {etud.nomprenom}</a>
|
||||
</p>""",
|
||||
dest_url="",
|
||||
cancel_url=url_for(
|
||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
"scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid
|
||||
),
|
||||
OK="Supprimer définitivement cet étudiant",
|
||||
parameters={"etudid": etudid},
|
||||
@ -2018,7 +2018,7 @@ def check_group_apogee(group_id, etat=None, fix=False, fixmail=False):
|
||||
H.append(
|
||||
'<tr><td><a href="%s">%s</a></td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>'
|
||||
% (
|
||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
nom,
|
||||
nom_usuel,
|
||||
prenom,
|
||||
|
@ -0,0 +1,44 @@
|
||||
"""config nouvelle permission ViewEtudData: donne aux rôles Ens, Secr, Admin
|
||||
|
||||
Revision ID: 3fa988ff8970
|
||||
Revises: b4859c04205f
|
||||
Create Date: 2024-01-20 13:59:31.491442
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "3fa988ff8970"
|
||||
down_revision = "b4859c04205f"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# Donne la permission ViewEtudData aux rôles Admin, Ens, Secr
|
||||
# cette permission est 1<<30
|
||||
op.execute(
|
||||
"UPDATE role SET permissions = permissions | (1<<30) where role.name = 'Admin';"
|
||||
)
|
||||
op.execute(
|
||||
"UPDATE role SET permissions = permissions | (1<<30) where role.name = 'Ens';"
|
||||
)
|
||||
op.execute(
|
||||
"UPDATE role SET permissions = permissions | (1<<30) where role.name = 'Secr';"
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
# retire la permission ViewEtudData aux rôles Admin, Ens, Secr
|
||||
# cette permission est 1<<30
|
||||
op.execute(
|
||||
"UPDATE role SET permissions = permissions & ~(1<<30) where role.name = 'Admin';"
|
||||
)
|
||||
op.execute(
|
||||
"UPDATE role SET permissions = permissions & ~(1<<30) where role.name = 'Ens';"
|
||||
)
|
||||
op.execute(
|
||||
"UPDATE role SET permissions = permissions & ~(1<<30) where role.name = 'Secr';"
|
||||
)
|
@ -357,16 +357,11 @@ def test_import_etuds_xlsx(test_client):
|
||||
"civilite_etat_civil_str": "Mme",
|
||||
"nom_disp": "NOM_USUEL10 (NOM10)",
|
||||
"ne": "(e)",
|
||||
"email_default": "",
|
||||
"inscription": "ancien",
|
||||
"situation": "ancien élève",
|
||||
"inscriptionstr": "ancien",
|
||||
"inscription_formsemestre_id": None,
|
||||
"etatincursem": "?",
|
||||
"ilycee": "",
|
||||
"rap": "",
|
||||
"telephonestr": "",
|
||||
"telephonemobilestr": "",
|
||||
},
|
||||
)
|
||||
# Test de search_etud_in_dept
|
||||
|
Loading…
Reference in New Issue
Block a user