forked from ScoDoc/ScoDoc
modernisation/methodes sur Identite/bul. head.
This commit is contained in:
parent
c923a5015b
commit
8f911234b2
@ -224,7 +224,7 @@ class BulletinBUT:
|
|||||||
(bulletins non publiés).
|
(bulletins non publiés).
|
||||||
"""
|
"""
|
||||||
res = self.res
|
res = self.res
|
||||||
etat_inscription = etud.etat_inscription(formsemestre.id)
|
etat_inscription = etud.inscription_etat(formsemestre.id)
|
||||||
nb_inscrits = self.res.get_inscriptions_counts()[scu.INSCRIT]
|
nb_inscrits = self.res.get_inscriptions_counts()[scu.INSCRIT]
|
||||||
published = (not formsemestre.bul_hide_xml) or force_publishing
|
published = (not formsemestre.bul_hide_xml) or force_publishing
|
||||||
d = {
|
d = {
|
||||||
|
@ -72,7 +72,7 @@ def bulletin_but_xml_compat(
|
|||||||
etud: Identite = Identite.query.get_or_404(etudid)
|
etud: Identite = Identite.query.get_or_404(etudid)
|
||||||
results = bulletin_but.ResultatsSemestreBUT(formsemestre)
|
results = bulletin_but.ResultatsSemestreBUT(formsemestre)
|
||||||
nb_inscrits = results.get_inscriptions_counts()[scu.INSCRIT]
|
nb_inscrits = results.get_inscriptions_counts()[scu.INSCRIT]
|
||||||
# etat_inscription = etud.etat_inscription(formsemestre.id)
|
# etat_inscription = etud.inscription_etat(formsemestre.id)
|
||||||
etat_inscription = results.formsemestre.etuds_inscriptions[etudid].etat
|
etat_inscription = results.formsemestre.etuds_inscriptions[etudid].etat
|
||||||
if (not formsemestre.bul_hide_xml) or force_publishing:
|
if (not formsemestre.bul_hide_xml) or force_publishing:
|
||||||
published = 1
|
published = 1
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
et données rattachées (adresses, annotations, ...)
|
et données rattachées (adresses, annotations, ...)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from flask import abort, url_for
|
from flask import abort, url_for
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
from sqlalchemy import desc, text
|
||||||
|
|
||||||
from app import db
|
from app import db, log
|
||||||
from app import models
|
from app import models
|
||||||
|
|
||||||
from app.scodoc import notesdb as ndb
|
from app.scodoc import notesdb as ndb
|
||||||
@ -82,6 +84,11 @@ class Identite(db.Model):
|
|||||||
return scu.suppress_accents(s)
|
return scu.suppress_accents(s)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
@property
|
||||||
|
def e(self):
|
||||||
|
"terminaison en français: 'ne', '', 'ou '(e)'"
|
||||||
|
return {"M": "", "F": "e"}.get(self.civilite, "(e)")
|
||||||
|
|
||||||
def nom_disp(self) -> str:
|
def nom_disp(self) -> str:
|
||||||
"Nom à afficher"
|
"Nom à afficher"
|
||||||
if self.nom_usuel:
|
if self.nom_usuel:
|
||||||
@ -123,7 +130,7 @@ class Identite(db.Model):
|
|||||||
|
|
||||||
def get_first_email(self, field="email") -> str:
|
def get_first_email(self, field="email") -> str:
|
||||||
"Le mail associé à la première adrese de l'étudiant, ou None"
|
"Le mail associé à la première adrese de l'étudiant, ou None"
|
||||||
return self.adresses[0].email or None if self.adresses.count() > 0 else None
|
return getattr(self.adresses[0], field) if self.adresses.count() > 0 else None
|
||||||
|
|
||||||
def to_dict_scodoc7(self):
|
def to_dict_scodoc7(self):
|
||||||
"""Représentation dictionnaire,
|
"""Représentation dictionnaire,
|
||||||
@ -134,7 +141,7 @@ class Identite(db.Model):
|
|||||||
# ScoDoc7 output_formators: (backward compat)
|
# ScoDoc7 output_formators: (backward compat)
|
||||||
e["etudid"] = self.id
|
e["etudid"] = self.id
|
||||||
e["date_naissance"] = ndb.DateISOtoDMY(e["date_naissance"])
|
e["date_naissance"] = ndb.DateISOtoDMY(e["date_naissance"])
|
||||||
e["ne"] = {"M": "", "F": "ne"}.get(self.civilite, "(e)")
|
e["ne"] = self.e
|
||||||
return {k: e[k] or "" for k in e} # convert_null_outputs_to_empty
|
return {k: e[k] or "" for k in e} # convert_null_outputs_to_empty
|
||||||
|
|
||||||
def to_dict_bul(self, include_urls=True):
|
def to_dict_bul(self, include_urls=True):
|
||||||
@ -172,6 +179,23 @@ class Identite(db.Model):
|
|||||||
]
|
]
|
||||||
return r[0] if r else None
|
return r[0] if r else None
|
||||||
|
|
||||||
|
def inscriptions_courantes(self) -> list: # -> list[FormSemestreInscription]:
|
||||||
|
"""Liste des inscriptions à des semestres _courants_
|
||||||
|
(il est rare qu'il y en ai plus d'une, mais c'est possible).
|
||||||
|
Triées par date de début de semestre décroissante (le plus récent en premier).
|
||||||
|
"""
|
||||||
|
from app.models.formsemestre import FormSemestre, FormSemestreInscription
|
||||||
|
|
||||||
|
return (
|
||||||
|
FormSemestreInscription.query.join(FormSemestreInscription.formsemestre)
|
||||||
|
.filter(
|
||||||
|
FormSemestreInscription.etudid == self.id,
|
||||||
|
text("date_debut < now() and date_fin > now()"),
|
||||||
|
)
|
||||||
|
.order_by(desc(FormSemestre.date_debut))
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
def inscription_courante_date(self, date_debut, date_fin):
|
def inscription_courante_date(self, date_debut, date_fin):
|
||||||
"""La première inscription à un formsemestre incluant la
|
"""La première inscription à un formsemestre incluant la
|
||||||
période [date_debut, date_fin]
|
période [date_debut, date_fin]
|
||||||
@ -183,8 +207,8 @@ class Identite(db.Model):
|
|||||||
]
|
]
|
||||||
return r[0] if r else None
|
return r[0] if r else None
|
||||||
|
|
||||||
def etat_inscription(self, formsemestre_id):
|
def inscription_etat(self, formsemestre_id):
|
||||||
"""etat de l'inscription de cet étudiant au semestre:
|
"""État de l'inscription de cet étudiant au semestre:
|
||||||
False si pas inscrit, ou scu.INSCRIT, DEMISSION, DEF
|
False si pas inscrit, ou scu.INSCRIT, DEMISSION, DEF
|
||||||
"""
|
"""
|
||||||
# voir si ce n'est pas trop lent:
|
# voir si ce n'est pas trop lent:
|
||||||
@ -195,6 +219,110 @@ class Identite(db.Model):
|
|||||||
return ins.etat
|
return ins.etat
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def inscription_descr(self) -> dict:
|
||||||
|
"""Description de l'état d'inscription"""
|
||||||
|
inscription_courante = self.inscription_courante()
|
||||||
|
if inscription_courante:
|
||||||
|
titre_sem = inscription_courante.formsemestre.titre_mois()
|
||||||
|
return {
|
||||||
|
"etat_in_cursem": inscription_courante.etat,
|
||||||
|
"inscription_courante": inscription_courante,
|
||||||
|
"inscription": titre_sem,
|
||||||
|
"inscription_str": "Inscrit en " + titre_sem,
|
||||||
|
"situation": self.descr_situation_etud(),
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
if self.formsemestre_inscriptions:
|
||||||
|
# cherche l'inscription la plus récente:
|
||||||
|
fin_dernier_sem = max(
|
||||||
|
[
|
||||||
|
inscr.formsemestre.date_debut
|
||||||
|
for inscr in self.formsemestre_inscriptions
|
||||||
|
]
|
||||||
|
)
|
||||||
|
if fin_dernier_sem > datetime.date.today():
|
||||||
|
inscription = "futur"
|
||||||
|
situation = "futur élève"
|
||||||
|
else:
|
||||||
|
inscription = "ancien"
|
||||||
|
situation = "ancien élève"
|
||||||
|
else:
|
||||||
|
inscription = ("non inscrit",)
|
||||||
|
situation = inscription
|
||||||
|
return {
|
||||||
|
"etat_in_cursem": "?",
|
||||||
|
"inscription_courante": None,
|
||||||
|
"inscription": inscription,
|
||||||
|
"inscription_str": inscription,
|
||||||
|
"situation": situation,
|
||||||
|
}
|
||||||
|
|
||||||
|
def descr_situation_etud(self) -> str:
|
||||||
|
"""Chaîne décrivant la situation _actuelle_ de l'étudiant.
|
||||||
|
Exemple:
|
||||||
|
"inscrit en BUT R&T semestre 2 FI (Jan 2022 - Jul 2022) le 16/01/2022"
|
||||||
|
ou
|
||||||
|
"non inscrit"
|
||||||
|
"""
|
||||||
|
inscriptions_courantes = self.inscriptions_courantes()
|
||||||
|
if inscriptions_courantes:
|
||||||
|
inscr = inscriptions_courantes[0]
|
||||||
|
if inscr.etat == scu.INSCRIT:
|
||||||
|
situation = f"inscrit{self.e} en {inscr.formsemestre.titre_mois()}"
|
||||||
|
# Cherche la date d'inscription dans scolar_events:
|
||||||
|
events = models.ScolarEvent.query.filter_by(
|
||||||
|
etudid=self.id,
|
||||||
|
formsemestre_id=inscr.formsemestre.id,
|
||||||
|
event_type="INSCRIPTION",
|
||||||
|
).all()
|
||||||
|
if not events:
|
||||||
|
log(
|
||||||
|
f"*** situation inconsistante pour {self} (inscrit mais pas d'event)"
|
||||||
|
)
|
||||||
|
date_ins = "???" # ???
|
||||||
|
else:
|
||||||
|
date_ins = events[0].event_date
|
||||||
|
situation += date_ins.strftime(" le %d/%m/%Y")
|
||||||
|
else:
|
||||||
|
situation = f"démission de {inscr.formsemestre.titre_mois()}"
|
||||||
|
# Cherche la date de demission dans scolar_events:
|
||||||
|
events = models.ScolarEvent.query.filter_by(
|
||||||
|
etudid=self.id,
|
||||||
|
formsemestre_id=inscr.formsemestre.id,
|
||||||
|
event_type="DEMISSION",
|
||||||
|
).all()
|
||||||
|
if not events:
|
||||||
|
log(
|
||||||
|
f"*** situation inconsistante pour {self} (demission mais pas d'event)"
|
||||||
|
)
|
||||||
|
date_dem = "???" # ???
|
||||||
|
else:
|
||||||
|
date_dem = events[0].event_date
|
||||||
|
situation += date_dem.strftime(" le %d/%m/%Y")
|
||||||
|
else:
|
||||||
|
situation = "non inscrit" + self.e
|
||||||
|
|
||||||
|
return situation
|
||||||
|
|
||||||
|
def photo_html(self, title=None, size="small") -> str:
|
||||||
|
"""HTML img tag for the photo, either in small size (h90)
|
||||||
|
or original size (size=="orig")
|
||||||
|
"""
|
||||||
|
from app.scodoc import sco_photos
|
||||||
|
|
||||||
|
# sco_photo traite des dicts:
|
||||||
|
return sco_photos.etud_photo_html(
|
||||||
|
etud=dict(
|
||||||
|
etudid=self.id,
|
||||||
|
code_nip=self.code_nip,
|
||||||
|
nomprenom=self.nomprenom,
|
||||||
|
nom_disp=self.nom_disp(),
|
||||||
|
photo_filename=self.photo_filename,
|
||||||
|
),
|
||||||
|
title=title,
|
||||||
|
size=size,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def make_etud_args(
|
def make_etud_args(
|
||||||
etudid=None, code_nip=None, use_request=True, raise_exc=False, abort_404=True
|
etudid=None, code_nip=None, use_request=True, raise_exc=False, abort_404=True
|
||||||
|
@ -12,7 +12,6 @@ from app import log
|
|||||||
from app.models import APO_CODE_STR_LEN
|
from app.models import APO_CODE_STR_LEN
|
||||||
from app.models import SHORT_STR_LEN
|
from app.models import SHORT_STR_LEN
|
||||||
from app.models import CODE_STR_LEN
|
from app.models import CODE_STR_LEN
|
||||||
from app.models import UniteEns
|
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.models.ues import UniteEns
|
from app.models.ues import UniteEns
|
||||||
|
@ -6,7 +6,8 @@ import flask_sqlalchemy
|
|||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app.comp import df_cache
|
from app.comp import df_cache
|
||||||
from app.models import Identite, Module
|
from app.models.etudiants import Identite
|
||||||
|
from app.models.modules import Module
|
||||||
|
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
@ -29,13 +29,11 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
import email
|
import email
|
||||||
import pprint
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
from flask import url_for
|
from flask import render_template, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from flask_mail import Message
|
|
||||||
|
|
||||||
from app import email
|
from app import email
|
||||||
from app import log
|
from app import log
|
||||||
@ -802,18 +800,10 @@ def formsemestre_bulletinetud(
|
|||||||
prefer_mail_perso=False,
|
prefer_mail_perso=False,
|
||||||
):
|
):
|
||||||
"page bulletin de notes"
|
"page bulletin de notes"
|
||||||
try:
|
etud: Identite = Identite.query.get_or_404(etudid)
|
||||||
etud = sco_etud.get_etud_info(filled=True)[0]
|
|
||||||
etudid = etud["etudid"]
|
|
||||||
except:
|
|
||||||
sco_etud.log_unknown_etud()
|
|
||||||
raise ScoValueError("étudiant inconnu")
|
|
||||||
|
|
||||||
formsemestre: FormSemestre = FormSemestre.query.get(formsemestre_id)
|
formsemestre: FormSemestre = FormSemestre.query.get(formsemestre_id)
|
||||||
if not formsemestre:
|
if not formsemestre:
|
||||||
# API, donc erreurs admises
|
|
||||||
raise ScoValueError(f"semestre {formsemestre_id} inconnu !")
|
raise ScoValueError(f"semestre {formsemestre_id} inconnu !")
|
||||||
sem = formsemestre.to_dict()
|
|
||||||
|
|
||||||
bulletin = do_formsemestre_bulletinetud(
|
bulletin = do_formsemestre_bulletinetud(
|
||||||
formsemestre,
|
formsemestre,
|
||||||
@ -825,37 +815,39 @@ def formsemestre_bulletinetud(
|
|||||||
prefer_mail_perso=prefer_mail_perso,
|
prefer_mail_perso=prefer_mail_perso,
|
||||||
)[0]
|
)[0]
|
||||||
if format not in {"html", "pdfmail"}:
|
if format not in {"html", "pdfmail"}:
|
||||||
filename = scu.bul_filename(sem, etud, format)
|
filename = scu.bul_filename(formsemestre, etud, format)
|
||||||
return scu.send_file(bulletin, filename, mime=scu.get_mime_suffix(format)[0])
|
return scu.send_file(bulletin, filename, mime=scu.get_mime_suffix(format)[0])
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
_formsemestre_bulletinetud_header_html(
|
_formsemestre_bulletinetud_header_html(etud, formsemestre, format, version),
|
||||||
etud, etudid, formsemestre, format, version
|
|
||||||
),
|
|
||||||
bulletin,
|
bulletin,
|
||||||
]
|
]
|
||||||
|
|
||||||
H.append("""<p>Situation actuelle: """)
|
H.append("""<p>Situation actuelle: """)
|
||||||
if etud["inscription_formsemestre_id"]:
|
inscription_courante = etud.inscription_courante()
|
||||||
|
if inscription_courante:
|
||||||
H.append(
|
H.append(
|
||||||
f"""<a class="stdlink" href="{url_for(
|
f"""<a class="stdlink" href="{url_for(
|
||||||
"notes.formsemestre_status",
|
"notes.formsemestre_status",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=etud["inscription_formsemestre_id"])
|
formsemestre_id=inscription_courante.formsemestre_id)
|
||||||
}">"""
|
}">"""
|
||||||
)
|
)
|
||||||
H.append(etud["inscriptionstr"])
|
inscription_descr = etud.inscription_descr()
|
||||||
if etud["inscription_formsemestre_id"]:
|
H.append(inscription_descr["inscription_str"])
|
||||||
|
if inscription_courante:
|
||||||
H.append("""</a>""")
|
H.append("""</a>""")
|
||||||
H.append("""</p>""")
|
H.append("""</p>""")
|
||||||
if sem["modalite"] == "EXT":
|
if formsemestre.modalite == "EXT":
|
||||||
H.append(
|
H.append(
|
||||||
"""<p><a
|
f"""<p><a
|
||||||
href="formsemestre_ext_edit_ue_validations?formsemestre_id=%s&etudid=%s"
|
href="{url_for('notes.formsemestre_ext_edit_ue_validations',
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
|
etudid=etudid)}"
|
||||||
class="stdlink">
|
class="stdlink">
|
||||||
Editer les validations d'UE dans ce semestre extérieur
|
Éditer les validations d'UE dans ce semestre extérieur
|
||||||
</a></p>"""
|
</a></p>"""
|
||||||
% (formsemestre_id, etudid)
|
|
||||||
)
|
)
|
||||||
# Place du diagramme radar
|
# Place du diagramme radar
|
||||||
H.append(
|
H.append(
|
||||||
@ -1048,16 +1040,15 @@ def mail_bulletin(formsemestre_id, I, pdfdata, filename, recipient_addr):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _formsemestre_bulletinetud_header_html(
|
def _formsemestre_bulletinetud_header_html_old_XXX(
|
||||||
etud,
|
etud: Identite,
|
||||||
etudid,
|
|
||||||
formsemestre: FormSemestre,
|
formsemestre: FormSemestre,
|
||||||
format=None,
|
format=None,
|
||||||
version=None,
|
version=None,
|
||||||
):
|
):
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
html_sco_header.sco_header(
|
||||||
page_title="Bulletin de %(nomprenom)s" % etud,
|
page_title=f"Bulletin de {etud.nomprenom}",
|
||||||
javascripts=[
|
javascripts=[
|
||||||
"js/bulletin.js",
|
"js/bulletin.js",
|
||||||
"libjs/d3.v3.min.js",
|
"libjs/d3.v3.min.js",
|
||||||
@ -1068,8 +1059,8 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
f"""<table class="bull_head"><tr><td>
|
f"""<table class="bull_head"><tr><td>
|
||||||
<h2><a class="discretelink" href="{
|
<h2><a class="discretelink" href="{
|
||||||
url_for(
|
url_for(
|
||||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"]
|
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||||
)}">{etud["nomprenom"]}</a></h2>
|
)}">{etud.nomprenom}</a></h2>
|
||||||
|
|
||||||
<form name="f" method="GET" action="{request.base_url}">
|
<form name="f" method="GET" action="{request.base_url}">
|
||||||
Bulletin <span class="bull_liensemestre"><a href="{
|
Bulletin <span class="bull_liensemestre"><a href="{
|
||||||
@ -1082,7 +1073,7 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
<td>établi le {time.strftime("%d/%m/%Y à %Hh%M")} (notes sur 20)</td>
|
<td>établi le {time.strftime("%d/%m/%Y à %Hh%M")} (notes sur 20)</td>
|
||||||
<td><span class="rightjust">
|
<td><span class="rightjust">
|
||||||
<input type="hidden" name="formsemestre_id" value="{formsemestre.id}"></input>
|
<input type="hidden" name="formsemestre_id" value="{formsemestre.id}"></input>
|
||||||
<input type="hidden" name="etudid" value="{etudid}"></input>
|
<input type="hidden" name="etudid" value="{etud.id}"></input>
|
||||||
<input type="hidden" name="format" value="{format}"></input>
|
<input type="hidden" name="format" value="{format}"></input>
|
||||||
<select name="version" onchange="document.f.submit()" class="noprint">
|
<select name="version" onchange="document.f.submit()" class="noprint">
|
||||||
""",
|
""",
|
||||||
@ -1100,8 +1091,52 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
H.append("""</select></td>""")
|
H.append("""</select></td>""")
|
||||||
# Menu
|
# Menu
|
||||||
endpoint = "notes.formsemestre_bulletinetud"
|
endpoint = "notes.formsemestre_bulletinetud"
|
||||||
|
menu_autres_operations = make_menu_autres_operations(
|
||||||
|
formsemestre, etud, endpoint, version
|
||||||
|
)
|
||||||
|
|
||||||
menuBul = [
|
H.append("""<td class="bulletin_menubar"><div class="bulletin_menubar">""")
|
||||||
|
H.append(menu_autres_operations)
|
||||||
|
H.append("""</div></td>""")
|
||||||
|
H.append(
|
||||||
|
'<td> <a href="%s">%s</a></td>'
|
||||||
|
% (
|
||||||
|
url_for(
|
||||||
|
"notes.formsemestre_bulletinetud",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre.id,
|
||||||
|
etudid=etud.id,
|
||||||
|
format="pdf",
|
||||||
|
version=version,
|
||||||
|
),
|
||||||
|
scu.ICON_PDF,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
H.append("""</tr></table>""")
|
||||||
|
#
|
||||||
|
H.append(
|
||||||
|
"""</form></span></td><td class="bull_photo"><a href="%s">%s</a>
|
||||||
|
"""
|
||||||
|
% (
|
||||||
|
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id),
|
||||||
|
sco_photos.etud_photo_html(etud, title="fiche de " + etud.nomprenom),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
H.append(
|
||||||
|
"""</td></tr>
|
||||||
|
</table>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return "".join(H)
|
||||||
|
|
||||||
|
|
||||||
|
def make_menu_autres_operations(
|
||||||
|
formsemestre: FormSemestre, etud: Identite, endpoint: str, version: str
|
||||||
|
) -> str:
|
||||||
|
etud_email = etud.get_first_email() or ""
|
||||||
|
etud_perso = etud.get_first_email("emailperso") or ""
|
||||||
|
menu_items = [
|
||||||
{
|
{
|
||||||
"title": "Réglages bulletins",
|
"title": "Réglages bulletins",
|
||||||
"endpoint": "notes.formsemestre_edit_options",
|
"endpoint": "notes.formsemestre_edit_options",
|
||||||
@ -1124,43 +1159,42 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
"endpoint": endpoint,
|
"endpoint": endpoint,
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
"version": version,
|
"version": version,
|
||||||
"format": "pdf",
|
"format": "pdf",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Envoi par mail à %s" % etud["email"],
|
"title": f"Envoi par mail à {etud_email}",
|
||||||
"endpoint": endpoint,
|
"endpoint": endpoint,
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
"version": version,
|
"version": version,
|
||||||
"format": "pdfmail",
|
"format": "pdfmail",
|
||||||
},
|
},
|
||||||
# possible slt si on a un mail...
|
# possible slt si on a un mail...
|
||||||
"enabled": etud["email"] and can_send_bulletin_by_mail(formsemestre.id),
|
"enabled": etud_email and can_send_bulletin_by_mail(formsemestre.id),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Envoi par mail à %s (adr. personnelle)" % etud["emailperso"],
|
"title": f"Envoi par mail à {etud_perso} (adr. personnelle)",
|
||||||
"endpoint": endpoint,
|
"endpoint": endpoint,
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
"version": version,
|
"version": version,
|
||||||
"format": "pdfmail",
|
"format": "pdfmail",
|
||||||
"prefer_mail_perso": 1,
|
"prefer_mail_perso": 1,
|
||||||
},
|
},
|
||||||
# possible slt si on a un mail...
|
# possible slt si on a un mail...
|
||||||
"enabled": etud["emailperso"]
|
"enabled": etud_perso and can_send_bulletin_by_mail(formsemestre.id),
|
||||||
and can_send_bulletin_by_mail(formsemestre.id),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Version json",
|
"title": "Version json",
|
||||||
"endpoint": endpoint,
|
"endpoint": endpoint,
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
"version": version,
|
"version": version,
|
||||||
"format": "json",
|
"format": "json",
|
||||||
},
|
},
|
||||||
@ -1170,7 +1204,7 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
"endpoint": endpoint,
|
"endpoint": endpoint,
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
"version": version,
|
"version": version,
|
||||||
"format": "xml",
|
"format": "xml",
|
||||||
},
|
},
|
||||||
@ -1180,7 +1214,7 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
"endpoint": "notes.appreciation_add_form",
|
"endpoint": "notes.appreciation_add_form",
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
},
|
},
|
||||||
"enabled": (
|
"enabled": (
|
||||||
formsemestre.can_be_edited_by(current_user)
|
formsemestre.can_be_edited_by(current_user)
|
||||||
@ -1192,7 +1226,7 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
"endpoint": "notes.formsemestre_ext_create_form",
|
"endpoint": "notes.formsemestre_ext_create_form",
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
},
|
},
|
||||||
"enabled": current_user.has_permission(Permission.ScoImplement),
|
"enabled": current_user.has_permission(Permission.ScoImplement),
|
||||||
},
|
},
|
||||||
@ -1201,7 +1235,7 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
"endpoint": "notes.formsemestre_validate_previous_ue",
|
"endpoint": "notes.formsemestre_validate_previous_ue",
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
},
|
},
|
||||||
"enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
|
"enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
|
||||||
},
|
},
|
||||||
@ -1210,7 +1244,7 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
"endpoint": "notes.external_ue_create_form",
|
"endpoint": "notes.external_ue_create_form",
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
},
|
},
|
||||||
"enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
|
"enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
|
||||||
},
|
},
|
||||||
@ -1219,7 +1253,7 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
"endpoint": "notes.formsemestre_validation_etud_form",
|
"endpoint": "notes.formsemestre_validation_etud_form",
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
},
|
},
|
||||||
"enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
|
"enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
|
||||||
},
|
},
|
||||||
@ -1228,43 +1262,44 @@ def _formsemestre_bulletinetud_header_html(
|
|||||||
"endpoint": "notes.formsemestre_pvjury_pdf",
|
"endpoint": "notes.formsemestre_pvjury_pdf",
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
"etudid": etudid,
|
"etudid": etud.id,
|
||||||
},
|
},
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
return htmlutils.make_menu("Autres opérations", menu_items, alone=True)
|
||||||
|
|
||||||
H.append("""<td class="bulletin_menubar"><div class="bulletin_menubar">""")
|
|
||||||
H.append(htmlutils.make_menu("Autres opérations", menuBul, alone=True))
|
def _formsemestre_bulletinetud_header_html(
|
||||||
H.append("""</div></td>""")
|
etud,
|
||||||
H.append(
|
formsemestre: FormSemestre,
|
||||||
'<td> <a href="%s">%s</a></td>'
|
format=None,
|
||||||
% (
|
version=None,
|
||||||
url_for(
|
):
|
||||||
"notes.formsemestre_bulletinetud",
|
H = [
|
||||||
scodoc_dept=g.scodoc_dept,
|
html_sco_header.sco_header(
|
||||||
formsemestre_id=formsemestre.id,
|
page_title=f"Bulletin de {etud.nomprenom}",
|
||||||
etudid=etudid,
|
javascripts=[
|
||||||
format="pdf",
|
"js/bulletin.js",
|
||||||
|
"libjs/d3.v3.min.js",
|
||||||
|
"js/radar_bulletin.js",
|
||||||
|
],
|
||||||
|
cssstyles=["css/radar_bulletin.css"],
|
||||||
|
),
|
||||||
|
render_template(
|
||||||
|
"bul_head.html",
|
||||||
|
etud=etud,
|
||||||
|
format=format,
|
||||||
|
formsemestre=formsemestre,
|
||||||
|
menu_autres_operations=make_menu_autres_operations(
|
||||||
|
etud=etud,
|
||||||
|
formsemestre=formsemestre,
|
||||||
|
endpoint="notes.formsemestre_bulletinetud",
|
||||||
version=version,
|
version=version,
|
||||||
),
|
),
|
||||||
scu.ICON_PDF,
|
scu=scu,
|
||||||
)
|
time=time,
|
||||||
)
|
version=version,
|
||||||
H.append("""</tr></table>""")
|
),
|
||||||
#
|
]
|
||||||
H.append(
|
return "\n".join(H)
|
||||||
"""</form></span></td><td class="bull_photo"><a href="%s">%s</a>
|
|
||||||
"""
|
|
||||||
% (
|
|
||||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
|
||||||
sco_photos.etud_photo_html(etud, title="fiche de " + etud["nom"]),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
H.append(
|
|
||||||
"""</td></tr>
|
|
||||||
</table>
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
return "".join(H)
|
|
||||||
|
@ -117,7 +117,7 @@ class BulletinGenerator:
|
|||||||
def get_filename(self):
|
def get_filename(self):
|
||||||
"""Build a filename to be proposed to the web client"""
|
"""Build a filename to be proposed to the web client"""
|
||||||
sem = sco_formsemestre.get_formsemestre(self.infos["formsemestre_id"])
|
sem = sco_formsemestre.get_formsemestre(self.infos["formsemestre_id"])
|
||||||
return scu.bul_filename(sem, self.infos["etud"], "pdf")
|
return scu.bul_filename_old(sem, self.infos["etud"], "pdf")
|
||||||
|
|
||||||
def generate(self, format="", stand_alone=True):
|
def generate(self, format="", stand_alone=True):
|
||||||
"""Return bulletin in specified format"""
|
"""Return bulletin in specified format"""
|
||||||
|
@ -138,7 +138,7 @@ def formsemestre_bulletinetud_published_dict(
|
|||||||
if not published:
|
if not published:
|
||||||
return d # stop !
|
return d # stop !
|
||||||
|
|
||||||
etat_inscription = etud.etat_inscription(formsemestre.id)
|
etat_inscription = etud.inscription_etat(formsemestre.id)
|
||||||
if etat_inscription != scu.INSCRIT:
|
if etat_inscription != scu.INSCRIT:
|
||||||
d.update(dict_decision_jury(etudid, formsemestre_id, with_decisions=True))
|
d.update(dict_decision_jury(etudid, formsemestre_id, with_decisions=True))
|
||||||
return d
|
return d
|
||||||
|
@ -33,8 +33,7 @@ import os
|
|||||||
import time
|
import time
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from flask import url_for, g, request
|
from flask import url_for, g
|
||||||
from flask_mail import Message
|
|
||||||
|
|
||||||
from app import email
|
from app import email
|
||||||
from app import log
|
from app import log
|
||||||
@ -46,7 +45,6 @@ from app.scodoc.sco_exceptions import ScoGenError, ScoValueError
|
|||||||
from app.scodoc import safehtml
|
from app.scodoc import safehtml
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.scolog import logdb
|
from app.scodoc.scolog import logdb
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
|
||||||
|
|
||||||
|
|
||||||
def format_etud_ident(etud):
|
def format_etud_ident(etud):
|
||||||
@ -860,7 +858,7 @@ def list_scolog(etudid):
|
|||||||
return cursor.dictfetchall()
|
return cursor.dictfetchall()
|
||||||
|
|
||||||
|
|
||||||
def fill_etuds_info(etuds, add_admission=True):
|
def fill_etuds_info(etuds: list[dict], add_admission=True):
|
||||||
"""etuds est une liste d'etudiants (mappings)
|
"""etuds est une liste d'etudiants (mappings)
|
||||||
Pour chaque etudiant, ajoute ou formatte les champs
|
Pour chaque etudiant, ajoute ou formatte les champs
|
||||||
-> informations pour fiche etudiant ou listes diverses
|
-> informations pour fiche etudiant ou listes diverses
|
||||||
@ -977,7 +975,10 @@ def etud_inscriptions_infos(etudid: int, ne="") -> dict:
|
|||||||
|
|
||||||
|
|
||||||
def descr_situation_etud(etudid: int, ne="") -> str:
|
def descr_situation_etud(etudid: int, ne="") -> str:
|
||||||
"""chaîne décrivant la situation actuelle de l'étudiant"""
|
"""Chaîne décrivant la situation actuelle de l'étudiant
|
||||||
|
XXX Obsolete, utiliser Identite.descr_situation_etud() dans
|
||||||
|
les nouveaux codes
|
||||||
|
"""
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
|
@ -351,7 +351,8 @@ def copy_portal_photo_to_fs(etud):
|
|||||||
"""Copy the photo from portal (distant website) to local fs.
|
"""Copy the photo from portal (distant website) to local fs.
|
||||||
Returns rel. path or None if copy failed, with a diagnostic message
|
Returns rel. path or None if copy failed, with a diagnostic message
|
||||||
"""
|
"""
|
||||||
sco_etud.format_etud_ident(etud)
|
if "nomprenom" not in etud:
|
||||||
|
sco_etud.format_etud_ident(etud)
|
||||||
url = photo_portal_url(etud)
|
url = photo_portal_url(etud)
|
||||||
if not url:
|
if not url:
|
||||||
return None, "%(nomprenom)s: pas de code NIP" % etud
|
return None, "%(nomprenom)s: pas de code NIP" % etud
|
||||||
|
@ -608,7 +608,7 @@ def is_valid_filename(filename):
|
|||||||
return VALID_EXP.match(filename)
|
return VALID_EXP.match(filename)
|
||||||
|
|
||||||
|
|
||||||
def bul_filename(sem, etud, format):
|
def bul_filename_old(sem: dict, etud: dict, format):
|
||||||
"""Build a filename for this bulletin"""
|
"""Build a filename for this bulletin"""
|
||||||
dt = time.strftime("%Y-%m-%d")
|
dt = time.strftime("%Y-%m-%d")
|
||||||
filename = f"bul-{sem['titre_num']}-{dt}-{etud['nom']}.{format}"
|
filename = f"bul-{sem['titre_num']}-{dt}-{etud['nom']}.{format}"
|
||||||
@ -616,6 +616,14 @@ def bul_filename(sem, etud, format):
|
|||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
|
||||||
|
def bul_filename(formsemestre, etud, format):
|
||||||
|
"""Build a filename for this bulletin"""
|
||||||
|
dt = time.strftime("%Y-%m-%d")
|
||||||
|
filename = f"bul-{formsemestre.sem.titre_num}-{dt}-{etud.nom}.{format}"
|
||||||
|
filename = make_filename(filename)
|
||||||
|
return filename
|
||||||
|
|
||||||
|
|
||||||
def flash_errors(form):
|
def flash_errors(form):
|
||||||
"""Flashes form errors (version sommaire)"""
|
"""Flashes form errors (version sommaire)"""
|
||||||
for field, errors in form.errors.items():
|
for field, errors in form.errors.items():
|
||||||
|
@ -41,7 +41,7 @@ class releveBUT extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set showData(data) {
|
set showData(data) {
|
||||||
this.showInformations(data);
|
// this.showInformations(data);
|
||||||
this.showSemestre(data);
|
this.showSemestre(data);
|
||||||
this.showSynthese(data);
|
this.showSynthese(data);
|
||||||
this.showEvaluations(data);
|
this.showEvaluations(data);
|
||||||
@ -68,13 +68,7 @@ class releveBUT extends HTMLElement {
|
|||||||
<div>
|
<div>
|
||||||
<div class="wait"></div>
|
<div class="wait"></div>
|
||||||
<main class="releve">
|
<main class="releve">
|
||||||
<!--------------------------->
|
|
||||||
<!-- Info. étudiant -->
|
|
||||||
<!--------------------------->
|
|
||||||
<section class=etudiant>
|
|
||||||
<img class=studentPic src="" alt="Photo de l'étudiant" width=100 height=120>
|
|
||||||
<div class=infoEtudiant></div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!--------------------------------------------------------------------------------------->
|
<!--------------------------------------------------------------------------------------->
|
||||||
<!-- Zone spéciale pour que les IUT puisse ajouter des infos locales sur la passerelle -->
|
<!-- Zone spéciale pour que les IUT puisse ajouter des infos locales sur la passerelle -->
|
||||||
|
58
app/templates/bul_head.html
Normal file
58
app/templates/bul_head.html
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{# -*- mode: jinja-html -*- #}
|
||||||
|
{# L'en-tête des bulletins HTML #}
|
||||||
|
{# was _formsemestre_bulletinetud_header_html #}
|
||||||
|
|
||||||
|
<table class="bull_head">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h2><a class="discretelink" href="{{
|
||||||
|
url_for(
|
||||||
|
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid,
|
||||||
|
)}}">{{etud.nomprenom}}</a></h2>
|
||||||
|
<form name="f" method="GET" action="{{request.base_url}}">
|
||||||
|
Bulletin <span class="bull_liensemestre"><a href="{{
|
||||||
|
url_for("notes.formsemestre_status",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre.id)}}
|
||||||
|
">{{formsemestre.titre_mois()}}</a></span>
|
||||||
|
<br/>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>établi le {{time.strftime("%d/%m/%Y à %Hh%M")}} (notes sur 20)</td>
|
||||||
|
<td><span class="rightjust">
|
||||||
|
<input type="hidden" name="formsemestre_id" value="{{formsemestre.id}}"></input>
|
||||||
|
<input type="hidden" name="etudid" value="{{etud.id}}"></input>
|
||||||
|
<input type="hidden" name="format" value="{{format}}"></input>
|
||||||
|
<select name="version" onchange="document.f.submit()" class="noprint">
|
||||||
|
{% for (v, e) in (
|
||||||
|
("short", "Version courte"),
|
||||||
|
("selectedevals", "Version intermédiaire"),
|
||||||
|
("long", "Version complète"),
|
||||||
|
) %}
|
||||||
|
<option value="{{v}}" {% if (v == version) %}selected{% endif %}>{{e}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="bulletin_menubar">
|
||||||
|
<div class="bulletin_menubar">{{menu_autres_operations|safe}}</div>
|
||||||
|
</td>
|
||||||
|
<td><a href="{{url_for(
|
||||||
|
'notes.formsemestre_bulletinetud',
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre.id,
|
||||||
|
etudid=etud.id,
|
||||||
|
format='pdf',
|
||||||
|
version=version,
|
||||||
|
)}}">{{scu.ICON_PDF|safe}}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td class="bull_photo"><a href="{{
|
||||||
|
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||||
|
}}">{{etud.photo_html(title="fiche de " + etud["nom"])|safe}}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
@ -6,6 +6,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
|
<h2>Totoro</h2>
|
||||||
|
|
||||||
|
|
||||||
<releve-but></releve-but>
|
<releve-but></releve-but>
|
||||||
<script src="/ScoDoc/static/js/releve-but.js"></script>
|
<script src="/ScoDoc/static/js/releve-but.js"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user