Diverses améliorations pour faciliter la config BUT. Voir #862
This commit is contained in:
parent
56aa5fbba3
commit
fae9fbdd09
@ -119,6 +119,12 @@ def _build_bulletin_but_infos(
|
||||
refcomp = formsemestre.formation.referentiel_competence
|
||||
if refcomp is None:
|
||||
raise ScoNoReferentielCompetences(formation=formsemestre.formation)
|
||||
|
||||
warn_html = cursus_but.formsemestre_warning_apc_setup(
|
||||
formsemestre, bulletins_sem.res
|
||||
)
|
||||
if warn_html:
|
||||
raise ScoValueError("<b>Formation mal configurée pour le BUT</b>" + warn_html)
|
||||
ue_validation_by_niveau = validations_view.get_ue_validation_by_niveau(
|
||||
refcomp, etud
|
||||
)
|
||||
|
@ -23,29 +23,21 @@ from app.comp.res_but import ResultatsSemestreBUT
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
|
||||
from app.models.but_refcomp import (
|
||||
ApcAnneeParcours,
|
||||
ApcCompetence,
|
||||
ApcNiveau,
|
||||
ApcParcours,
|
||||
ApcParcoursNiveauCompetence,
|
||||
ApcReferentielCompetences,
|
||||
)
|
||||
from app.models import Scolog, ScolarAutorisationInscription
|
||||
from app.models.but_validations import (
|
||||
ApcValidationAnnee,
|
||||
ApcValidationRCUE,
|
||||
)
|
||||
from app.models.ues import UEParcours
|
||||
from app.models.but_validations import ApcValidationRCUE
|
||||
from app.models.etudiants import Identite
|
||||
from app.models.formations import Formation
|
||||
from app.models.formsemestre import FormSemestre, FormSemestreInscription
|
||||
from app.models.formsemestre import FormSemestre
|
||||
from app.models.ues import UniteEns
|
||||
from app.models.validations import ScolarFormSemestreValidation
|
||||
from app.scodoc import codes_cursus as sco_codes
|
||||
from app.scodoc.codes_cursus import code_ue_validant, CODES_UE_VALIDES, UE_STANDARD
|
||||
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc.sco_exceptions import ScoNoReferentielCompetences, ScoValueError
|
||||
|
||||
from app.scodoc import sco_cursus_dut
|
||||
|
||||
|
||||
@ -440,11 +432,16 @@ def formsemestre_warning_apc_setup(
|
||||
"""
|
||||
if not formsemestre.formation.is_apc():
|
||||
return ""
|
||||
url_formation = url_for(
|
||||
"notes.ue_table",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=formsemestre.formation.id,
|
||||
semestre_idx=formsemestre.semestre_id,
|
||||
)
|
||||
if formsemestre.formation.referentiel_competence is None:
|
||||
return f"""<div class="formsemestre_status_warning">
|
||||
La <a class="stdlink" href="{
|
||||
url_for("notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formsemestre.formation.id)
|
||||
}">formation n'est pas associée à un référentiel de compétence.</a>
|
||||
La <a class="stdlink" href="{url_formation}">formation
|
||||
n'est pas associée à un référentiel de compétence.</a>
|
||||
</div>
|
||||
"""
|
||||
H = []
|
||||
@ -462,7 +459,9 @@ def formsemestre_warning_apc_setup(
|
||||
)
|
||||
if nb_ues_sans_parcours != nb_ues_tot:
|
||||
H.append(
|
||||
f"""Le semestre n'est associé à aucun parcours, mais les UEs de la formation ont des parcours"""
|
||||
"""Le semestre n'est associé à aucun parcours,
|
||||
mais les UEs de la formation ont des parcours
|
||||
"""
|
||||
)
|
||||
# Vérifie les niveaux de chaque parcours
|
||||
for parcour in formsemestre.parcours or [None]:
|
||||
@ -489,7 +488,8 @@ def formsemestre_warning_apc_setup(
|
||||
if not H:
|
||||
return ""
|
||||
return f"""<div class="formsemestre_status_warning">
|
||||
Problème dans la configuration de la formation:
|
||||
Problème dans la
|
||||
<a class="stdlink" href="{url_formation}">configuration de la formation</a>:
|
||||
<ul>
|
||||
<li>{ '</li><li>'.join(H) }</li>
|
||||
</ul>
|
||||
@ -502,6 +502,76 @@ def formsemestre_warning_apc_setup(
|
||||
"""
|
||||
|
||||
|
||||
def formation_semestre_niveaux_warning(formation: Formation, semestre_idx: int) -> str:
|
||||
"""Vérifie que tous les niveaux de compétences de cette année de formation
|
||||
ont bien des UEs.
|
||||
Afin de ne pas générer trop de messages, on ne considère que les parcours
|
||||
du référentiel de compétences pour lesquels au moins une UE a été associée.
|
||||
|
||||
Renvoie fragment de html
|
||||
"""
|
||||
annee = (semestre_idx - 1) // 2 + 1 # année BUT
|
||||
ref_comp: ApcReferentielCompetences = formation.referentiel_competence
|
||||
niveaux_sans_ue_by_parcour = {} # { parcour.code : [ ue ... ] }
|
||||
parcours_ids = {
|
||||
uep.parcours_id
|
||||
for uep in UEParcours.query.join(UniteEns).filter_by(
|
||||
formation_id=formation.id, type=UE_STANDARD
|
||||
)
|
||||
}
|
||||
for parcour in ref_comp.parcours:
|
||||
if parcour.id not in parcours_ids:
|
||||
continue # saute parcours associés à aucune UE (tous semestres)
|
||||
niveaux_sans_ue = []
|
||||
niveaux = ApcNiveau.niveaux_annee_de_parcours(parcour, annee, ref_comp)
|
||||
# print(f"\n# Parcours {parcour.code} : {len(niveaux)} niveaux")
|
||||
for niveau in niveaux:
|
||||
ues = [ue for ue in formation.ues if ue.niveau_competence_id == niveau.id]
|
||||
if not ues:
|
||||
niveaux_sans_ue.append(niveau)
|
||||
# print( niveau.competence.titre + " " + str(niveau.ordre) + "\t" + str(ue) )
|
||||
if niveaux_sans_ue:
|
||||
niveaux_sans_ue_by_parcour[parcour.code] = niveaux_sans_ue
|
||||
#
|
||||
H = []
|
||||
for parcour_code, niveaux in niveaux_sans_ue_by_parcour.items():
|
||||
H.append(
|
||||
f"""<li>Parcours {parcour_code} : {
|
||||
len(niveaux)} niveaux sans UEs
|
||||
<span>
|
||||
{ ', '.join( f'{niveau.competence.titre} {niveau.ordre}'
|
||||
for niveau in niveaux
|
||||
)
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
"""
|
||||
)
|
||||
# Combien de compétences de tronc commun ?
|
||||
_, niveaux_by_parcours = ref_comp.get_niveaux_by_parcours(annee)
|
||||
nb_niveaux_tc = len(niveaux_by_parcours["TC"])
|
||||
nb_ues_tc = len(
|
||||
formation.query_ues_parcour(None)
|
||||
.filter(UniteEns.semestre_idx == semestre_idx)
|
||||
.all()
|
||||
)
|
||||
if nb_niveaux_tc != nb_ues_tc:
|
||||
H.append(
|
||||
f"""<li>{nb_niveaux_tc} niveaux de compétences de tronc commun,
|
||||
mais {nb_ues_tc} UEs de tronc commun !</li>"""
|
||||
)
|
||||
|
||||
if H:
|
||||
return f"""<div class="formation_semestre_niveaux_warning">
|
||||
<div>Problèmes détectés à corriger :</div>
|
||||
<ul>
|
||||
{"".join(H)}
|
||||
</ul>
|
||||
</div>
|
||||
"""
|
||||
return "" # no problem detected
|
||||
|
||||
|
||||
def ue_associee_au_niveau_du_parcours(
|
||||
ues_possibles: list[UniteEns], niveau: ApcNiveau, sem_name: str = "S"
|
||||
) -> UniteEns:
|
||||
|
@ -50,14 +50,11 @@ import traceback
|
||||
|
||||
import reportlab
|
||||
from reportlab.platypus import (
|
||||
SimpleDocTemplate,
|
||||
DocIf,
|
||||
Paragraph,
|
||||
Spacer,
|
||||
Frame,
|
||||
PageBreak,
|
||||
)
|
||||
from reportlab.platypus import Table, TableStyle, Image, KeepInFrame
|
||||
from reportlab.platypus import Table, KeepInFrame
|
||||
|
||||
from flask import request
|
||||
from flask_login import current_user
|
||||
@ -213,26 +210,26 @@ class BulletinGenerator:
|
||||
story.append(PageBreak()) # insert page break at end
|
||||
|
||||
return story
|
||||
else:
|
||||
# Generation du document PDF
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
report = io.BytesIO() # in-memory document, no disk file
|
||||
document = sco_pdf.BaseDocTemplate(report)
|
||||
document.addPageTemplates(
|
||||
sco_pdf.ScoDocPageTemplate(
|
||||
document,
|
||||
author="%s %s (E. Viennet) [%s]"
|
||||
% (sco_version.SCONAME, sco_version.SCOVERSION, self.description),
|
||||
title=f"""Bulletin {sem["titremois"]} de {etat_civil}""",
|
||||
subject="Bulletin de note",
|
||||
margins=self.margins,
|
||||
server_name=self.server_name,
|
||||
filigranne=self.filigranne,
|
||||
preferences=sco_preferences.SemPreferences(formsemestre_id),
|
||||
)
|
||||
|
||||
# Generation du document PDF
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
report = io.BytesIO() # in-memory document, no disk file
|
||||
document = sco_pdf.BaseDocTemplate(report)
|
||||
document.addPageTemplates(
|
||||
sco_pdf.ScoDocPageTemplate(
|
||||
document,
|
||||
author=f"""{sco_version.SCONAME} {
|
||||
sco_version.SCOVERSION} (E. Viennet) [{self.description}]""",
|
||||
title=f"""Bulletin {sem["titremois"]} de {etat_civil}""",
|
||||
subject="Bulletin de note",
|
||||
margins=self.margins,
|
||||
server_name=self.server_name,
|
||||
filigranne=self.filigranne,
|
||||
preferences=sco_preferences.SemPreferences(formsemestre_id),
|
||||
)
|
||||
document.build(story)
|
||||
data = report.getvalue()
|
||||
)
|
||||
document.build(story)
|
||||
data = report.getvalue()
|
||||
return data
|
||||
|
||||
def buildTableObject(self, P, pdfTableStyle, colWidths):
|
||||
|
@ -28,7 +28,7 @@
|
||||
from flask.templating import render_template
|
||||
|
||||
from app import db
|
||||
from app.but import apc_edit_ue
|
||||
from app.but import cursus_but
|
||||
from app.models import UniteEns, Matiere, Module, FormSemestre, ModuleImpl
|
||||
from app.models.validations import ScolarFormSemestreValidation
|
||||
from app.scodoc import codes_cursus
|
||||
@ -101,18 +101,26 @@ def html_edit_formation_apc(
|
||||
),
|
||||
}
|
||||
|
||||
html_ue_warning = {
|
||||
semestre_idx: cursus_but.formation_semestre_niveaux_warning(
|
||||
formation, semestre_idx
|
||||
)
|
||||
for semestre_idx in semestre_ids
|
||||
}
|
||||
|
||||
H = [
|
||||
render_template(
|
||||
"pn/form_ues.j2",
|
||||
formation=formation,
|
||||
semestre_ids=semestre_ids,
|
||||
editable=editable,
|
||||
tag_editable=tag_editable,
|
||||
icons=icons,
|
||||
ues_by_sem=ues_by_sem,
|
||||
ects_by_sem=ects_by_sem,
|
||||
scu=scu,
|
||||
codes_cursus=codes_cursus,
|
||||
ects_by_sem=ects_by_sem,
|
||||
editable=editable,
|
||||
formation=formation,
|
||||
html_ue_warning=html_ue_warning,
|
||||
icons=icons,
|
||||
scu=scu,
|
||||
semestre_ids=semestre_ids,
|
||||
tag_editable=tag_editable,
|
||||
ues_by_sem=ues_by_sem,
|
||||
),
|
||||
]
|
||||
for semestre_idx in semestre_ids:
|
||||
|
@ -892,7 +892,9 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
||||
<form>
|
||||
<input type="checkbox" class="sco_tag_checkbox"
|
||||
{'checked' if show_tags else ''}
|
||||
> Montrer les tags des modules voire en ajouter <i>(ceux correspondant aux titres des compétences étant ajoutés par défaut)</i></input>
|
||||
> Montrer les tags des modules voire en ajouter
|
||||
<i>(ceux correspondant aux titres des compétences étant ajoutés par défaut)</i>
|
||||
</input>
|
||||
</form>
|
||||
"""
|
||||
)
|
||||
|
@ -211,8 +211,6 @@ def do_formsemestre_desinscription(
|
||||
"""Désinscription d'un étudiant.
|
||||
Si semestre extérieur et dernier inscrit, suppression de ce semestre.
|
||||
"""
|
||||
from app.scodoc import sco_formsemestre_edit
|
||||
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
etud = Identite.get_etud(etudid)
|
||||
# -- check lock
|
||||
@ -258,17 +256,14 @@ def do_formsemestre_desinscription(
|
||||
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
|
||||
# --- Semestre extérieur
|
||||
if formsemestre.modalite == "EXT":
|
||||
inscrits = do_formsemestre_inscription_list(
|
||||
args={"formsemestre_id": formsemestre_id}
|
||||
)
|
||||
nbinscrits = len(inscrits)
|
||||
if nbinscrits == 0:
|
||||
if 0 == len(formsemestre.inscriptions):
|
||||
log(
|
||||
f"""do_formsemestre_desinscription:
|
||||
suppression du semestre extérieur {formsemestre}"""
|
||||
)
|
||||
flash("Semestre exterieur supprimé")
|
||||
sco_formsemestre_edit.do_formsemestre_delete(formsemestre_id)
|
||||
db.session.delete(formsemestre)
|
||||
db.session.commit()
|
||||
flash(f"Semestre extérieur supprimé: {formsemestre.titre_annee()}")
|
||||
|
||||
logdb(
|
||||
cnx,
|
||||
@ -587,26 +582,29 @@ def formsemestre_inscription_option(etudid, formsemestre_id):
|
||||
ue_id = ue.id
|
||||
ue_descr = ue.acronyme
|
||||
if ue.type != UE_STANDARD:
|
||||
ue_descr += " <em>%s</em>" % UE_TYPE_NAME[ue.type]
|
||||
ue_descr += f" <em>{UE_TYPE_NAME[ue.type]}</em>"
|
||||
ue_status = nt.get_etud_ue_status(etudid, ue_id)
|
||||
if ue_status and ue_status["is_capitalized"]:
|
||||
sem_origin = sco_formsemestre.get_formsemestre(ue_status["formsemestre_id"])
|
||||
ue_descr += (
|
||||
' <a class="discretelink" href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" title="%s">(capitalisée le %s)'
|
||||
% (
|
||||
sem_origin["formsemestre_id"],
|
||||
etudid,
|
||||
sem_origin["titreannee"],
|
||||
ndb.DateISOtoDMY(ue_status["event_date"]),
|
||||
)
|
||||
)
|
||||
ue_descr += f"""
|
||||
<a class="discretelink" href="{ url_for(
|
||||
'notes.formsemestre_bulletinetud', scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=sem_origin["formsemestre_id"],
|
||||
etudid = etudid
|
||||
)}" title="{sem_origin['titreannee']}">(capitalisée le {
|
||||
ndb.DateISOtoDMY(ue_status["event_date"])
|
||||
})
|
||||
"""
|
||||
descr.append(
|
||||
(
|
||||
"sec_%s" % ue_id,
|
||||
f"sec_{ue_id}",
|
||||
{
|
||||
"input_type": "separator",
|
||||
"title": """<b>%s :</b> <a href="#" onclick="chkbx_select('%s', true);">inscrire</a> | <a href="#" onclick="chkbx_select('%s', false);">désinscrire</a> à tous les modules"""
|
||||
% (ue_descr, ue_id, ue_id),
|
||||
"title": f"""<b>{ue_descr} :</b>
|
||||
<a href="#" onclick="chkbx_select('{ue_id}', true);">inscrire</a> | <a
|
||||
href="#" onclick="chkbx_select('{ue_id}', false);">désinscrire</a>
|
||||
à tous les modules
|
||||
""",
|
||||
},
|
||||
)
|
||||
)
|
||||
@ -776,9 +774,7 @@ def do_moduleimpl_incription_options(
|
||||
# verifie que ce module existe bien
|
||||
mods = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)
|
||||
if len(mods) != 1:
|
||||
raise ScoValueError(
|
||||
"inscription: invalid moduleimpl_id: %s" % moduleimpl_id
|
||||
)
|
||||
raise ScoValueError(f"inscription: invalid moduleimpl_id: {moduleimpl_id}")
|
||||
mod = mods[0]
|
||||
sco_moduleimpl.do_moduleimpl_inscription_create(
|
||||
{"moduleimpl_id": moduleimpl_id, "etudid": etudid},
|
||||
@ -790,7 +786,7 @@ def do_moduleimpl_incription_options(
|
||||
mods = sco_moduleimpl.moduleimpl_list(moduleimpl_id=moduleimpl_id)
|
||||
if len(mods) != 1:
|
||||
raise ScoValueError(
|
||||
"desinscription: invalid moduleimpl_id: %s" % moduleimpl_id
|
||||
f"desinscription: invalid moduleimpl_id: {moduleimpl_id}"
|
||||
)
|
||||
mod = mods[0]
|
||||
inscr = sco_moduleimpl.do_moduleimpl_inscription_list(
|
||||
@ -798,8 +794,7 @@ def do_moduleimpl_incription_options(
|
||||
)
|
||||
if not inscr:
|
||||
raise ScoValueError(
|
||||
"pas inscrit a ce module ! (etudid=%s, moduleimpl_id=%s)"
|
||||
% (etudid, moduleimpl_id)
|
||||
f"pas inscrit a ce module ! (etudid={etudid}, moduleimpl_id={moduleimpl_id})"
|
||||
)
|
||||
oid = inscr[0]["moduleimpl_inscription_id"]
|
||||
sco_moduleimpl.do_moduleimpl_inscription_delete(
|
||||
@ -808,11 +803,13 @@ def do_moduleimpl_incription_options(
|
||||
|
||||
H = [
|
||||
html_sco_header.sco_header(),
|
||||
"""<h3>Modifications effectuées</h3>
|
||||
<p><a class="stdlink" href="%s">
|
||||
Retour à la fiche étudiant</a></p>
|
||||
"""
|
||||
% url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid),
|
||||
f"""<h3>Modifications effectuées</h3>
|
||||
<p><a class="stdlink" href="{
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
}">
|
||||
Retour à la fiche étudiant</a>
|
||||
</p>
|
||||
""",
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
return "\n".join(H)
|
||||
@ -856,49 +853,59 @@ def formsemestre_inscrits_ailleurs(formsemestre_id):
|
||||
"""Page listant les étudiants inscrits dans un autre semestre
|
||||
dont les dates recouvrent le semestre indiqué.
|
||||
"""
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
H = [
|
||||
html_sco_header.html_sem_header(
|
||||
"Inscriptions multiples parmi les étudiants du semestre ",
|
||||
init_qtip=True,
|
||||
javascripts=["js/etud_info.js"],
|
||||
)
|
||||
]
|
||||
insd = list_inscrits_ailleurs(formsemestre_id)
|
||||
# liste ordonnée par nom
|
||||
etudlist = [
|
||||
sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
for etudid in insd.keys()
|
||||
if insd[etudid]
|
||||
]
|
||||
etudlist.sort(key=lambda x: x["nom"])
|
||||
etudlist = [Identite.get_etud(etudid) for etudid, sems in insd.items() if sems]
|
||||
etudlist.sort(key=lambda x: x.sort_key)
|
||||
if etudlist:
|
||||
H.append("<ul>")
|
||||
for etud in etudlist:
|
||||
H.append(
|
||||
'<li><a href="%s" class="discretelink">%s</a> : '
|
||||
% (
|
||||
f"""<li><a id="{etud.id}" class="discretelink etudinfo"
|
||||
href={
|
||||
url_for(
|
||||
"scolar.fiche_etud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud["etudid"],
|
||||
),
|
||||
etud["nomprenom"],
|
||||
)
|
||||
etudid=etud.id,
|
||||
)
|
||||
}
|
||||
>{etud.nomprenom}</a> :
|
||||
"""
|
||||
)
|
||||
l = []
|
||||
for s in insd[etud["etudid"]]:
|
||||
for s in insd[etud.id]:
|
||||
l.append(
|
||||
'<a class="discretelink" href="formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(titremois)s</a>'
|
||||
% s
|
||||
f"""<a class="discretelink" href="{
|
||||
url_for('notes.formsemestre_status',
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id
|
||||
)}">{s['titremois']}</a>"""
|
||||
)
|
||||
H.append(", ".join(l))
|
||||
H.append("</li>")
|
||||
H.append("</ul>")
|
||||
H.append("<p>Total: %d étudiants concernés.</p>" % len(etudlist))
|
||||
H.append(
|
||||
"""<p class="help">Ces étudiants sont inscrits dans le semestre sélectionné et aussi dans d'autres semestres qui se déroulent en même temps ! <br>Sauf exception, cette situation est anormale:</p>
|
||||
f"""
|
||||
</ul>
|
||||
<p><b>Total: {len(etudlist)} étudiants concernés.</b></p>
|
||||
|
||||
<p class="help">Ces étudiants sont inscrits dans le semestre sélectionné et aussi
|
||||
dans d'autres semestres qui se déroulent en même temps !
|
||||
</p>
|
||||
<p>
|
||||
<b>Sauf exception, cette situation est anormale:</b>
|
||||
</p>
|
||||
<ul>
|
||||
<li>vérifier que les dates des semestres se suivent sans se chevaucher</li>
|
||||
<li>ou si besoin désinscrire le(s) étudiant(s) de l'un des semestres (via leurs fiches individuelles).</li>
|
||||
<li>vérifier que les dates des semestres se suivent <em>sans se chevaucher</em>
|
||||
</li>
|
||||
<li>ou bien si besoin désinscrire le(s) étudiant(s) de l'un des semestres
|
||||
(via leurs fiches individuelles).
|
||||
</li>
|
||||
</ul>
|
||||
"""
|
||||
)
|
||||
|
@ -110,12 +110,13 @@ def formsemestre_synchro_etuds(
|
||||
raise ScoValueError("opération impossible: semestre verrouille")
|
||||
if not sem["etapes"]:
|
||||
raise ScoValueError(
|
||||
"""opération impossible: ce semestre n'a pas de code étape
|
||||
(voir "<a href="formsemestre_editwithmodules?formsemestre_id=%(formsemestre_id)s">Modifier ce semestre</a>")
|
||||
f"""opération impossible: ce semestre n'a pas de code étape
|
||||
(voir <a class="stdlink" href="{
|
||||
url_for('notes.formsemestre_editwithmodules',
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)
|
||||
}">Modifier ce semestre</a>)
|
||||
"""
|
||||
% sem
|
||||
)
|
||||
header = html_sco_header.sco_header(page_title="Synchronisation étudiants")
|
||||
footer = html_sco_header.sco_footer()
|
||||
base_url = url_for(
|
||||
"notes.formsemestre_synchro_etuds",
|
||||
@ -166,7 +167,13 @@ def formsemestre_synchro_etuds(
|
||||
suffix=scu.XLSX_SUFFIX,
|
||||
)
|
||||
|
||||
H = [header]
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title="Synchronisation étudiants",
|
||||
init_qtip=True,
|
||||
javascripts=["js/etud_info.js"],
|
||||
)
|
||||
]
|
||||
if not submitted:
|
||||
H += _build_page(
|
||||
sem,
|
||||
|
@ -2411,6 +2411,29 @@ div.formation_list_ues_titre {
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
div.formation_semestre_niveaux_warning {
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
padding: 4px;
|
||||
margin-top: 8px;
|
||||
margin-left: 24px;
|
||||
margin-right: 24px;
|
||||
background-color: yellow;
|
||||
border-radius: 8px;
|
||||
}
|
||||
div.formation_semestre_niveaux_warning div {
|
||||
color: black;
|
||||
font-size: 110%;
|
||||
}
|
||||
div.formation_semestre_niveaux_warning ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
div.formation_semestre_niveaux_warning ul li:before {
|
||||
content: '⚠️';
|
||||
margin-right: 10px; /* Adjust space between emoji and text */
|
||||
}
|
||||
|
||||
div.formation_list_modules,
|
||||
div.formation_list_ues {
|
||||
border-radius: 18px;
|
||||
@ -2426,6 +2449,7 @@ div.formation_list_ues {
|
||||
}
|
||||
|
||||
div.formation_list_ues_content {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
div.formation_list_modules {
|
||||
@ -2508,7 +2532,13 @@ div.formation_parcs > div {
|
||||
opacity: 0.7;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
padding: 4px 8px;
|
||||
padding: 2px 6px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
div.formation_parcs > div.ue_tc {
|
||||
color: black;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.formation_parcs > div.focus {
|
||||
|
@ -4,6 +4,7 @@
|
||||
<div class="formation_list_ues_titre">Unités d'Enseignement
|
||||
semestre {{semestre_idx}} - {{ects_by_sem[semestre_idx] | safe}} ECTS
|
||||
</div>
|
||||
{{ html_ue_warning[semestre_idx] | safe }}
|
||||
<div class="formation_list_ues_content">
|
||||
<ul class="apc_ue_list">
|
||||
{% for ue in ues_by_sem[semestre_idx] %}
|
||||
@ -62,6 +63,8 @@
|
||||
<div class="formation_parcs">
|
||||
{% for parc in ue.parcours %}
|
||||
<div>{{ parc.code }}</div>
|
||||
{% else %}
|
||||
<div class="ue_tc" title="aucun parcours">Tronc Commun</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
Loading…
Reference in New Issue
Block a user