forked from ScoDoc/ScoDoc
Amélioration page bilan ECTS: plus de détails, messages d'avertissement. Closes #992
This commit is contained in:
parent
e12dca7aef
commit
8c3e7b4ff6
@ -86,6 +86,12 @@ def _news_delete_jury_etud(etud: Identite, detail: str = ""):
|
||||
text=f"""Suppression décision jury {detail} pour <a href="{url}">{etud.nomprenom}</a>""",
|
||||
url=url,
|
||||
)
|
||||
Scolog.logdb(
|
||||
"jury_delete_manual",
|
||||
etudid=etud.id,
|
||||
msg=f"Validation {detail} effacée",
|
||||
commit=True,
|
||||
)
|
||||
|
||||
|
||||
@bp.route(
|
||||
|
@ -501,7 +501,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
semestre_idx=formsemestre.semestre_id,
|
||||
formation_id=formsemestre.formation.id)}">
|
||||
{formsemestre.formation.html()} ({
|
||||
{formsemestre.formation.html()|safe} ({
|
||||
formsemestre.formation.id})</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -64,7 +64,7 @@ class Formation(ScoDocModel):
|
||||
|
||||
def html(self) -> str:
|
||||
"titre complet pour affichage"
|
||||
return f"""Formation {self.titre} ({self.acronyme}) [version {self.version}] code {self.formation_code}"""
|
||||
return f"""Formation {self.titre} ({self.acronyme}) version {self.version} code <tt>{self.formation_code}</tt>"""
|
||||
|
||||
@classmethod
|
||||
def get_formation(cls, formation_id: int | str, dept_id: int = None) -> "Formation":
|
||||
|
@ -91,7 +91,7 @@ class ScolarFormSemestreValidation(db.Model):
|
||||
d.pop("_sa_instance_state", None)
|
||||
return d
|
||||
|
||||
def html(self, detail=False) -> str:
|
||||
def html(self, detail=True) -> str:
|
||||
"Affichage html"
|
||||
if self.ue_id is not None:
|
||||
moyenne = (
|
||||
@ -114,11 +114,12 @@ class ScolarFormSemestreValidation(db.Model):
|
||||
+ ", ".join([p.code for p in self.ue.parcours]))
|
||||
+ "</span>"
|
||||
if self.ue.parcours else ""}
|
||||
{("émise par " + link)}
|
||||
: <b>{self.code}</b>{moyenne}
|
||||
<b>{(self.ue.ects or 0):g} ECTS</b>
|
||||
le {self.event_date.strftime(scu.DATEATIME_FMT)}
|
||||
"""
|
||||
{("émise par " + link)}
|
||||
""" + (
|
||||
f"le {self.event_date.strftime(scu.DATEATIME_FMT)}" if detail else ""
|
||||
)
|
||||
else:
|
||||
return f"""Validation du semestre S{
|
||||
self.formsemestre.semestre_id if self.formsemestre else "?"}
|
||||
|
@ -765,7 +765,7 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
|
||||
"delete_small_dis_img", title="Suppression impossible (module utilisé)"
|
||||
)
|
||||
H = [
|
||||
f"""<h2>{formation.html()} {lockicon}
|
||||
f"""<h2>{formation.html()|safe} {lockicon}
|
||||
</h2>
|
||||
""",
|
||||
]
|
||||
|
@ -8,7 +8,12 @@ span.parcours {
|
||||
color: blueviolet;
|
||||
}
|
||||
|
||||
div.ue_list_etud_validations ul.liste_validations li {
|
||||
div.liste_validations {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
div.ue_list_etud_validations div.liste_validations details {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
@ -28,6 +33,7 @@ details {
|
||||
}
|
||||
|
||||
div.validation-details {
|
||||
margin-left: 32px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 16px;
|
||||
margin-left: 32px;
|
||||
}
|
@ -44,7 +44,7 @@
|
||||
{%- endmacro %}
|
||||
|
||||
{% block app_content %}
|
||||
<h2>{{formation.html()}}</h2>
|
||||
<h2>{{formation.html()|safe}}</h2>
|
||||
|
||||
{# Liens vers les différents parcours #}
|
||||
<div class="les_parcours">
|
||||
@ -133,7 +133,7 @@ Choisissez un parcours...
|
||||
d'associer à chaque semestre d'un niveau de compétence une UE de la formation
|
||||
<a class="stdlink"
|
||||
href="{{url_for('notes.ue_table', scodoc_dept=g.scodoc_dept, formation_id=formation.id )
|
||||
}}">{{formation.html()}}
|
||||
}}">{{formation.html()|safe}}
|
||||
</a>.</p>
|
||||
|
||||
<p>Le symbole <span class="parc">TC</span> désigne un niveau du tronc commun
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "sco_page.j2" %}
|
||||
{% extends "sco_page_dept.j2" %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
@ -10,8 +10,13 @@
|
||||
<h1>Bilan des ECTS de {{etud.html_link_fiche()|safe}}</h1>
|
||||
|
||||
<div class="help">
|
||||
Cette page donne toutes les UEs acquises par l'étudiant (codes <tt>ADM, ADJ, ADJR, ADSUP, CMP...</tt>)
|
||||
dans chaque formation qu'il a suivi.
|
||||
<p>
|
||||
Cette page donne toutes les UEs acquises par l'étudiant (codes <tt>ADM, ADJ, ADJR, ADSUP, CMP...</tt>).
|
||||
</p>
|
||||
<p>
|
||||
La somme des crédits ECTS en bas de page peut compter des UEs
|
||||
suivies plusieurs fois (redoublements) n'a pas de signification pour l'octroit des diplômes.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% for diplome in formsemestre_by_diplome %}
|
||||
@ -21,4 +26,29 @@
|
||||
{% include "jury/ue_list_etud_validations.j2" %}
|
||||
{% endfor %}
|
||||
|
||||
{% if ue_warnings %}
|
||||
<div class="scobox">
|
||||
<div class="scobox-title warning">Attention</div>
|
||||
<ul>
|
||||
{% for warning in ue_warnings %}
|
||||
<li>{{warning|safe}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="help fontred">Ces problème peuvent dans certains cas affecter
|
||||
le comptage des crédits ECTS et la délivrance des diplômes.</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock app_content %}
|
||||
|
||||
{% block scripts %}
|
||||
{{super()}}
|
||||
<script>
|
||||
function open_all_details() {
|
||||
var details = document.querySelectorAll('.liste_validations details');
|
||||
details.forEach(function(detail) {
|
||||
detail.open = true;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
@ -5,31 +5,52 @@
|
||||
<div class="help">Liste de toutes les UEs validées par {{etud.html_link_fiche()|safe}},
|
||||
sur des semestres ou déclarées comme "antérieures" (externes).
|
||||
</div>
|
||||
<ul class="liste_validations">
|
||||
<div class="liste_validations">
|
||||
{% for validation in validations %}
|
||||
|
||||
<li
|
||||
<div
|
||||
{% if loop.index0 > 0 and validation.formsemestre and loop.previtem.formsemestre.semestre_id != validation.formsemestre.semestre_id %}
|
||||
class="new_semestre"
|
||||
data-ue_id="{{validation.ue.id}}"
|
||||
{% endif %}
|
||||
>{{ validation.html() | safe }}
|
||||
{% if edit_mode %}
|
||||
{% if validation.formsemestre and validation.formsemestre.can_edit_jury() %}
|
||||
<form class="inline-form">
|
||||
<button data-v_id="{{validation.id}}" data-type="validation_ue" data-etudid="{{etud.id}}">
|
||||
effacer
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
{{ scu.icontag("lock_img", border="0", title="Semestre verrouillé")|safe }}
|
||||
>
|
||||
<details>
|
||||
<summary>
|
||||
{{ validation.html(detail=False) | safe }}
|
||||
{% if edit_mode %}
|
||||
{% if validation.formsemestre and validation.formsemestre.can_edit_jury() %}
|
||||
<form class="inline-form">
|
||||
<button data-v_id="{{validation.id}}" data-type="validation_ue" data-etudid="{{etud.id}}">
|
||||
effacer
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
{{ scu.icontag("lock_img", border="0", title="Semestre verrouillé")|safe }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
</summary>
|
||||
<div class="validation-details">
|
||||
<b>UE {{validation.ue.acronyme}}</b> <tt>[{{validation.ue.ue_code}}]</tt> en
|
||||
<a class="discretelink" href="{{
|
||||
url_for('notes.ue_table', scodoc_dept=g.scodoc_dept,
|
||||
formation_id=validation.ue.formation.id, semestre_idx=validation.ue.semestre_idx)
|
||||
}}">{{validation.ue.formation.html()|safe}}</a>
|
||||
{% if validation.ue.formation.is_apc() %}
|
||||
<div>Compétence: {{validation.ue.niveau_competence}}</div>
|
||||
<div>Référentiel :
|
||||
{{ validation.ue.formation.referentiel_competence.get_title()
|
||||
if validation.ue.formation.referentiel_competence else '<em>pas de référentiel</em>' }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div><a class="stdlink" href="#" onclick="open_all_details()">ouvrir tous les détails</a></div>
|
||||
{% if total_ects %}
|
||||
<div class="total_ects">
|
||||
Total ECTS: {{ "%g" % total_ects }}
|
||||
Total ECTS (toutes UEs, y compris redoublées): {{ "%g" % total_ects }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
@ -944,6 +944,8 @@ def etud_bilan_ects(etudid: int):
|
||||
ects_by_diplome = {}
|
||||
titre_by_diplome = {} # { diplome : titre }
|
||||
validations_by_diplome = {} # { diplome : query validations UEs }
|
||||
validations_by_ue_code = defaultdict(list) # { ue_code : [validation] }
|
||||
validations_by_niveau_sem = defaultdict(list) # { niveau_sem : [validation] }
|
||||
for diplome, formsemestres in formsemestre_by_diplome.items():
|
||||
formsemestre = formsemestres[0]
|
||||
titre_by_diplome[diplome] = formsemestre.formation.get_titre_version()
|
||||
@ -962,6 +964,62 @@ def etud_bilan_ects(etudid: int):
|
||||
(validation.ue.ects or 0.0)
|
||||
for validation in validations_by_diplome[diplome]
|
||||
)
|
||||
for validation in validations:
|
||||
validations_by_ue_code[validation.ue.ue_code].append(validation)
|
||||
validations_by_niveau_sem[
|
||||
(
|
||||
(
|
||||
validation.ue.niveau_competence.id
|
||||
if validation.ue.niveau_competence
|
||||
else None
|
||||
),
|
||||
validation.ue.semestre_idx,
|
||||
)
|
||||
].append(validation)
|
||||
|
||||
ref_comp_ids = {
|
||||
v.ue.formation.referentiel_competence_id
|
||||
for validations in validations_by_ue_code.values()
|
||||
for v in validations
|
||||
if v.ue.formation.referentiel_competence_id is not None
|
||||
}
|
||||
|
||||
ue_warnings = []
|
||||
if len(ref_comp_ids) > 1:
|
||||
ue_warnings.append(
|
||||
"""plusieurs référentiels de compétences utilisés !
|
||||
(ok si plusieurs diplôme différents suivis)"""
|
||||
)
|
||||
for ue_code, validations in validations_by_ue_code.items():
|
||||
ectss = {v.ue.ects for v in validations}
|
||||
if len(ectss) > 1:
|
||||
ects_str = ", ".join(
|
||||
f"{v.ue.acronyme}: {v.ue.ects} ects" for v in validations
|
||||
)
|
||||
ue_acros = ", ".join({v.ue.acronyme for v in validations})
|
||||
ue_warnings.append(
|
||||
f"""Les UEs {ue_acros} ont le même code ({ue_code
|
||||
}) mais des ECTS différents: {ects_str}"""
|
||||
)
|
||||
for (niveau_id, semestre_idx), validations in validations_by_niveau_sem.items():
|
||||
if not validations:
|
||||
continue # safeguard
|
||||
formation = validations[0].ue.formation
|
||||
ue_acros = ", ".join({v.ue.acronyme for v in validations})
|
||||
if niveau_id is None and formation.is_apc():
|
||||
ue_warnings.append(
|
||||
f"""Les UEs {ue_acros} du S{semestre_idx
|
||||
} n'ont pas de niveau de compétence associé !"""
|
||||
)
|
||||
ectss = {v.ue.ects for v in validations}
|
||||
if len(ectss) > 1:
|
||||
ects_str = ", ".join(
|
||||
f"{v.ue.acronyme}: {v.ue.ects} ects" for v in validations
|
||||
)
|
||||
ue_warnings.append(
|
||||
f"""Les UEs {ue_acros} du même code niveau de compétence
|
||||
({validations[0].ue.niveau_competence}) ont des ECTS différents: {ects_str}"""
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"jury/etud_bilan_ects.j2",
|
||||
@ -969,5 +1027,8 @@ def etud_bilan_ects(etudid: int):
|
||||
ects_by_diplome=ects_by_diplome,
|
||||
formsemestre_by_diplome=formsemestre_by_diplome,
|
||||
titre_by_diplome=titre_by_diplome,
|
||||
title=f"Bilan ECTS {etud.nomprenom}",
|
||||
ue_warnings=ue_warnings,
|
||||
validations_by_diplome=validations_by_diplome,
|
||||
sco=ScoData(etud=etud),
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user