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>""",
|
text=f"""Suppression décision jury {detail} pour <a href="{url}">{etud.nomprenom}</a>""",
|
||||||
url=url,
|
url=url,
|
||||||
)
|
)
|
||||||
|
Scolog.logdb(
|
||||||
|
"jury_delete_manual",
|
||||||
|
etudid=etud.id,
|
||||||
|
msg=f"Validation {detail} effacée",
|
||||||
|
commit=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
|
@ -501,7 +501,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
semestre_idx=formsemestre.semestre_id,
|
semestre_idx=formsemestre.semestre_id,
|
||||||
formation_id=formsemestre.formation.id)}">
|
formation_id=formsemestre.formation.id)}">
|
||||||
{formsemestre.formation.html()} ({
|
{formsemestre.formation.html()|safe} ({
|
||||||
formsemestre.formation.id})</a>
|
formsemestre.formation.id})</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -64,7 +64,7 @@ class Formation(ScoDocModel):
|
|||||||
|
|
||||||
def html(self) -> str:
|
def html(self) -> str:
|
||||||
"titre complet pour affichage"
|
"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
|
@classmethod
|
||||||
def get_formation(cls, formation_id: int | str, dept_id: int = None) -> "Formation":
|
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)
|
d.pop("_sa_instance_state", None)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def html(self, detail=False) -> str:
|
def html(self, detail=True) -> str:
|
||||||
"Affichage html"
|
"Affichage html"
|
||||||
if self.ue_id is not None:
|
if self.ue_id is not None:
|
||||||
moyenne = (
|
moyenne = (
|
||||||
@ -114,11 +114,12 @@ class ScolarFormSemestreValidation(db.Model):
|
|||||||
+ ", ".join([p.code for p in self.ue.parcours]))
|
+ ", ".join([p.code for p in self.ue.parcours]))
|
||||||
+ "</span>"
|
+ "</span>"
|
||||||
if self.ue.parcours else ""}
|
if self.ue.parcours else ""}
|
||||||
{("émise par " + link)}
|
|
||||||
: <b>{self.code}</b>{moyenne}
|
: <b>{self.code}</b>{moyenne}
|
||||||
<b>{(self.ue.ects or 0):g} ECTS</b>
|
<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:
|
else:
|
||||||
return f"""Validation du semestre S{
|
return f"""Validation du semestre S{
|
||||||
self.formsemestre.semestre_id if self.formsemestre else "?"}
|
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é)"
|
"delete_small_dis_img", title="Suppression impossible (module utilisé)"
|
||||||
)
|
)
|
||||||
H = [
|
H = [
|
||||||
f"""<h2>{formation.html()} {lockicon}
|
f"""<h2>{formation.html()|safe} {lockicon}
|
||||||
</h2>
|
</h2>
|
||||||
""",
|
""",
|
||||||
]
|
]
|
||||||
|
@ -8,7 +8,12 @@ span.parcours {
|
|||||||
color: blueviolet;
|
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;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,6 +33,7 @@ details {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.validation-details {
|
div.validation-details {
|
||||||
margin-left: 32px;
|
margin-top: 12px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
margin-left: 32px;
|
||||||
}
|
}
|
@ -44,7 +44,7 @@
|
|||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
<h2>{{formation.html()}}</h2>
|
<h2>{{formation.html()|safe}}</h2>
|
||||||
|
|
||||||
{# Liens vers les différents parcours #}
|
{# Liens vers les différents parcours #}
|
||||||
<div class="les_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
|
d'associer à chaque semestre d'un niveau de compétence une UE de la formation
|
||||||
<a class="stdlink"
|
<a class="stdlink"
|
||||||
href="{{url_for('notes.ue_table', scodoc_dept=g.scodoc_dept, formation_id=formation.id )
|
href="{{url_for('notes.ue_table', scodoc_dept=g.scodoc_dept, formation_id=formation.id )
|
||||||
}}">{{formation.html()}}
|
}}">{{formation.html()|safe}}
|
||||||
</a>.</p>
|
</a>.</p>
|
||||||
|
|
||||||
<p>Le symbole <span class="parc">TC</span> désigne un niveau du tronc commun
|
<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 %}
|
{% block styles %}
|
||||||
{{super()}}
|
{{super()}}
|
||||||
@ -10,8 +10,13 @@
|
|||||||
<h1>Bilan des ECTS de {{etud.html_link_fiche()|safe}}</h1>
|
<h1>Bilan des ECTS de {{etud.html_link_fiche()|safe}}</h1>
|
||||||
|
|
||||||
<div class="help">
|
<div class="help">
|
||||||
Cette page donne toutes les UEs acquises par l'étudiant (codes <tt>ADM, ADJ, ADJR, ADSUP, CMP...</tt>)
|
<p>
|
||||||
dans chaque formation qu'il a suivi.
|
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>
|
</div>
|
||||||
|
|
||||||
{% for diplome in formsemestre_by_diplome %}
|
{% for diplome in formsemestre_by_diplome %}
|
||||||
@ -21,4 +26,29 @@
|
|||||||
{% include "jury/ue_list_etud_validations.j2" %}
|
{% include "jury/ue_list_etud_validations.j2" %}
|
||||||
{% endfor %}
|
{% 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 %}
|
{% 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}},
|
<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).
|
sur des semestres ou déclarées comme "antérieures" (externes).
|
||||||
</div>
|
</div>
|
||||||
<ul class="liste_validations">
|
<div class="liste_validations">
|
||||||
{% for validation in validations %}
|
{% for validation in validations %}
|
||||||
|
|
||||||
<li
|
<div
|
||||||
{% if loop.index0 > 0 and validation.formsemestre and loop.previtem.formsemestre.semestre_id != validation.formsemestre.semestre_id %}
|
{% if loop.index0 > 0 and validation.formsemestre and loop.previtem.formsemestre.semestre_id != validation.formsemestre.semestre_id %}
|
||||||
class="new_semestre"
|
class="new_semestre"
|
||||||
|
data-ue_id="{{validation.ue.id}}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
>{{ validation.html() | safe }}
|
>
|
||||||
{% if edit_mode %}
|
<details>
|
||||||
{% if validation.formsemestre and validation.formsemestre.can_edit_jury() %}
|
<summary>
|
||||||
<form class="inline-form">
|
{{ validation.html(detail=False) | safe }}
|
||||||
<button data-v_id="{{validation.id}}" data-type="validation_ue" data-etudid="{{etud.id}}">
|
{% if edit_mode %}
|
||||||
effacer
|
{% if validation.formsemestre and validation.formsemestre.can_edit_jury() %}
|
||||||
</button>
|
<form class="inline-form">
|
||||||
</form>
|
<button data-v_id="{{validation.id}}" data-type="validation_ue" data-etudid="{{etud.id}}">
|
||||||
{% else %}
|
effacer
|
||||||
{{ scu.icontag("lock_img", border="0", title="Semestre verrouillé")|safe }}
|
</button>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
{{ scu.icontag("lock_img", border="0", title="Semestre verrouillé")|safe }}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
</summary>
|
||||||
</li>
|
<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 %}
|
{% endfor %}
|
||||||
</ul>
|
</div>
|
||||||
|
<div><a class="stdlink" href="#" onclick="open_all_details()">ouvrir tous les détails</a></div>
|
||||||
{% if total_ects %}
|
{% if total_ects %}
|
||||||
<div class="total_ects">
|
<div class="total_ects">
|
||||||
Total ECTS: {{ "%g" % total_ects }}
|
Total ECTS (toutes UEs, y compris redoublées): {{ "%g" % total_ects }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
@ -944,6 +944,8 @@ def etud_bilan_ects(etudid: int):
|
|||||||
ects_by_diplome = {}
|
ects_by_diplome = {}
|
||||||
titre_by_diplome = {} # { diplome : titre }
|
titre_by_diplome = {} # { diplome : titre }
|
||||||
validations_by_diplome = {} # { diplome : query validations UEs }
|
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():
|
for diplome, formsemestres in formsemestre_by_diplome.items():
|
||||||
formsemestre = formsemestres[0]
|
formsemestre = formsemestres[0]
|
||||||
titre_by_diplome[diplome] = formsemestre.formation.get_titre_version()
|
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)
|
(validation.ue.ects or 0.0)
|
||||||
for validation in validations_by_diplome[diplome]
|
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(
|
return render_template(
|
||||||
"jury/etud_bilan_ects.j2",
|
"jury/etud_bilan_ects.j2",
|
||||||
@ -969,5 +1027,8 @@ def etud_bilan_ects(etudid: int):
|
|||||||
ects_by_diplome=ects_by_diplome,
|
ects_by_diplome=ects_by_diplome,
|
||||||
formsemestre_by_diplome=formsemestre_by_diplome,
|
formsemestre_by_diplome=formsemestre_by_diplome,
|
||||||
titre_by_diplome=titre_by_diplome,
|
titre_by_diplome=titre_by_diplome,
|
||||||
|
title=f"Bilan ECTS {etud.nomprenom}",
|
||||||
|
ue_warnings=ue_warnings,
|
||||||
validations_by_diplome=validations_by_diplome,
|
validations_by_diplome=validations_by_diplome,
|
||||||
|
sco=ScoData(etud=etud),
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user