WIP: intégration bulletins
This commit is contained in:
parent
8f911234b2
commit
2220b617b8
@ -111,9 +111,10 @@ class BulletinBUT:
|
|||||||
d["modules"] = self.etud_mods_results(etud, modimpls_spo)
|
d["modules"] = self.etud_mods_results(etud, modimpls_spo)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def etud_mods_results(self, etud, modimpls) -> dict:
|
def etud_mods_results(self, etud, modimpls, version="long") -> dict:
|
||||||
"""dict synthèse résultats des modules indiqués,
|
"""dict synthèse résultats des modules indiqués,
|
||||||
avec évaluations de chacun."""
|
avec évaluations de chacun (sauf si version == "short")
|
||||||
|
"""
|
||||||
res = self.res
|
res = self.res
|
||||||
d = {}
|
d = {}
|
||||||
# etud_idx = self.etud_index[etud.id]
|
# etud_idx = self.etud_index[etud.id]
|
||||||
@ -154,12 +155,14 @@ class BulletinBUT:
|
|||||||
"evaluations": [
|
"evaluations": [
|
||||||
self.etud_eval_results(etud, e)
|
self.etud_eval_results(etud, e)
|
||||||
for e in modimpl.evaluations
|
for e in modimpl.evaluations
|
||||||
if e.visibulletin
|
if (e.visibulletin or version == "long")
|
||||||
and (
|
and (
|
||||||
modimpl_results.evaluations_etat[e.id].is_complete
|
modimpl_results.evaluations_etat[e.id].is_complete
|
||||||
or self.prefs["bul_show_all_evals"]
|
or self.prefs["bul_show_all_evals"]
|
||||||
)
|
)
|
||||||
],
|
]
|
||||||
|
if version != "short"
|
||||||
|
else [],
|
||||||
}
|
}
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@ -217,9 +220,17 @@ class BulletinBUT:
|
|||||||
return f"Bonus de {fmt_note(bonus_vect.iloc[0])}"
|
return f"Bonus de {fmt_note(bonus_vect.iloc[0])}"
|
||||||
|
|
||||||
def bulletin_etud(
|
def bulletin_etud(
|
||||||
self, etud: Identite, formsemestre: FormSemestre, force_publishing=False
|
self,
|
||||||
|
etud: Identite,
|
||||||
|
formsemestre: FormSemestre,
|
||||||
|
force_publishing=False,
|
||||||
|
version="long",
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Le bulletin de l'étudiant dans ce semestre: dict pour la version JSON / HTML.
|
"""Le bulletin de l'étudiant dans ce semestre: dict pour la version JSON / HTML.
|
||||||
|
- version:
|
||||||
|
"long", "selectedevals": toutes les infos (notes des évaluations)
|
||||||
|
"short" : ne descend pas plus bas que les modules.
|
||||||
|
|
||||||
- Si force_publishing, rempli le bulletin même si bul_hide_xml est vrai
|
- Si force_publishing, rempli le bulletin même si bul_hide_xml est vrai
|
||||||
(bulletins non publiés).
|
(bulletins non publiés).
|
||||||
"""
|
"""
|
||||||
@ -282,8 +293,10 @@ class BulletinBUT:
|
|||||||
)
|
)
|
||||||
d.update(
|
d.update(
|
||||||
{
|
{
|
||||||
"ressources": self.etud_mods_results(etud, res.ressources),
|
"ressources": self.etud_mods_results(
|
||||||
"saes": self.etud_mods_results(etud, res.saes),
|
etud, res.ressources, version=version
|
||||||
|
),
|
||||||
|
"saes": self.etud_mods_results(etud, res.saes, version=version),
|
||||||
"ues": {
|
"ues": {
|
||||||
ue.acronyme: self.etud_ue_results(etud, ue)
|
ue.acronyme: self.etud_ue_results(etud, ue)
|
||||||
for ue in res.ues
|
for ue in res.ues
|
||||||
|
@ -160,6 +160,7 @@ class Identite(db.Model):
|
|||||||
"etudid": self.id,
|
"etudid": self.id,
|
||||||
"nom": self.nom_disp(),
|
"nom": self.nom_disp(),
|
||||||
"prenom": self.prenom,
|
"prenom": self.prenom,
|
||||||
|
"nomprenom": self.nomprenom,
|
||||||
}
|
}
|
||||||
if include_urls:
|
if include_urls:
|
||||||
d["fiche_url"] = url_for(
|
d["fiche_url"] = url_for(
|
||||||
|
@ -22,6 +22,7 @@ from app.scodoc import sco_codes_parcours
|
|||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.sco_vdi import ApoEtapeVDI
|
from app.scodoc.sco_vdi import ApoEtapeVDI
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
from app.scodoc.sco_utils import MONTH_NAMES_ABBREV
|
||||||
|
|
||||||
|
|
||||||
class FormSemestre(db.Model):
|
class FormSemestre(db.Model):
|
||||||
@ -162,8 +163,8 @@ class FormSemestre(db.Model):
|
|||||||
d["periode"] = 2 # typiquement, début en février: S2, S4...
|
d["periode"] = 2 # typiquement, début en février: S2, S4...
|
||||||
d["titre_num"] = self.titre_num()
|
d["titre_num"] = self.titre_num()
|
||||||
d["titreannee"] = self.titre_annee()
|
d["titreannee"] = self.titre_annee()
|
||||||
d["mois_debut"] = f"{self.date_debut.month} {self.date_debut.year}"
|
d["mois_debut"] = self.mois_debut()
|
||||||
d["mois_fin"] = f"{self.date_fin.month} {self.date_fin.year}"
|
d["mois_fin"] = self.mois_fin()
|
||||||
d["titremois"] = "%s %s (%s - %s)" % (
|
d["titremois"] = "%s %s (%s - %s)" % (
|
||||||
d["titre_num"],
|
d["titre_num"],
|
||||||
self.modalite or "",
|
self.modalite or "",
|
||||||
@ -293,6 +294,7 @@ class FormSemestre(db.Model):
|
|||||||
"""chaîne "J. Dupond, X. Martin"
|
"""chaîne "J. Dupond, X. Martin"
|
||||||
ou "Jacques Dupond, Xavier Martin"
|
ou "Jacques Dupond, Xavier Martin"
|
||||||
"""
|
"""
|
||||||
|
# was "nomcomplet"
|
||||||
if not self.responsables:
|
if not self.responsables:
|
||||||
return ""
|
return ""
|
||||||
if abbrev_prenom:
|
if abbrev_prenom:
|
||||||
@ -304,6 +306,14 @@ class FormSemestre(db.Model):
|
|||||||
"2021 - 2022"
|
"2021 - 2022"
|
||||||
return scu.annee_scolaire_repr(self.date_debut.year, self.date_debut.month)
|
return scu.annee_scolaire_repr(self.date_debut.year, self.date_debut.month)
|
||||||
|
|
||||||
|
def mois_debut(self) -> str:
|
||||||
|
"Oct 2021"
|
||||||
|
return f"{MONTH_NAMES_ABBREV[self.date_debut.month - 1]} {self.date_debut.year}"
|
||||||
|
|
||||||
|
def mois_fin(self) -> str:
|
||||||
|
"Jul 2022"
|
||||||
|
return f"{MONTH_NAMES_ABBREV[self.date_fin.month - 1]} {self.date_debut.year}"
|
||||||
|
|
||||||
def session_id(self) -> str:
|
def session_id(self) -> str:
|
||||||
"""identifiant externe de semestre de formation
|
"""identifiant externe de semestre de formation
|
||||||
Exemple: RT-DUT-FI-S1-ANNEE
|
Exemple: RT-DUT-FI-S1-ANNEE
|
||||||
|
@ -793,13 +793,14 @@ def etud_descr_situation_semestre(
|
|||||||
def formsemestre_bulletinetud(
|
def formsemestre_bulletinetud(
|
||||||
etudid=None,
|
etudid=None,
|
||||||
formsemestre_id=None,
|
formsemestre_id=None,
|
||||||
format="html",
|
format=None,
|
||||||
version="long",
|
version="long",
|
||||||
xml_with_decisions=False,
|
xml_with_decisions=False,
|
||||||
force_publishing=False, # force publication meme si semestre non publie sur "portail"
|
force_publishing=False, # force publication meme si semestre non publie sur "portail"
|
||||||
prefer_mail_perso=False,
|
prefer_mail_perso=False,
|
||||||
):
|
):
|
||||||
"page bulletin de notes"
|
"page bulletin de notes"
|
||||||
|
format = format or "html"
|
||||||
etud: Identite = Identite.query.get_or_404(etudid)
|
etud: Identite = Identite.query.get_or_404(etudid)
|
||||||
formsemestre: FormSemestre = FormSemestre.query.get(formsemestre_id)
|
formsemestre: FormSemestre = FormSemestre.query.get(formsemestre_id)
|
||||||
if not formsemestre:
|
if not formsemestre:
|
||||||
@ -879,7 +880,7 @@ def do_formsemestre_bulletinetud(
|
|||||||
formsemestre: FormSemestre,
|
formsemestre: FormSemestre,
|
||||||
etudid: int,
|
etudid: int,
|
||||||
version="long", # short, long, selectedevals
|
version="long", # short, long, selectedevals
|
||||||
format="html",
|
format=None,
|
||||||
nohtml=False,
|
nohtml=False,
|
||||||
xml_with_decisions=False, # force décisions dans XML
|
xml_with_decisions=False, # force décisions dans XML
|
||||||
force_publishing=False, # force publication meme si semestre non publié sur "portail"
|
force_publishing=False, # force publication meme si semestre non publié sur "portail"
|
||||||
@ -890,6 +891,7 @@ def do_formsemestre_bulletinetud(
|
|||||||
où bul est str ou bytes au format demandé (html, pdf, pdfmail, pdfpart, xml, json)
|
où bul est str ou bytes au format demandé (html, pdf, pdfmail, pdfpart, xml, json)
|
||||||
et filigranne est un message à placer en "filigranne" (eg "Provisoire").
|
et filigranne est un message à placer en "filigranne" (eg "Provisoire").
|
||||||
"""
|
"""
|
||||||
|
format = format or "html"
|
||||||
if format == "xml":
|
if format == "xml":
|
||||||
bul = sco_bulletins_xml.make_xml_formsemestre_bulletinetud(
|
bul = sco_bulletins_xml.make_xml_formsemestre_bulletinetud(
|
||||||
formsemestre.id,
|
formsemestre.id,
|
||||||
@ -1258,7 +1260,7 @@ def make_menu_autres_operations(
|
|||||||
"enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
|
"enabled": sco_permissions_check.can_validate_sem(formsemestre.id),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Editer PV jury",
|
"title": "Éditer PV jury",
|
||||||
"endpoint": "notes.formsemestre_pvjury_pdf",
|
"endpoint": "notes.formsemestre_pvjury_pdf",
|
||||||
"args": {
|
"args": {
|
||||||
"formsemestre_id": formsemestre.id,
|
"formsemestre_id": formsemestre.id,
|
||||||
|
@ -297,7 +297,11 @@ def register_bulletin_class(klass):
|
|||||||
|
|
||||||
|
|
||||||
def bulletin_class_descriptions():
|
def bulletin_class_descriptions():
|
||||||
return [x.description for x in BULLETIN_CLASSES.values()]
|
return [
|
||||||
|
BULLETIN_CLASSES[class_name].description
|
||||||
|
for class_name in BULLETIN_CLASSES
|
||||||
|
if BULLETIN_CLASSES[class_name].list_in_menu
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def bulletin_class_names() -> list[str]:
|
def bulletin_class_names() -> list[str]:
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask import g
|
from flask import g
|
||||||
from flask import request
|
from flask import 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 app import log
|
from app import log
|
||||||
@ -411,7 +411,7 @@ def formsemestre_status_menubar(sem):
|
|||||||
"enabled": sco_permissions_check.can_validate_sem(formsemestre_id),
|
"enabled": sco_permissions_check.can_validate_sem(formsemestre_id),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Editer les PV et archiver les résultats",
|
"title": "Éditer les PV et archiver les résultats",
|
||||||
"endpoint": "notes.formsemestre_archive",
|
"endpoint": "notes.formsemestre_archive",
|
||||||
"args": {"formsemestre_id": formsemestre_id},
|
"args": {"formsemestre_id": formsemestre_id},
|
||||||
"enabled": sco_permissions_check.can_edit_pv(formsemestre_id),
|
"enabled": sco_permissions_check.can_edit_pv(formsemestre_id),
|
||||||
@ -445,6 +445,7 @@ def retreive_formsemestre_from_request() -> int:
|
|||||||
"""Cherche si on a de quoi déduire le semestre affiché à partir des
|
"""Cherche si on a de quoi déduire le semestre affiché à partir des
|
||||||
arguments de la requête:
|
arguments de la requête:
|
||||||
formsemestre_id ou moduleimpl ou evaluation ou group_id ou partition_id
|
formsemestre_id ou moduleimpl ou evaluation ou group_id ou partition_id
|
||||||
|
Returns None si pas défini.
|
||||||
"""
|
"""
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
args = request.args
|
args = request.args
|
||||||
@ -505,34 +506,17 @@ def formsemestre_page_title():
|
|||||||
return ""
|
return ""
|
||||||
try:
|
try:
|
||||||
formsemestre_id = int(formsemestre_id)
|
formsemestre_id = int(formsemestre_id)
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id).copy()
|
formsemestre = FormSemestre.query.get(formsemestre_id)
|
||||||
except:
|
except:
|
||||||
log("can't find formsemestre_id %s" % formsemestre_id)
|
log("can't find formsemestre_id %s" % formsemestre_id)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
fill_formsemestre(sem)
|
h = render_template(
|
||||||
|
"formsemestre_page_title.html",
|
||||||
h = f"""<div class="formsemestre_page_title">
|
formsemestre=formsemestre,
|
||||||
<div class="infos">
|
scu=scu,
|
||||||
<span class="semtitle"><a class="stdlink" title="{sem['session_id']}"
|
sem_menu_bar=formsemestre_status_menubar(formsemestre.to_dict()),
|
||||||
href="{url_for('notes.formsemestre_status',
|
)
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=sem['formsemestre_id'])}"
|
|
||||||
>{sem['titre']}</a><a
|
|
||||||
title="{sem['etape_apo_str']}">{sem['num_sem']}</a>{sem['modalitestr']}</span><span
|
|
||||||
class="dates"><a
|
|
||||||
title="du {sem['date_debut']} au {sem['date_fin']} "
|
|
||||||
>{sem['mois_debut']} - {sem['mois_fin']}</a></span><span
|
|
||||||
class="resp"><a title="{sem['nomcomplet']}">{sem['resp']}</a></span><span
|
|
||||||
class="nbinscrits"><a class="discretelink"
|
|
||||||
href="{url_for("scolar.groups_view",
|
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=sem['formsemestre_id'])}"
|
|
||||||
>{sem['nbinscrits']} inscrits</a></span><span
|
|
||||||
class="lock">{sem['locklink']}</span><span
|
|
||||||
class="eye">{sem['eyelink']}</span>
|
|
||||||
</div>
|
|
||||||
{formsemestre_status_menubar(sem)}
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
|
|
||||||
return h
|
return h
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ def etud_photo_is_local(etud: dict, size="small"):
|
|||||||
return photo_pathname(etud["photo_filename"], size=size)
|
return photo_pathname(etud["photo_filename"], size=size)
|
||||||
|
|
||||||
|
|
||||||
def etud_photo_html(etud=None, etudid=None, title=None, size="small"):
|
def etud_photo_html(etud: dict = None, etudid=None, title=None, size="small"):
|
||||||
"""HTML img tag for the photo, either in small size (h90)
|
"""HTML img tag for the photo, either in small size (h90)
|
||||||
or original size (size=="orig")
|
or original size (size=="orig")
|
||||||
"""
|
"""
|
||||||
|
@ -619,7 +619,7 @@ def bul_filename_old(sem: dict, etud: dict, format):
|
|||||||
def bul_filename(formsemestre, etud, format):
|
def bul_filename(formsemestre, etud, 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-{formsemestre.sem.titre_num}-{dt}-{etud.nom}.{format}"
|
filename = f"bul-{formsemestre.titre_num()}-{dt}-{etud.nom}.{format}"
|
||||||
filename = make_filename(filename)
|
filename = make_filename(filename)
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
@ -14,16 +14,25 @@
|
|||||||
}
|
}
|
||||||
main{
|
main{
|
||||||
--couleurPrincipale: rgb(240,250,255);
|
--couleurPrincipale: rgb(240,250,255);
|
||||||
--couleurFondTitresUE: rgb(206,255,235);
|
--couleurFondTitresUE: #b6ebff;
|
||||||
--couleurFondTitresRes: rgb(125, 170, 255);
|
--couleurFondTitresRes: #f8c844;
|
||||||
--couleurFondTitresSAE: rgb(211, 255, 255);
|
--couleurFondTitresSAE: #c6ffab;
|
||||||
--couleurSecondaire: #fec;
|
--couleurSecondaire: #fec;
|
||||||
--couleurIntense: #c09;
|
--couleurIntense: rgb(4, 16, 159);;
|
||||||
--couleurSurlignage: rgba(232, 255, 132, 0.47);
|
--couleurSurlignage: rgba(255, 253, 110, 0.49);
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.releve a, .releve a:visited {
|
||||||
|
color: navy;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.releve a:hover {
|
||||||
|
color: red;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
.ready .wait{display: none;}
|
.ready .wait{display: none;}
|
||||||
.ready main{display: block;}
|
.ready main{display: block;}
|
||||||
h2{
|
h2{
|
||||||
@ -152,12 +161,14 @@ section>div:nth-child(1){
|
|||||||
column-gap: 4px;
|
column-gap: 4px;
|
||||||
flex: none;
|
flex: none;
|
||||||
}
|
}
|
||||||
.infoSemestre>div:nth-child(1){
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
.infoSemestre>div>div:nth-child(even){
|
.infoSemestre>div>div:nth-child(even){
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
.photo {
|
||||||
|
border: none;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
.rang{
|
.rang{
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
@ -213,7 +224,6 @@ section>div:nth-child(1){
|
|||||||
scroll-margin-top: 60px;
|
scroll-margin-top: 60px;
|
||||||
}
|
}
|
||||||
.module, .ue {
|
.module, .ue {
|
||||||
background: var(--couleurSecondaire);
|
|
||||||
color: #000;
|
color: #000;
|
||||||
padding: 4px 32px;
|
padding: 4px 32px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -225,6 +235,15 @@ section>div:nth-child(1){
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
.ue {
|
||||||
|
background: var(--couleurFondTitresRes);
|
||||||
|
}
|
||||||
|
.module {
|
||||||
|
background: var(--couleurFondTitresRes);
|
||||||
|
}
|
||||||
|
.module h3 {
|
||||||
|
background: var(--couleurFondTitresRes);
|
||||||
|
}
|
||||||
.module::before, .ue::before {
|
.module::before, .ue::before {
|
||||||
content:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='26px' height='26px' fill='white'><path d='M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z' /></svg>");
|
content:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='26px' height='26px' fill='white'><path d='M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z' /></svg>");
|
||||||
width: 26px;
|
width: 26px;
|
||||||
|
@ -1963,7 +1963,9 @@ table.notes_recapcomplet a:hover {
|
|||||||
div.notes_bulletin {
|
div.notes_bulletin {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
div.bulletin_menubar {
|
||||||
|
margin-right: 2em;
|
||||||
|
}
|
||||||
table.notes_bulletin {
|
table.notes_bulletin {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
border: 2px solid rgb(100,100,240);
|
border: 2px solid rgb(100,100,240);
|
||||||
|
@ -79,8 +79,8 @@ class releveBUT extends HTMLElement {
|
|||||||
<!-- Semestre -->
|
<!-- Semestre -->
|
||||||
<!--------------------------->
|
<!--------------------------->
|
||||||
<section>
|
<section>
|
||||||
<h2>Semestre </h2>
|
<h2 id="identite_etudiant"></h2>
|
||||||
<div class=flex>
|
<div>
|
||||||
<div class=infoSemestre></div>
|
<div class=infoSemestre></div>
|
||||||
<div>
|
<div>
|
||||||
<div class=decision></div>
|
<div class=decision></div>
|
||||||
@ -97,7 +97,7 @@ class releveBUT extends HTMLElement {
|
|||||||
<section>
|
<section>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Synthèse</h2>
|
<h2>Unités d'enseignement</h2>
|
||||||
<em>La moyenne des ressources dans une UE dépend des poids donnés aux évaluations.</em>
|
<em>La moyenne des ressources dans une UE dépend des poids donnés aux évaluations.</em>
|
||||||
</div>
|
</div>
|
||||||
<div class=CTA_Liste>
|
<div class=CTA_Liste>
|
||||||
@ -126,7 +126,7 @@ class releveBUT extends HTMLElement {
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div>
|
<div>
|
||||||
<h2>SAÉ</h2>
|
<h2>Situations d'apprentissage et d'évaluation (SAÉ)</h2>
|
||||||
<div class=CTA_Liste>
|
<div class=CTA_Liste>
|
||||||
Liste <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
Liste <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path d="M18 15l-6-6-6 6" />
|
<path d="M18 15l-6-6-6 6" />
|
||||||
@ -192,7 +192,8 @@ class releveBUT extends HTMLElement {
|
|||||||
/* Information sur le semestre */
|
/* Information sur le semestre */
|
||||||
/*******************************/
|
/*******************************/
|
||||||
showSemestre(data) {
|
showSemestre(data) {
|
||||||
this.shadow.querySelector("h2").innerHTML += data.semestre.numero;
|
|
||||||
|
this.shadow.querySelector("#identite_etudiant").innerHTML = ` ${data.etudiant.nomprenom} `;
|
||||||
this.shadow.querySelector(".dateInscription").innerHTML += this.ISOToDate(data.semestre.inscription);
|
this.shadow.querySelector(".dateInscription").innerHTML += this.ISOToDate(data.semestre.inscription);
|
||||||
let output = `
|
let output = `
|
||||||
<div>
|
<div>
|
||||||
@ -206,7 +207,9 @@ class releveBUT extends HTMLElement {
|
|||||||
<div class=enteteSemestre>Absences</div>
|
<div class=enteteSemestre>Absences</div>
|
||||||
<div class=enteteSemestre>N.J. ${data.semestre.absences?.injustifie ?? "-"}</div>
|
<div class=enteteSemestre>N.J. ${data.semestre.absences?.injustifie ?? "-"}</div>
|
||||||
<div style="grid-column: 2">Total ${data.semestre.absences?.total ?? "-"}</div>
|
<div style="grid-column: 2">Total ${data.semestre.absences?.total ?? "-"}</div>
|
||||||
</div>`;
|
</div>
|
||||||
|
<a class=photo href="${data.etudiant.fiche_url}"><img src="${data.etudiant.photo_url || "default_Student.svg"}" alt="photo de l'étudiant" title="fiche de l'étudiant" height="120" border="0"></a>
|
||||||
|
`;
|
||||||
/*${data.semestre.groupes.map(groupe => {
|
/*${data.semestre.groupes.map(groupe => {
|
||||||
return `
|
return `
|
||||||
<div>
|
<div>
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
<table class="bull_head">
|
<table class="bull_head">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
{% if not is_apc %}
|
||||||
<h2><a class="discretelink" href="{{
|
<h2><a class="discretelink" href="{{
|
||||||
url_for(
|
url_for(
|
||||||
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid,
|
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid,
|
||||||
)}}">{{etud.nomprenom}}</a></h2>
|
)}}">{{etud.nomprenom}}</a></h2>
|
||||||
|
{% endif %}
|
||||||
<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="{{
|
||||||
url_for("notes.formsemestre_status",
|
url_for("notes.formsemestre_status",
|
||||||
@ -50,9 +52,11 @@
|
|||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
|
{% if not is_apc %}
|
||||||
<td class="bull_photo"><a href="{{
|
<td class="bull_photo"><a href="{{
|
||||||
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||||
}}">{{etud.photo_html(title="fiche de " + etud["nom"])|safe}}</a>
|
}}">{{etud.photo_html(title="fiche de " + etud["nom"])|safe}}</a>
|
||||||
</td>
|
</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
<h2>Totoro</h2>
|
|
||||||
|
|
||||||
|
{% include 'bul_head.html' %}
|
||||||
|
|
||||||
<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>
|
||||||
|
50
app/templates/formsemestre_page_title.html
Normal file
50
app/templates/formsemestre_page_title.html
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{# -*- mode: jinja-html -*- #}
|
||||||
|
{# Element HTML decrivant un semestre (barre de menu et infos) #}
|
||||||
|
{# was formsemestre_page_title #}
|
||||||
|
|
||||||
|
<div class="formsemestre_page_title">
|
||||||
|
<div class="infos">
|
||||||
|
<span class="semtitle"><a class="stdlink"
|
||||||
|
title="{{formsemestre.session_id}}"
|
||||||
|
href="{{url_for('notes.formsemestre_status',
|
||||||
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)}}"
|
||||||
|
>TATO {{formsemestre.titre}}</a>
|
||||||
|
{%- if formsemestre.semestre_id != -1 -%}
|
||||||
|
<a
|
||||||
|
title="{{formsemestre.etapes_apo_str()
|
||||||
|
}}">, {{
|
||||||
|
formsemestre.formation.get_parcours().SESSION_NAME}}
|
||||||
|
{{formsemestre.semestre_id}}</a>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if formsemestre.modalite %} en {{formsemestre.modalite}}
|
||||||
|
{%- endif %}</span><span
|
||||||
|
class="dates"><a
|
||||||
|
title="du {{formsemestre.date_debut.strftime('%d/%m/%Y')}}
|
||||||
|
au {{formsemestre.date_fin.strftime('%d/%m/%Y')}} "
|
||||||
|
>{{formsemestre.mois_debut()}} - {{formsemestre.mois_fin()}}</a></span><span
|
||||||
|
class="resp"><a title="{{formsemestre.responsables_str(abbrev_prenom=False)}}">{{formsemestre.responsables_str()}}</a></span><span
|
||||||
|
class="nbinscrits"><a class="discretelink"
|
||||||
|
href="{{url_for('scolar.groups_view',
|
||||||
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)
|
||||||
|
}}"
|
||||||
|
>{{formsemestre.etuds_inscriptions|length}} inscrits</a></span><span
|
||||||
|
class="lock">
|
||||||
|
{%-if formsemestre.etat -%}
|
||||||
|
<a href="{{ url_for( 'notes.formsemestre_change_lock',
|
||||||
|
scodoc_dept=scodoc_dept, formsemestre_id=formsemestre.id )}}">{{
|
||||||
|
scu.icontag("lock_img", border="0", title="Semestre verrouillé")|safe
|
||||||
|
}}</a>
|
||||||
|
{%- endif -%}
|
||||||
|
</span><span class="eye"><a href="{{
|
||||||
|
url_for('notes.formsemestre_change_publication_bul',
|
||||||
|
scodoc_dept=scodoc_dept, formsemestre_id=formsemestre.id )
|
||||||
|
}}">{%-
|
||||||
|
if formsemestre.bul_hide_xml -%}}
|
||||||
|
{{scu.icontag("hide_img", border="0", title="Bulletins NON publiés")|safe}}
|
||||||
|
{%- else -%}
|
||||||
|
{{scu.icontag("eye_img", border="0", title="Bulletins publiés")|safe}}
|
||||||
|
{%- endif -%}
|
||||||
|
</a></span>
|
||||||
|
</div>
|
||||||
|
{{sem_menu_bar|safe}}
|
||||||
|
</div>
|
@ -50,27 +50,29 @@ def close_dept_db_connection(arg):
|
|||||||
class ScoData:
|
class ScoData:
|
||||||
"""Classe utilisée pour passer des valeurs aux vues (templates)"""
|
"""Classe utilisée pour passer des valeurs aux vues (templates)"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, etud=None, formsemestre=None):
|
||||||
# Champs utilisés par toutes les pages ScoDoc (sidebar, en-tête)
|
# Champs utilisés par toutes les pages ScoDoc (sidebar, en-tête)
|
||||||
self.Permission = Permission
|
self.Permission = Permission
|
||||||
self.scu = scu
|
self.scu = scu
|
||||||
self.SCOVERSION = sco_version.SCOVERSION
|
self.SCOVERSION = sco_version.SCOVERSION
|
||||||
# -- Informations étudiant courant, si sélectionné:
|
# -- Informations étudiant courant, si sélectionné:
|
||||||
etudid = g.get("etudid", None)
|
if etud is None:
|
||||||
if not etudid:
|
etudid = g.get("etudid", None)
|
||||||
if request.method == "GET":
|
if etudid is None:
|
||||||
etudid = request.args.get("etudid", None)
|
if request.method == "GET":
|
||||||
elif request.method == "POST":
|
etudid = request.args.get("etudid", None)
|
||||||
etudid = request.form.get("etudid", None)
|
elif request.method == "POST":
|
||||||
|
etudid = request.form.get("etudid", None)
|
||||||
if etudid:
|
if etudid is not None:
|
||||||
|
etud = Identite.query.get_or_404(etudid)
|
||||||
|
self.etud = etud
|
||||||
|
if etud is not None:
|
||||||
# Infos sur l'étudiant courant
|
# Infos sur l'étudiant courant
|
||||||
self.etud = Identite.query.get_or_404(etudid)
|
|
||||||
ins = self.etud.inscription_courante()
|
ins = self.etud.inscription_courante()
|
||||||
if ins:
|
if ins:
|
||||||
self.etud_cur_sem = ins.formsemestre
|
self.etud_cur_sem = ins.formsemestre
|
||||||
self.nbabs, self.nbabsjust = sco_abs.get_abs_count_in_interval(
|
self.nbabs, self.nbabsjust = sco_abs.get_abs_count_in_interval(
|
||||||
etudid,
|
etud.id,
|
||||||
self.etud_cur_sem.date_debut.isoformat(),
|
self.etud_cur_sem.date_debut.isoformat(),
|
||||||
self.etud_cur_sem.date_fin.isoformat(),
|
self.etud_cur_sem.date_fin.isoformat(),
|
||||||
)
|
)
|
||||||
@ -80,17 +82,22 @@ class ScoData:
|
|||||||
else:
|
else:
|
||||||
self.etud = None
|
self.etud = None
|
||||||
# --- Informations sur semestre courant, si sélectionné
|
# --- Informations sur semestre courant, si sélectionné
|
||||||
formsemestre_id = sco_formsemestre_status.retreive_formsemestre_from_request()
|
if formsemestre is None:
|
||||||
if formsemestre_id is None:
|
formsemestre_id = (
|
||||||
|
sco_formsemestre_status.retreive_formsemestre_from_request()
|
||||||
|
)
|
||||||
|
if formsemestre_id is not None:
|
||||||
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
|
if formsemestre is None:
|
||||||
self.sem = None
|
self.sem = None
|
||||||
self.sem_menu_bar = None
|
self.sem_menu_bar = None
|
||||||
else:
|
else:
|
||||||
self.sem = FormSemestre.query.get_or_404(formsemestre_id)
|
self.sem = formsemestre
|
||||||
self.sem_menu_bar = sco_formsemestre_status.formsemestre_status_menubar(
|
self.sem_menu_bar = sco_formsemestre_status.formsemestre_status_menubar(
|
||||||
self.sem.to_dict()
|
self.sem.to_dict()
|
||||||
)
|
)
|
||||||
# --- Préférences
|
# --- Préférences
|
||||||
self.prefs = sco_preferences.SemPreferences(formsemestre_id)
|
self.prefs = sco_preferences.SemPreferences(formsemestre.id)
|
||||||
|
|
||||||
|
|
||||||
from app.views import scodoc, notes, scolar, absences, users, pn_modules, refcomp
|
from app.views import scodoc, notes, scolar, absences, users, pn_modules, refcomp
|
||||||
|
@ -32,6 +32,7 @@ Emmanuel Viennet, 2021
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
import time
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
@ -276,7 +277,7 @@ sco_publish(
|
|||||||
def formsemestre_bulletinetud(
|
def formsemestre_bulletinetud(
|
||||||
etudid=None,
|
etudid=None,
|
||||||
formsemestre_id=None,
|
formsemestre_id=None,
|
||||||
format="html",
|
format=None,
|
||||||
version="long",
|
version="long",
|
||||||
xml_with_decisions=False,
|
xml_with_decisions=False,
|
||||||
force_publishing=False,
|
force_publishing=False,
|
||||||
@ -284,6 +285,7 @@ def formsemestre_bulletinetud(
|
|||||||
code_nip=None,
|
code_nip=None,
|
||||||
code_ine=None,
|
code_ine=None,
|
||||||
):
|
):
|
||||||
|
format = format or "html"
|
||||||
if not formsemestre_id:
|
if not formsemestre_id:
|
||||||
flask.abort(404, "argument manquant: formsemestre_id")
|
flask.abort(404, "argument manquant: formsemestre_id")
|
||||||
if not isinstance(formsemestre_id, int):
|
if not isinstance(formsemestre_id, int):
|
||||||
@ -311,12 +313,16 @@ def formsemestre_bulletinetud(
|
|||||||
if format == "json":
|
if format == "json":
|
||||||
r = bulletin_but.BulletinBUT(formsemestre)
|
r = bulletin_but.BulletinBUT(formsemestre)
|
||||||
return jsonify(
|
return jsonify(
|
||||||
r.bulletin_etud(etud, formsemestre, force_publishing=force_publishing)
|
r.bulletin_etud(
|
||||||
|
etud,
|
||||||
|
formsemestre,
|
||||||
|
force_publishing=force_publishing,
|
||||||
|
version=version,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
elif format == "html":
|
elif format == "html":
|
||||||
return render_template(
|
return render_template(
|
||||||
"but/bulletin.html",
|
"but/bulletin.html",
|
||||||
title=f"Bul. {etud.nom} - BUT",
|
|
||||||
bul_url=url_for(
|
bul_url=url_for(
|
||||||
"notes.formsemestre_bulletinetud",
|
"notes.formsemestre_bulletinetud",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
@ -324,8 +330,19 @@ def formsemestre_bulletinetud(
|
|||||||
etudid=etudid,
|
etudid=etudid,
|
||||||
format="json",
|
format="json",
|
||||||
force_publishing=1, # pour ScoDoc lui même
|
force_publishing=1, # pour ScoDoc lui même
|
||||||
|
version=version,
|
||||||
),
|
),
|
||||||
sco=ScoData(),
|
etud=etud,
|
||||||
|
formsemestre=formsemestre,
|
||||||
|
is_apc=formsemestre.formation.is_apc(),
|
||||||
|
menu_autres_operations=sco_bulletins.make_menu_autres_operations(
|
||||||
|
formsemestre, etud, "notes.formsemestre_bulletinetud", version
|
||||||
|
),
|
||||||
|
sco=ScoData(etud=etud),
|
||||||
|
scu=scu,
|
||||||
|
time=time,
|
||||||
|
title=f"Bul. {etud.nom} - BUT",
|
||||||
|
version=version,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not (etudid or code_nip or code_ine):
|
if not (etudid or code_nip or code_ine):
|
||||||
|
Loading…
Reference in New Issue
Block a user