Select Git revision
sco_page_etud.py
Forked from
Jean-Marie Place / SCODOC_R6A06
Source project has a limited visibility.
-
Armand Sady authored
test html code to see where the html should be created, and how to render it properly with the rest of the code
Armand Sady authoredtest html code to see where the html should be created, and how to render it properly with the rest of the code
sco_page_etud.py 31.00 KiB
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""ScoDoc fiche_etud
Fiche description d'un étudiant et de son parcours
"""
from flask import url_for, g, render_template, request
from flask_login import current_user
import sqlalchemy as sa
from app import log
from app.auth.models import User
from app.but import cursus_but, validations_view
from app.models import (
Adresse,
EtudAnnotation,
FormSemestre,
Identite,
ScoDocSiteConfig,
ValidationDUT120,
)
from app.scodoc import (
codes_cursus,
htmlutils,
sco_archives_etud,
sco_bac,
sco_cursus,
sco_etud,
sco_groups,
sco_permissions_check,
sco_report,
)
from app.scodoc.html_sidebar import retreive_formsemestre_from_request
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
def _menu_scolarite(
authuser, formsemestre: FormSemestre, etudid: int, etat_inscription: str
):
"""HTML pour menu "scolarite" pour un etudiant dans un semestre.
Le contenu du menu depend des droits de l'utilisateur et de l'état de l'étudiant.
"""
locked = not formsemestre.etat
if locked:
lockicon = scu.icontag(
"lock_25",
file_format="svg",
border="0",
height="20px",
title="Semestre verrouillé",
)
return lockicon # no menu
if not authuser.has_permission(
Permission.EtudInscrit
) and not authuser.has_permission(Permission.EtudChangeGroups):
return "" # no menu
args = {"etudid": etudid, "formsemestre_id": formsemestre.id}
if etat_inscription != scu.DEMISSION:
dem_title = "Démission"
dem_url = "scolar.form_dem"
else:
dem_title = "Annuler la démission"
dem_url = "scolar.do_cancel_dem"
# Note: seul un etudiant inscrit (I) peut devenir défaillant.
if etat_inscription != codes_cursus.DEF:
def_title = "Déclarer défaillance"
def_url = "scolar.form_def"
elif etat_inscription == codes_cursus.DEF:
def_title = "Annuler la défaillance"
def_url = "scolar.do_cancel_def"
def_enabled = (
(etat_inscription != scu.DEMISSION)
and authuser.has_permission(Permission.EtudInscrit)
and not locked
)
items = [
{
"title": dem_title,
"endpoint": dem_url,
"args": args,
"enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
},
{
"title": "Validation du semestre (jury)",
"endpoint": "notes.formsemestre_validation_etud_form",
"args": args,
"enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
},
{
"title": def_title,
"endpoint": def_url,
"args": args,
"enabled": def_enabled,
},
{
"title": "Désinscrire (en cas d'erreur)",
"endpoint": "notes.formsemestre_desinscription",
"args": args,
"enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
},
{
"title": "Inscrire à un module optionnel (ou au sport)",
"endpoint": "notes.formsemestre_inscription_option",
"args": args,
"enabled": authuser.has_permission(Permission.EtudInscrit) and not locked,
},
{
"title": "Gérer les validations d'UEs antérieures",
"endpoint": "notes.formsemestre_validate_previous_ue",
"args": args,
"enabled": formsemestre.can_edit_jury(),
},
{
"title": "Enregistrer un semestre effectué ailleurs",
"endpoint": "notes.formsemestre_ext_create_form",
"args": args,
"enabled": authuser.has_permission(Permission.EditFormSemestre),
},
{
"title": "Affecter les notes manquantes",
"endpoint": "notes.formsemestre_note_etuds_sans_notes",
"args": args,
"enabled": authuser.has_permission(Permission.EditAllNotes),
},
{
"title": "Inscrire à un autre semestre",
"endpoint": "notes.formsemestre_inscription_with_modules_form",
"args": {"etudid": etudid},
"enabled": authuser.has_permission(Permission.EtudInscrit),
},
]
return htmlutils.make_menu(
"Scolarité", items, css_class="direction_etud", alone=True
)
def fiche_etud(etudid=None):
"fiche d'informations sur un etudiant"
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
g.etudid = etudid
info = etud.to_dict_scodoc7(restrict=restrict_etud_data)
if etud.prenom_etat_civil:
info["etat_civil"] = (
"<h3>Etat-civil: "
+ etud.civilite_etat_civil_str
+ " "
+ etud.prenom_etat_civil
+ " "
+ etud.nom
+ "</h3>"
)
else:
info["etat_civil"] = ""
info["ScoURL"] = url_for("scolar.index_html", scodoc_dept=g.scodoc_dept)
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']})"
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 current_user.has_permission(
Permission.EtudChangeAdr
) and current_user.has_permission(Permission.ViewEtudData):
info[
"modifadresse"
] = f"""<a class="stdlink" href="{
url_for("scolar.form_change_coordonnees",
scodoc_dept=g.scodoc_dept, etudid=etudid)
}">modifier adresse</a>"""
else:
info["modifadresse"] = ""
# Groupes:
inscription_courante = etud.inscription_courante()
sco_groups.etud_add_group_infos(
info,
inscription_courante.formsemestre.id if inscription_courante else None,
only_to_show=True,
)
# Parcours de l'étudiant
last_formsemestre = None
inscriptions = etud.inscriptions()
info["last_formsemestre_id"] = (
inscriptions[0].formsemestre.id if inscriptions else ""
)
sem_info = {}
for inscription in inscriptions:
formsemestre = inscription.formsemestre
if inscription.etat != scu.INSCRIT:
descr, _ = etud_descr_situation_semestre(
etudid,
formsemestre,
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, formsemestre.id, only_to_show=True)
grlinks = []
for partition in e["partitions"].values():
if partition["partition_name"]:
gr_name = partition["group_name"]
else:
gr_name = "tous"
grlinks.append(
f"""<a class="discretelink" href="{
url_for('scolar.groups_lists',
scodoc_dept=g.scodoc_dept, group_ids=partition['group_id'])
}" title="Liste du groupe {gr_name}">{gr_name}</a>
"""
)
grlink = ", ".join(grlinks)
# infos ajoutées au semestre dans le parcours (groupe, menu)
menu = _menu_scolarite(current_user, formsemestre, etudid, inscription.etat)
if menu:
sem_info[formsemestre.id] = (
"<table><tr><td>" + grlink + "</td><td>" + menu + "</td></tr></table>"
)
else:
sem_info[formsemestre.id] = grlink
if inscriptions:
Se = sco_cursus.get_situation_etud_cursus(etud, info["last_formsemestre_id"])
info["liste_inscriptions"] = formsemestre_recap_parcours_table(
Se,
etudid,
with_links=False,
sem_info=sem_info,
with_all_columns=False,
)
info["link_bul_pdf"] = (
"""<span class="link_bul_pdf fontred">PDF interdits par l'admin.</span>"""
if ScoDocSiteConfig.is_bul_pdf_disabled()
else f"""
<span class="link_bul_pdf">
<a class="stdlink" href="{
url_for("notes.etud_bulletins_pdf", scodoc_dept=g.scodoc_dept, etudid=etudid)
}">Tous les bulletins</a>
</span>
"""
)
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)
}">Visualiser les compétences BUT</a>
</span>
"""
info["link_inscrire_ailleurs"] = (
f"""<span class="link_bul_pdf"><a class="stdlink" href="{
url_for("notes.formsemestre_inscription_with_modules_form",
scodoc_dept=g.scodoc_dept, etudid=etudid)
}">Inscrire à un autre semestre</a></span>
"""
if current_user.has_permission(Permission.EtudInscrit)
else ""
)
can_edit_jury = current_user.has_permission(Permission.EtudInscrit)
info[
"link_inscrire_ailleurs"
] += f"""
<span class="link_bul_pdf"><a class="stdlink" href="{
url_for("notes.jury_delete_manual",
scodoc_dept=g.scodoc_dept, etudid=etudid,
read_only=not can_edit_jury)
}">{'Éditer' if can_edit_jury else 'Détail de'} toutes décisions de jury</a></span>
"""
info[
"link_bilan_ects"
] = f"""<span class="link_bul_pdf"><a class="stdlink" href="{
url_for("notes.etud_bilan_ects",
scodoc_dept=g.scodoc_dept, etudid=etudid)
}">ECTS</a></span>"""
else:
# non inscrit
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",
scodoc_dept=g.scodoc_dept, etudid=etudid)
}">inscrire</a></li>"""
)
l.append("</b></b>")
info["liste_inscriptions"] = "\n".join(l)
info["link_bul_pdf"] = ""
info["link_inscrire_ailleurs"] = ""
info["link_bilan_ects"] = ""
# Liste des annotations
html_annotations_list = "\n".join(
[] if restrict_etud_data else get_html_annotations_list(etud)
)
# fiche admission
if etud.admission:
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",
)
)
if has_bac_info or has_adm_notes:
adm_tmpl = """<!-- Donnees admission -->
<div class="fichetitre">Informations admission</div>
"""
if has_adm_notes:
adm_tmpl += """
<table>
<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_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>
</tr>
</table>
"""
adm_tmpl += """
<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 infos_admission["type_admission"]:
adm_tmpl += """<span>Voie d'admission: <span class="etud_type_admission">%(type_admission)s</span></span> """
if infos_admission["classement"]:
adm_tmpl += """<span>Rang admission: <span class="etud_type_admission">%(classement)s</span></span>"""
if infos_admission["type_admission"] or infos_admission["classement"]:
adm_tmpl += "</div>"
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 % infos_admission
else:
info["adm_data"] = ""
# Fichiers archivés:
info["fichiers_archive_htm"] = (
""
if restrict_etud_data
else (
'<div class="fichetitre">Fichiers associés</div>'
+ sco_archives_etud.etud_list_archives_html(etud)
)
)
# Modules & Notes
info["module_html"] = "<div> TEST </div>"
# Devenir de l'étudiant:
has_debouche = True
if sco_permissions_check.can_edit_suivi():
suivi_readonly = "0"
link_add_suivi = """<li class="adddebouche">
<a id="adddebouchelink" class="stdlink" href="#">ajouter une ligne</a>
</li>"""
else:
suivi_readonly = "1"
link_add_suivi = ""
if has_debouche:
info[
"debouche_html"
] = f"""<div id="fichedebouche"
data-readonly="{suivi_readonly}"
data-etudid="{info['etudid']}">
<span class="debouche_tit">Devenir:</span>
<div><form>
<ul class="listdebouches">
{link_add_suivi}
</ul>
</form></div>
</div>"""
else:
info["debouche_html"] = "" # pas de boite "devenir"
# Inscriptions
info[
"inscriptions_mkup"
] = f"""<div class="ficheinscriptions" id="ficheinscriptions">
<div class="fichetitre">Cursus</div>{info["liste_inscriptions"]}
{info["link_bul_pdf"]}
{info["link_inscrire_ailleurs"]}
{info["link_bilan_ects"]}
</div>"""
#
if info["groupes"].strip():
info[
"groupes_row"
] = f"""<tr>
<td class="fichetitre2">Groupes :</td><td>{info['groupes']}</td>
</tr>"""
else:
info["groupes_row"] = ""
info["menus_etud"] = menus_etud(etudid)
if info["boursier"] and not restrict_etud_data:
info["bourse_span"] = """<span class="boursier">boursier</span>"""
else:
info["bourse_span"] = ""
# Liens vers compétences BUT
if last_formsemestre and last_formsemestre.formation.is_apc():
try:
but_cursus = cursus_but.EtudCursusBUT(etud, last_formsemestre.formation)
except ScoValueError:
but_cursus = None
refcomp = last_formsemestre.formation.referentiel_competence
if refcomp:
ue_validation_by_niveau = validations_view.get_ue_validation_by_niveau(
refcomp, etud
)
ects_total = sum((v.ects() for v in ue_validation_by_niveau.values()))
else:
ects_total = ""
validation_dut120 = ValidationDUT120.query.filter_by(etudid=etudid).first()
validation_dut120_html = (
f"""Diplôme DUT décerné
en <a class="stdlink" href="{
url_for("notes.formsemestre_status",
scodoc_dept=g.scodoc_dept,
formsemestre_id=validation_dut120.formsemestre.id)
}">S{validation_dut120.formsemestre.semestre_id}</a>
"""
if validation_dut120
else ""
)
info[
"but_cursus_mkup"
] = f"""
<div class="section_but">
{render_template(
"but/cursus_etud.j2",
cursus=but_cursus,
scu=scu,
validation_dut120_html=validation_dut120_html,
) if but_cursus else '<span class="pb-config">problème configuration formation BUT</span>'}
<div class="fiche_but_col2">
<div class="link_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="132px"/>
<div style="text-align: center;">Compétences BUT</div>
</a>
</div>
<div class="fiche_total_etcs">
Total ECTS BUT : {(float(ects_total) if ects_total else 0):g}
</div>
</div>
</div>
"""
else:
info["but_cursus_mkup"] = ""
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
{info_naissance}
</table>
"""
+ adresse_template
+ """
</div>
</div>
"""
)
info["annotations_mkup"] = (
f"""
<div class="ficheannotations">
<div class="fichetitre">Annotations</div>
<table id="etudannotations">{html_annotations_list}</table>
<form action="doAddAnnotation" method="GET" class="noprint">
<input type="hidden" name="etudid" value="{etudid}">
<b>Ajouter une annotation sur {etud.nomprenom}: </b>
<div>
<textarea name="comment" rows="4" cols="50" value=""></textarea>
<div style="font-size: small; font-style: italic;">
<div>Ces annotations sont lisibles par tous les utilisateurs ayant la permission
<tt>ViewEtudData</tt> dans ce département (souvent les enseignants et le
secrétariat).
</div>
<div>L'annotation commençant par "PE:" est un avis de poursuite d'études.</div>
</div>
</div>
<input type="hidden" name="author" width=12 value="{current_user}">
<input type="submit" value="Ajouter annotation">
</form>
</div>
"""
if not restrict_etud_data
else ""
)
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)s">%(etudfoto)s</a>
</td></tr></table>
"""
+ situation_template
+ """
%(inscriptions_mkup)s
%(but_cursus_mkup)s
<div class="ficheadmission">
%(adm_data)s
%(fichiers_archive_htm)s
</div>
%(module_html)s
%(debouche_html)s
%(annotations_mkup)s
<div class="code_nip">code NIP: %(code_nip)s</div>
</div>
"""
)
return render_template(
"sco_page_dept.j2",
content=tmpl % info,
title=f"Fiche étudiant {etud.nomprenom}",
cssstyles=[
"libjs/jQuery-tagEditor/jquery.tag-editor.css",
"css/jury_but.css",
"css/cursus_but.css",
],
javascripts=[
"libjs/jinplace-1.2.1.min.js",
"js/ue_list.js",
"libjs/jQuery-tagEditor/jquery.tag-editor.min.js",
"libjs/jQuery-tagEditor/jquery.caret.min.js",
"js/recap_parcours.js",
"js/etud_debouche.js",
],
)
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 admission 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 get_html_annotations_list(etud: Identite) -> list[str]:
"""Liste de chaînes html décrivant les annotations."""
html_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=etud.id, 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 = User.query.filter_by(user_name=annot.author).first()
html_annotations_list.append(
f"""<tr><td><span class="annodate">Le {
annot.date.strftime(scu.DATE_FMT) if annot.date else "?"}
par {author.get_prenomnom() if author else "?"} :
</span><span class="annoc">{annot.comment or ""}</span></td>{del_link}</tr>
"""
)
return html_annotations_list
def menus_etud(etudid):
"""Menu etudiant (operations sur l'etudiant)"""
authuser = current_user
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
menuEtud = [
{
"title": etud["nomprenom"],
"endpoint": "scolar.fiche_etud",
"args": {"etudid": etud["etudid"]},
"enabled": True,
"helpmsg": "Fiche étudiant",
},
{
"title": "Changer la photo",
"endpoint": "scolar.form_change_photo",
"args": {"etudid": etud["etudid"]},
"enabled": authuser.has_permission(Permission.EtudChangeAdr),
},
{
"title": "Changer les données identité/admission",
"endpoint": "scolar.etudident_edit_form",
"args": {"etudid": etud["etudid"]},
"enabled": authuser.has_permission(Permission.EtudInscrit)
and authuser.has_permission(Permission.ViewEtudData),
},
{
"title": "Copier dans un autre département...",
"endpoint": "scolar.etud_copy_in_other_dept",
"args": {"etudid": etud["etudid"]},
"enabled": authuser.has_permission(Permission.EtudInscrit),
},
{
"title": "Supprimer cet étudiant...",
"endpoint": "scolar.etudident_delete",
"args": {"etudid": etud["etudid"]},
"enabled": authuser.has_permission(Permission.EtudInscrit),
},
{
"title": "Voir le journal...",
"endpoint": "scolar.show_etud_log",
"args": {"etudid": etud["etudid"]},
"enabled": True,
},
]
return htmlutils.make_menu(
"Étudiant", menuEtud, alone=True, css_class="menu-etudiant"
)
def etud_info_html(etudid, with_photo="1", debug=False):
"""An HTML div with basic information and links about this etud.
Used for popups information windows.
"""
formsemestre_id = retreive_formsemestre_from_request()
with_photo = int(with_photo)
etud = Identite.get_etud(etudid)
photo_html = etud.photo_html(title="fiche de " + etud.nomprenom)
code_cursus, _ = sco_report.get_code_cursus_etud(
etud, formsemestres=etud.get_formsemestres(), prefix="S", separator=", "
)
if etud.admission:
bac = sco_bac.Baccalaureat(etud.admission.bac, etud.admission.specialite)
bac_abbrev = bac.abbrev()
else:
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.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:
if formsemestre_id: # un semestre est spécifié par la page
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
else:
# le semestre "en cours" pour l'étudiant
inscription_courante = etud.inscription_courante()
formsemestre = (
inscription_courante.formsemestre if inscription_courante else None
)
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{formsemestre.semestre_id}</b>: {grc}</div>"""
H += "</div>" # fin partie gauche (eid_left)
if with_photo:
H += '<span class="eid_right">' + photo_html + "</span>"
H += "</div>"
if debug:
return render_template("sco_page.j2", title="debug", content=H)
return H