Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into table
This commit is contained in:
commit
569df98e25
@ -630,19 +630,38 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
d[dec_rcue.rcue.ue_2.id] = dec_rcue
|
d[dec_rcue.rcue.ue_2.id] = dec_rcue
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def next_annee_semestre_id(self, code: str) -> int:
|
def next_semestre_ids(self, code: str) -> set[int]:
|
||||||
"""L'indice du semestre dans lequel l'étudiant est autorisé à
|
"""Les indices des semestres dans lequels l'étudiant est autorisé
|
||||||
poursuivre l'année suivante. None si aucun."""
|
à poursuivre après le semestre courant.
|
||||||
if self.formsemestre_pair is None:
|
"""
|
||||||
return None # seulement sur année
|
ids = set()
|
||||||
if code == RED:
|
# La poursuite d'études dans un semestre pair d’une même année
|
||||||
return self.formsemestre_pair.semestre_id - 1
|
# est de droit pour tout étudiant:
|
||||||
elif (
|
if (self.formsemestre.semestre_id % 2) and sco_codes.ParcoursBUT.NB_SEM:
|
||||||
code in sco_codes.BUT_CODES_PASSAGE
|
ids.add(self.formsemestre.semestre_id + 1)
|
||||||
|
|
||||||
|
# La poursuite d’études dans un semestre impair est possible si
|
||||||
|
# et seulement si l’étudiant a obtenu :
|
||||||
|
# - la moyenne à plus de la moitié des regroupements cohérents d’UE ;
|
||||||
|
# - et une moyenne égale ou supérieure à 8 sur 20 à chaque RCUE.
|
||||||
|
#
|
||||||
|
# La condition a paru trop stricte à de nombreux collègues.
|
||||||
|
# ScoDoc ne contraint donc pas à la respecter strictement.
|
||||||
|
# Si le code est dans BUT_CODES_PASSAGE (ADM, ADJ, PASD, PAS1NCI, ATJ),
|
||||||
|
# autorise à passer dans le semestre suivant
|
||||||
|
if (
|
||||||
|
self.jury_annuel
|
||||||
|
and code in sco_codes.BUT_CODES_PASSAGE
|
||||||
and self.formsemestre_pair.semestre_id < sco_codes.ParcoursBUT.NB_SEM
|
and self.formsemestre_pair.semestre_id < sco_codes.ParcoursBUT.NB_SEM
|
||||||
):
|
):
|
||||||
return self.formsemestre_pair.semestre_id + 1
|
ids.add(self.formsemestre.semestre_id + 1)
|
||||||
return None
|
|
||||||
|
if code == RED:
|
||||||
|
ids.add(
|
||||||
|
self.formsemestre.semestre_id - (self.formsemestre.semestre_id + 1) % 2
|
||||||
|
)
|
||||||
|
|
||||||
|
return ids
|
||||||
|
|
||||||
def record_form(self, form: dict):
|
def record_form(self, form: dict):
|
||||||
"""Enregistre les codes de jury en base
|
"""Enregistre les codes de jury en base
|
||||||
@ -704,9 +723,9 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
f"code annee <tt>{html.escape(code)}</tt> invalide pour formsemestre {html.escape(self.formsemestre)}"
|
f"code annee <tt>{html.escape(code)}</tt> invalide pour formsemestre {html.escape(self.formsemestre)}"
|
||||||
)
|
)
|
||||||
if code == self.code_valide or (self.code_valide is not None and no_overwrite):
|
|
||||||
self.recorded = True
|
if code != self.code_valide and (self.code_valide is None or not no_overwrite):
|
||||||
return False # no change
|
# Enregistrement du code annuel BUT
|
||||||
if self.validation:
|
if self.validation:
|
||||||
db.session.delete(self.validation)
|
db.session.delete(self.validation)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
@ -730,19 +749,15 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# --- Autorisation d'inscription dans semestre suivant ?
|
# --- Autorisation d'inscription dans semestre suivant ?
|
||||||
if self.formsemestre_pair is not None:
|
|
||||||
if code is None:
|
|
||||||
ScolarAutorisationInscription.delete_autorisation_etud(
|
ScolarAutorisationInscription.delete_autorisation_etud(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
origin_formsemestre_id=self.formsemestre_pair.id,
|
origin_formsemestre_id=self.formsemestre.id,
|
||||||
)
|
)
|
||||||
else:
|
for next_semestre_id in self.next_semestre_ids(code):
|
||||||
next_semestre_id = self.next_annee_semestre_id(code)
|
|
||||||
if next_semestre_id is not None:
|
|
||||||
ScolarAutorisationInscription.autorise_etud(
|
ScolarAutorisationInscription.autorise_etud(
|
||||||
self.etud.id,
|
self.etud.id,
|
||||||
self.formsemestre_pair.formation.formation_code,
|
self.formsemestre.formation.formation_code,
|
||||||
self.formsemestre_pair.id,
|
self.formsemestre.id,
|
||||||
next_semestre_id,
|
next_semestre_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -872,18 +887,18 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
self.invalidate_formsemestre_cache()
|
self.invalidate_formsemestre_cache()
|
||||||
|
|
||||||
def get_autorisations_passage(self) -> list[int]:
|
def get_autorisations_passage(self) -> list[int]:
|
||||||
"""Les liste des indices de semestres auxquels on est autorisé à
|
"""Liste des indices de semestres auxquels on est autorisé à
|
||||||
s'inscrire depuis cette année"""
|
s'inscrire depuis le semestre courant.
|
||||||
formsemestre = self.formsemestre_pair or self.formsemestre_impair
|
"""
|
||||||
if not formsemestre:
|
return sorted(
|
||||||
return []
|
[
|
||||||
return [
|
|
||||||
a.semestre_id
|
a.semestre_id
|
||||||
for a in ScolarAutorisationInscription.query.filter_by(
|
for a in ScolarAutorisationInscription.query.filter_by(
|
||||||
etudid=self.etud.id,
|
etudid=self.etud.id,
|
||||||
origin_formsemestre_id=formsemestre.id,
|
origin_formsemestre_id=self.formsemestre.id,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
def descr_niveaux_validation(self, line_sep: str = "\n") -> str:
|
def descr_niveaux_validation(self, line_sep: str = "\n") -> str:
|
||||||
"""Description textuelle des niveaux validés (enregistrés)
|
"""Description textuelle des niveaux validés (enregistrés)
|
||||||
|
@ -11,7 +11,7 @@ import re
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import flash, url_for
|
from flask import flash, render_template, url_for
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@ -32,8 +32,10 @@ from app.models import (
|
|||||||
ScolarAutorisationInscription,
|
ScolarAutorisationInscription,
|
||||||
ScolarFormSemestreValidation,
|
ScolarFormSemestreValidation,
|
||||||
)
|
)
|
||||||
|
from app.models.config import ScoDocSiteConfig
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
|
||||||
|
|
||||||
@ -43,9 +45,10 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
|
|||||||
"""
|
"""
|
||||||
H = []
|
H = []
|
||||||
|
|
||||||
H.append("""<div class="but_section_annee">""")
|
if deca.jury_annuel:
|
||||||
H.append(
|
H.append(
|
||||||
f"""
|
f"""
|
||||||
|
<div class="but_section_annee">
|
||||||
<div>
|
<div>
|
||||||
<b>Décision de jury pour l'année :</b> {
|
<b>Décision de jury pour l'année :</b> {
|
||||||
_gen_but_select("code_annee", deca.codes, deca.code_valide,
|
_gen_but_select("code_annee", deca.codes, deca.code_valide,
|
||||||
@ -53,11 +56,9 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
|
|||||||
}
|
}
|
||||||
<span>({deca.code_valide or 'non'} enregistrée)</span>
|
<span>({deca.code_valide or 'non'} enregistrée)</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
div_explanation = f"""<div class="but_explanation">{deca.explanation}</div>"""
|
|
||||||
|
|
||||||
H.append("""</div>""")
|
|
||||||
|
|
||||||
formsemestre_1 = deca.formsemestre_impair
|
formsemestre_1 = deca.formsemestre_impair
|
||||||
formsemestre_2 = deca.formsemestre_pair
|
formsemestre_2 = deca.formsemestre_pair
|
||||||
@ -74,7 +75,7 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
|
|||||||
<div class="titre_niveaux">
|
<div class="titre_niveaux">
|
||||||
<b>Niveaux de compétences et unités d'enseignement du BUT{deca.annee_but}</b>
|
<b>Niveaux de compétences et unités d'enseignement du BUT{deca.annee_but}</b>
|
||||||
</div>
|
</div>
|
||||||
{div_explanation}
|
<div class="but_explanation">{deca.explanation}</div>
|
||||||
<div class="but_annee">
|
<div class="but_annee">
|
||||||
<div class="titre"></div>
|
<div class="titre"></div>
|
||||||
<div class="titre">{"S" +str(formsemestre_1.semestre_id)
|
<div class="titre">{"S" +str(formsemestre_1.semestre_id)
|
||||||
@ -285,7 +286,7 @@ def jury_but_semestriel(
|
|||||||
read_only: bool,
|
read_only: bool,
|
||||||
navigation_div: str = "",
|
navigation_div: str = "",
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Formulaire saisie décision d'UE d'un semestre BUT isolé (pas jury annuel)"""
|
"""Page: formulaire saisie décision d'UE d'un semestre BUT isolé (pas jury annuel)."""
|
||||||
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
|
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
|
||||||
parcour, ues = jury_but.list_ue_parcour_etud(formsemestre, etud, res)
|
parcour, ues = jury_but.list_ue_parcour_etud(formsemestre, etud, res)
|
||||||
inscription_etat = etud.inscription_etat(formsemestre.id)
|
inscription_etat = etud.inscription_etat(formsemestre.id)
|
||||||
@ -450,11 +451,27 @@ def jury_but_semestriel(
|
|||||||
)
|
)
|
||||||
H.append("</div>") # but_annee
|
H.append("</div>") # but_annee
|
||||||
|
|
||||||
|
div_autorisations_passage = (
|
||||||
|
f"""
|
||||||
|
<div class="but_autorisations_passage">
|
||||||
|
<span>Autorisé à passer en :</span>
|
||||||
|
{ ", ".join( ["S" + str(a.semestre_id or '') for a in autorisations_passage ] )}
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
if autorisations_passage
|
||||||
|
else """<div class="but_autorisations_passage but_explanation">pas d'autorisations de passage enregistrées.</div>"""
|
||||||
|
)
|
||||||
|
H.append(div_autorisations_passage)
|
||||||
|
|
||||||
if read_only:
|
if read_only:
|
||||||
H.append(
|
H.append(
|
||||||
"""<div class="but_explanation">
|
f"""<div class="but_explanation">
|
||||||
Vous n'avez pas la permission de modifier ces décisions.
|
{"Vous n'avez pas la permission de modifier ces décisions."
|
||||||
Les champs entourés en vert sont enregistrés.</div>"""
|
if formsemestre.etat
|
||||||
|
else "Semestre verrouillé."}
|
||||||
|
Les champs entourés en vert sont enregistrés.
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if formsemestre.semestre_id < formsemestre.formation.get_parcours().NB_SEM:
|
if formsemestre.semestre_id < formsemestre.formation.get_parcours().NB_SEM:
|
||||||
@ -464,9 +481,6 @@ def jury_but_semestriel(
|
|||||||
<input type="checkbox" name="autorisation_passage" value="1" {
|
<input type="checkbox" name="autorisation_passage" value="1" {
|
||||||
"checked" if est_autorise_a_passer else ""}>
|
"checked" if est_autorise_a_passer else ""}>
|
||||||
<em>autoriser à passer dans le semestre S{formsemestre.semestre_id+1}</em>
|
<em>autoriser à passer dans le semestre S{formsemestre.semestre_id+1}</em>
|
||||||
{("(autorisations enregistrées: " + ' '.join(
|
|
||||||
'S' + str(a.semestre_id or '') for a in autorisations_passage) + ")"
|
|
||||||
) if autorisations_passage else ""}
|
|
||||||
</input>
|
</input>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
@ -481,7 +495,19 @@ def jury_but_semestriel(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
H.append(navigation_div)
|
H.append(navigation_div)
|
||||||
|
H.append("</div>")
|
||||||
|
H.append(
|
||||||
|
render_template(
|
||||||
|
"but/documentation_codes_jury.html",
|
||||||
|
nom_univ=f"""Export {sco_preferences.get_preference("InstituteName")
|
||||||
|
or sco_preferences.get_preference("UnivName")
|
||||||
|
or "Apogée"}""",
|
||||||
|
codes=ScoDocSiteConfig.get_codes_apo_dict(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
|
@ -740,7 +740,8 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
f"""<a href="{url_for('notes.formsemestre_validation_etud_form',
|
f"""<a href="{url_for('notes.formsemestre_validation_etud_form',
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=self.formsemestre.id, etudid=etudid
|
scodoc_dept=g.scodoc_dept, formsemestre_id=self.formsemestre.id, etudid=etudid
|
||||||
)
|
)
|
||||||
}">{"saisir" if not jury_code_sem else "modifier"} décision</a>""",
|
}">{("saisir" if not jury_code_sem else "modifier")
|
||||||
|
if self.formsemestre.etat else "voir"} décisions</a>""",
|
||||||
"col_jury_link",
|
"col_jury_link",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -55,7 +55,8 @@ class Formation(db.Model):
|
|||||||
modules = db.relationship("Module", lazy="dynamic", backref="formation")
|
modules = db.relationship("Module", lazy="dynamic", backref="formation")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__}(id={self.id}, dept_id={self.dept_id}, acronyme='{self.acronyme!r}')>"
|
return f"""<{self.__class__.__name__}(id={self.id}, dept_id={
|
||||||
|
self.dept_id}, acronyme={self.acronyme!r}, version={self.version})>"""
|
||||||
|
|
||||||
def to_html(self) -> str:
|
def to_html(self) -> str:
|
||||||
"titre complet pour affichage"
|
"titre complet pour affichage"
|
||||||
|
@ -111,6 +111,7 @@ class UniteEns(db.Model):
|
|||||||
e["ects"] = e["ects"]
|
e["ects"] = e["ects"]
|
||||||
e["coefficient"] = e["coefficient"] if e["coefficient"] else 0.0
|
e["coefficient"] = e["coefficient"] if e["coefficient"] else 0.0
|
||||||
e["code_apogee"] = e["code_apogee"] or "" # pas de None
|
e["code_apogee"] = e["code_apogee"] or "" # pas de None
|
||||||
|
e["parcour"] = self.parcour.to_dict() if self.parcour else None
|
||||||
if with_module_ue_coefs:
|
if with_module_ue_coefs:
|
||||||
if convert_objects:
|
if convert_objects:
|
||||||
e["module_ue_coefs"] = [
|
e["module_ue_coefs"] = [
|
||||||
|
@ -99,7 +99,7 @@ def html_edit_formation_apc(
|
|||||||
|
|
||||||
H = [
|
H = [
|
||||||
render_template(
|
render_template(
|
||||||
"pn/form_ues.html",
|
"pn/form_ues.j2",
|
||||||
formation=formation,
|
formation=formation,
|
||||||
semestre_ids=semestre_ids,
|
semestre_ids=semestre_ids,
|
||||||
editable=editable,
|
editable=editable,
|
||||||
@ -122,7 +122,7 @@ def html_edit_formation_apc(
|
|||||||
).first()
|
).first()
|
||||||
H += [
|
H += [
|
||||||
render_template(
|
render_template(
|
||||||
"pn/form_mods.html",
|
"pn/form_mods.j2",
|
||||||
formation=formation,
|
formation=formation,
|
||||||
titre=f"Ressources du S{semestre_idx}",
|
titre=f"Ressources du S{semestre_idx}",
|
||||||
create_element_msg="créer une nouvelle ressource",
|
create_element_msg="créer une nouvelle ressource",
|
||||||
@ -138,7 +138,7 @@ def html_edit_formation_apc(
|
|||||||
if ues_by_sem[semestre_idx].count() > 0
|
if ues_by_sem[semestre_idx].count() > 0
|
||||||
else "",
|
else "",
|
||||||
render_template(
|
render_template(
|
||||||
"pn/form_mods.html",
|
"pn/form_mods.j2",
|
||||||
formation=formation,
|
formation=formation,
|
||||||
titre=f"Situations d'Apprentissage et d'Évaluation (SAÉs) S{semestre_idx}",
|
titre=f"Situations d'Apprentissage et d'Évaluation (SAÉs) S{semestre_idx}",
|
||||||
create_element_msg="créer une nouvelle SAÉ",
|
create_element_msg="créer une nouvelle SAÉ",
|
||||||
@ -154,7 +154,7 @@ def html_edit_formation_apc(
|
|||||||
if ues_by_sem[semestre_idx].count() > 0
|
if ues_by_sem[semestre_idx].count() > 0
|
||||||
else "",
|
else "",
|
||||||
render_template(
|
render_template(
|
||||||
"pn/form_mods.html",
|
"pn/form_mods.j2",
|
||||||
formation=formation,
|
formation=formation,
|
||||||
titre=f"Autres modules (non BUT) du S{semestre_idx}",
|
titre=f"Autres modules (non BUT) du S{semestre_idx}",
|
||||||
create_element_msg="créer un nouveau module",
|
create_element_msg="créer un nouveau module",
|
||||||
@ -196,7 +196,7 @@ def html_ue_infos(ue):
|
|||||||
and ue.matieres.count() == 0
|
and ue.matieres.count() == 0
|
||||||
)
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"pn/ue_infos.html",
|
"pn/ue_infos.j2",
|
||||||
titre=f"UE {ue.acronyme} {ue.titre}",
|
titre=f"UE {ue.acronyme} {ue.titre}",
|
||||||
ue=ue,
|
ue=ue,
|
||||||
formsemestres=formsemestres,
|
formsemestres=formsemestres,
|
||||||
|
@ -723,7 +723,7 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
|
|||||||
"libjs/jQuery-tagEditor/jquery.caret.min.js",
|
"libjs/jQuery-tagEditor/jquery.caret.min.js",
|
||||||
"js/module_tag_editor.js",
|
"js/module_tag_editor.js",
|
||||||
],
|
],
|
||||||
page_title=f"Programme {formation.acronyme}",
|
page_title=f"Programme {formation.acronyme} v{formation.version}",
|
||||||
),
|
),
|
||||||
f"""<h2>{formation.to_html()} {lockicon}
|
f"""<h2>{formation.to_html()} {lockicon}
|
||||||
</h2>
|
</h2>
|
||||||
@ -765,7 +765,7 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
|||||||
# Description de la formation
|
# Description de la formation
|
||||||
H.append(
|
H.append(
|
||||||
render_template(
|
render_template(
|
||||||
"pn/form_descr.html",
|
"pn/form_descr.j2",
|
||||||
formation=formation,
|
formation=formation,
|
||||||
parcours=parcours,
|
parcours=parcours,
|
||||||
editable=editable,
|
editable=editable,
|
||||||
@ -913,8 +913,12 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
|||||||
<li><a class="stdlink" href="{
|
<li><a class="stdlink" href="{
|
||||||
url_for('notes.formation_export', scodoc_dept=g.scodoc_dept,
|
url_for('notes.formation_export', scodoc_dept=g.scodoc_dept,
|
||||||
formation_id=formation_id, format='xml')
|
formation_id=formation_id, format='xml')
|
||||||
}">Export XML de la formation</a>
|
}">Export XML de la formation</a> ou
|
||||||
(permet de la sauvegarder pour l'échanger avec un autre site)
|
<a class="stdlink" href="{
|
||||||
|
url_for('notes.formation_export', scodoc_dept=g.scodoc_dept,
|
||||||
|
formation_id=formation_id, format='xml', export_codes_apo=0)
|
||||||
|
}">sans codes Apogée</a>
|
||||||
|
(permet de l'enregistrer pour l'échanger avec un autre site)
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li><a class="stdlink" href="{
|
<li><a class="stdlink" href="{
|
||||||
|
@ -109,6 +109,7 @@ def formation_export(
|
|||||||
export_ids=False,
|
export_ids=False,
|
||||||
export_tags=True,
|
export_tags=True,
|
||||||
export_external_ues=False,
|
export_external_ues=False,
|
||||||
|
export_codes_apo=True,
|
||||||
format=None,
|
format=None,
|
||||||
):
|
):
|
||||||
"""Get a formation, with UE, matieres, modules
|
"""Get a formation, with UE, matieres, modules
|
||||||
@ -116,30 +117,45 @@ def formation_export(
|
|||||||
"""
|
"""
|
||||||
formation: Formation = Formation.query.get_or_404(formation_id)
|
formation: Formation = Formation.query.get_or_404(formation_id)
|
||||||
f_dict = formation.to_dict(with_refcomp_attrs=True)
|
f_dict = formation.to_dict(with_refcomp_attrs=True)
|
||||||
selector = {"formation_id": formation_id}
|
if not export_ids:
|
||||||
|
del f_dict["formation_id"]
|
||||||
|
del f_dict["dept_id"]
|
||||||
|
ues = formation.ues
|
||||||
if not export_external_ues:
|
if not export_external_ues:
|
||||||
selector["is_external"] = False
|
ues = ues.filter_by(is_external=False)
|
||||||
ues = sco_edit_ue.ue_list(selector)
|
ues = ues.all()
|
||||||
f_dict["ue"] = ues
|
ues.sort(key=lambda u: (u.semestre_idx or 0, u.numero or 0, u.acronyme))
|
||||||
for ue_dict in ues:
|
f_dict["ue"] = []
|
||||||
ue_id = ue_dict["ue_id"]
|
for ue in ues:
|
||||||
|
ue_dict = ue.to_dict()
|
||||||
|
f_dict["ue"].append(ue_dict)
|
||||||
|
ue_dict.pop("module_ue_coefs", None)
|
||||||
if formation.is_apc():
|
if formation.is_apc():
|
||||||
# BUT: indique niveau de compétence associé à l'UE
|
# BUT: indique niveau de compétence associé à l'UE
|
||||||
ue = UniteEns.query.get(ue_id)
|
|
||||||
if ue.niveau_competence:
|
if ue.niveau_competence:
|
||||||
ue_dict["apc_niveau_libelle"] = ue.niveau_competence.libelle
|
ue_dict["apc_niveau_libelle"] = ue.niveau_competence.libelle
|
||||||
ue_dict["apc_niveau_annee"] = ue.niveau_competence.annee
|
ue_dict["apc_niveau_annee"] = ue.niveau_competence.annee
|
||||||
ue_dict["apc_niveau_ordre"] = ue.niveau_competence.ordre
|
ue_dict["apc_niveau_ordre"] = ue.niveau_competence.ordre
|
||||||
ue_dict["reference"] = ue_id # pour les coefficients
|
# Et le parcour:
|
||||||
|
if ue.parcour:
|
||||||
|
ue_dict["parcour"] = [ue.parcour.to_dict(with_annees=False)]
|
||||||
|
ue_dict["reference"] = ue.id # pour les coefficients
|
||||||
if not export_ids:
|
if not export_ids:
|
||||||
del ue_dict["id"]
|
for id_id in (
|
||||||
del ue_dict["ue_id"]
|
"id",
|
||||||
del ue_dict["formation_id"]
|
"ue_id",
|
||||||
if "niveau_competence_id" in ue_dict:
|
"formation_id",
|
||||||
del ue_dict["niveau_competence_id"]
|
"parcour_id",
|
||||||
|
"niveau_competence_id",
|
||||||
|
):
|
||||||
|
ue_dict.pop(id_id, None)
|
||||||
|
|
||||||
|
if not export_codes_apo:
|
||||||
|
ue_dict.pop("code_apogee", None)
|
||||||
if ue_dict["ects"] is None:
|
if ue_dict["ects"] is None:
|
||||||
del ue_dict["ects"]
|
del ue_dict["ects"]
|
||||||
mats = sco_edit_matiere.matiere_list({"ue_id": ue_id})
|
mats = sco_edit_matiere.matiere_list({"ue_id": ue.id})
|
||||||
|
mats.sort(key=lambda m: m["numero"] or 0)
|
||||||
ue_dict["matiere"] = mats
|
ue_dict["matiere"] = mats
|
||||||
for mat in mats:
|
for mat in mats:
|
||||||
matiere_id = mat["matiere_id"]
|
matiere_id = mat["matiere_id"]
|
||||||
@ -148,6 +164,7 @@ def formation_export(
|
|||||||
del mat["matiere_id"]
|
del mat["matiere_id"]
|
||||||
del mat["ue_id"]
|
del mat["ue_id"]
|
||||||
mods = sco_edit_module.module_list({"matiere_id": matiere_id})
|
mods = sco_edit_module.module_list({"matiere_id": matiere_id})
|
||||||
|
mods.sort(key=lambda m: (m["numero"] or 0, m["code"]))
|
||||||
mat["module"] = mods
|
mat["module"] = mods
|
||||||
for mod in mods:
|
for mod in mods:
|
||||||
module_id = mod["module_id"]
|
module_id = mod["module_id"]
|
||||||
@ -183,6 +200,8 @@ def formation_export(
|
|||||||
del mod["matiere_id"]
|
del mod["matiere_id"]
|
||||||
del mod["module_id"]
|
del mod["module_id"]
|
||||||
del mod["formation_id"]
|
del mod["formation_id"]
|
||||||
|
if not export_codes_apo:
|
||||||
|
del mod["code_apogee"]
|
||||||
if mod["ects"] is None:
|
if mod["ects"] is None:
|
||||||
del mod["ects"]
|
del mod["ects"]
|
||||||
|
|
||||||
@ -323,14 +342,30 @@ def formation_import_xml(doc: str, import_tags=True, use_local_refcomp=False):
|
|||||||
referentiel_competence_id, ue_info[1]
|
referentiel_competence_id, ue_info[1]
|
||||||
)
|
)
|
||||||
ue_id = sco_edit_ue.do_ue_create(ue_info[1])
|
ue_id = sco_edit_ue.do_ue_create(ue_info[1])
|
||||||
|
ue: UniteEns = UniteEns.query.get(ue_id)
|
||||||
|
assert ue
|
||||||
if xml_ue_id:
|
if xml_ue_id:
|
||||||
ues_old2new[xml_ue_id] = ue_id
|
ues_old2new[xml_ue_id] = ue_id
|
||||||
# élément optionnel présent dans les exports BUT:
|
# élément optionnel présent dans les exports BUT:
|
||||||
ue_reference = ue_info[1].get("reference")
|
ue_reference = ue_info[1].get("reference")
|
||||||
if ue_reference:
|
if ue_reference:
|
||||||
ue_reference_to_id[int(ue_reference)] = ue_id
|
ue_reference_to_id[int(ue_reference)] = ue_id
|
||||||
|
|
||||||
# -- create matieres
|
# -- create matieres
|
||||||
for mat_info in ue_info[2]:
|
for mat_info in ue_info[2]:
|
||||||
|
if mat_info[0] == "parcour":
|
||||||
|
# Parcours (BUT)
|
||||||
|
code_parcours = mat_info[1]["code"]
|
||||||
|
parcour = ApcParcours.query.filter_by(
|
||||||
|
code=code_parcours,
|
||||||
|
referentiel_id=referentiel_competence_id,
|
||||||
|
).first()
|
||||||
|
if parcour:
|
||||||
|
ue.parcour = parcour
|
||||||
|
db.session.add(ue)
|
||||||
|
else:
|
||||||
|
log(f"Warning: parcours {code_parcours} inexistant !")
|
||||||
|
continue
|
||||||
assert mat_info[0] == "matiere"
|
assert mat_info[0] == "matiere"
|
||||||
mat_info[1]["ue_id"] = ue_id
|
mat_info[1]["ue_id"] = ue_id
|
||||||
mat_id = sco_edit_matiere.do_matiere_create(mat_info[1])
|
mat_id = sco_edit_matiere.do_matiere_create(mat_info[1])
|
||||||
@ -382,12 +417,12 @@ def formation_import_xml(doc: str, import_tags=True, use_local_refcomp=False):
|
|||||||
# associe les parcours de ce module (BUT)
|
# associe les parcours de ce module (BUT)
|
||||||
if referentiel_competence_id is not None:
|
if referentiel_competence_id is not None:
|
||||||
code_parcours = child[1]["code"]
|
code_parcours = child[1]["code"]
|
||||||
parcours = ApcParcours.query.filter_by(
|
parcour = ApcParcours.query.filter_by(
|
||||||
code=code_parcours,
|
code=code_parcours,
|
||||||
referentiel_id=referentiel_competence_id,
|
referentiel_id=referentiel_competence_id,
|
||||||
).first()
|
).first()
|
||||||
if parcours:
|
if parcour:
|
||||||
module.parcours.append(parcours)
|
module.parcours.append(parcour)
|
||||||
db.session.add(module)
|
db.session.add(module)
|
||||||
else:
|
else:
|
||||||
log(
|
log(
|
||||||
|
@ -556,9 +556,10 @@ def do_formsemestre_createwithmodules(edit=False, formsemestre: FormSemestre = N
|
|||||||
str(parcour.id) for parcour in ref_comp.parcours
|
str(parcour.id) for parcour in ref_comp.parcours
|
||||||
],
|
],
|
||||||
"explanation": """Parcours proposés dans ce semestre.
|
"explanation": """Parcours proposés dans ce semestre.
|
||||||
S'il s'agit d'un semestre de "tronc commun", ne pas indiquer de parcours.
|
Cocher tous les parcours est exactement équivalent à n'en cocher aucun:
|
||||||
Attention, si aucun parcours n'est coché, toutes les UEs du
|
par exemple, pour un semestre de "tronc commun", on peut ne pas indiquer de parcours.
|
||||||
programme seront considérées, quel que soit leur parcours.
|
Si aucun parcours n'est coché, toutes les UEs du
|
||||||
|
programme seront donc considérées, quel que soit leur parcours.
|
||||||
""",
|
""",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -602,9 +602,21 @@ def formsemestre_recap_parcours_table(
|
|||||||
<td class="datedebut">{sem['mois_debut']}</td>
|
<td class="datedebut">{sem['mois_debut']}</td>
|
||||||
<td class="rcp_titre_sem"><a class="formsemestre_status_link"
|
<td class="rcp_titre_sem"><a class="formsemestre_status_link"
|
||||||
href="{a_url}formsemestre_bulletinetud?formsemestre_id={formsemestre.id}&etudid={etudid}"
|
href="{a_url}formsemestre_bulletinetud?formsemestre_id={formsemestre.id}&etudid={etudid}"
|
||||||
title="Bulletin de notes">{formsemestre.titre_annee()}{parcours_name}</a></td>
|
title="Bulletin de notes">{formsemestre.titre_annee()}{parcours_name}</a>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
if nt.is_apc:
|
||||||
|
H.append(
|
||||||
|
f"""<a class="stdlink jury_link" title="Validations du semestre BUT"
|
||||||
|
href="{ url_for("notes.formsemestre_validation_but",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre.id,
|
||||||
|
etudid=etudid,
|
||||||
|
)
|
||||||
|
}">jury</a>"""
|
||||||
|
)
|
||||||
|
H.append("""</td>""")
|
||||||
|
|
||||||
if nt.is_apc:
|
if nt.is_apc:
|
||||||
H.append('<td class="rcp_but">BUT</td>')
|
H.append('<td class="rcp_but">BUT</td>')
|
||||||
elif decision_sem:
|
elif decision_sem:
|
||||||
|
@ -39,21 +39,22 @@ from app import log
|
|||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_pvjury
|
from app.scodoc import sco_formations
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_formsemestre_inscriptions
|
from app.scodoc import sco_formsemestre_inscriptions
|
||||||
from app.scodoc import sco_formations
|
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_preferences
|
||||||
|
from app.scodoc import sco_pvjury
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
|
||||||
|
|
||||||
def list_authorized_etuds_by_sem(sem, delai=274, ignore_jury=False):
|
def list_authorized_etuds_by_sem(sem, delai=274, ignore_jury=False):
|
||||||
"""Liste des etudiants autorisés à s'inscrire dans sem.
|
"""Liste des etudiants autorisés à s'inscrire dans sem.
|
||||||
delai = nb de jours max entre la date de l'autorisation et celle de debut du semestre cible.
|
delai = nb de jours max entre la date de l'autorisation et celle de debut du semestre cible.
|
||||||
ignore_jury: si vrai, considère tous les étudiants comem autorisés, même
|
ignore_jury: si vrai, considère tous les étudiants comme autorisés, même
|
||||||
s'ils n'ont pas de décision de jury.
|
s'ils n'ont pas de décision de jury.
|
||||||
"""
|
"""
|
||||||
src_sems = list_source_sems(sem, delai=delai)
|
src_sems = list_source_sems(sem, delai=delai)
|
||||||
@ -276,8 +277,8 @@ def formsemestre_inscr_passage(
|
|||||||
submitted=False,
|
submitted=False,
|
||||||
dialog_confirmed=False,
|
dialog_confirmed=False,
|
||||||
ignore_jury=False,
|
ignore_jury=False,
|
||||||
):
|
) -> str:
|
||||||
"""Form. pour inscription des etudiants d'un semestre dans un autre
|
"""Page Form. pour inscription des etudiants d'un semestre dans un autre
|
||||||
(donné par formsemestre_id).
|
(donné par formsemestre_id).
|
||||||
Permet de selectionner parmi les etudiants autorisés à s'inscrire.
|
Permet de selectionner parmi les etudiants autorisés à s'inscrire.
|
||||||
Principe:
|
Principe:
|
||||||
@ -285,8 +286,8 @@ def formsemestre_inscr_passage(
|
|||||||
- afficher chaque semestre "boites" avec cases à cocher
|
- afficher chaque semestre "boites" avec cases à cocher
|
||||||
- si l'étudiant est déjà inscrit, le signaler (gras, nom de groupes): il peut être désinscrit
|
- si l'étudiant est déjà inscrit, le signaler (gras, nom de groupes): il peut être désinscrit
|
||||||
- on peut choisir les groupes TD, TP, TA
|
- on peut choisir les groupes TD, TP, TA
|
||||||
- seuls les etudiants non inscrits changent (de groupe)
|
- seuls les étudiants non inscrits changent (de groupe)
|
||||||
- les etudiants inscrit qui se trouvent décochés sont désinscrits
|
- les étudiants inscrit qui se trouvent décochés sont désinscrits
|
||||||
- Confirmation: indiquer les étudiants inscrits et ceux désinscrits, le total courant.
|
- Confirmation: indiquer les étudiants inscrits et ceux désinscrits, le total courant.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -326,11 +327,9 @@ def formsemestre_inscr_passage(
|
|||||||
a_desinscrire = inscrits_set - etuds_set
|
a_desinscrire = inscrits_set - etuds_set
|
||||||
else:
|
else:
|
||||||
a_inscrire = a_desinscrire = []
|
a_inscrire = a_desinscrire = []
|
||||||
# log('formsemestre_inscr_passage: a_inscrire=%s' % str(a_inscrire) )
|
|
||||||
# log('formsemestre_inscr_passage: a_desinscrire=%s' % str(a_desinscrire) )
|
|
||||||
|
|
||||||
if not submitted:
|
if not submitted:
|
||||||
H += build_page(
|
H += _build_page(
|
||||||
sem,
|
sem,
|
||||||
auth_etuds_by_sem,
|
auth_etuds_by_sem,
|
||||||
inscrits,
|
inscrits,
|
||||||
@ -343,7 +342,7 @@ def formsemestre_inscr_passage(
|
|||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
# Confirmation
|
# Confirmation
|
||||||
if a_inscrire:
|
if a_inscrire:
|
||||||
H.append("<h3>Etudiants à inscrire</h3><ol>")
|
H.append("<h3>Étudiants à inscrire</h3><ol>")
|
||||||
for etud in set_to_sorted_etud_list(a_inscrire):
|
for etud in set_to_sorted_etud_list(a_inscrire):
|
||||||
H.append("<li>%(nomprenom)s</li>" % etud)
|
H.append("<li>%(nomprenom)s</li>" % etud)
|
||||||
H.append("</ol>")
|
H.append("</ol>")
|
||||||
@ -354,7 +353,7 @@ def formsemestre_inscr_passage(
|
|||||||
H.append('<li class="inscrailleurs">%(nomprenom)s</li>' % etud)
|
H.append('<li class="inscrailleurs">%(nomprenom)s</li>' % etud)
|
||||||
H.append("</ul>")
|
H.append("</ul>")
|
||||||
if a_desinscrire:
|
if a_desinscrire:
|
||||||
H.append("<h3>Etudiants à désinscrire</h3><ol>")
|
H.append("<h3>Étudiants à désinscrire</h3><ol>")
|
||||||
for etudid in a_desinscrire:
|
for etudid in a_desinscrire:
|
||||||
H.append(
|
H.append(
|
||||||
'<li class="desinscription">%(nomprenom)s</li>'
|
'<li class="desinscription">%(nomprenom)s</li>'
|
||||||
@ -384,21 +383,29 @@ def formsemestre_inscr_passage(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
with sco_cache.DeferredSemCacheManager():
|
||||||
# Inscription des étudiants au nouveau semestre:
|
# Inscription des étudiants au nouveau semestre:
|
||||||
do_inscrit(
|
do_inscrit(
|
||||||
sem,
|
sem,
|
||||||
a_inscrire,
|
a_inscrire,
|
||||||
inscrit_groupes=inscrit_groupes,
|
inscrit_groupes=inscrit_groupes,
|
||||||
)
|
)
|
||||||
|
# Désinscriptions:
|
||||||
# Desincriptions:
|
|
||||||
do_desinscrit(sem, a_desinscrire)
|
do_desinscrit(sem, a_desinscrire)
|
||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
"""<h3>Opération effectuée</h3>
|
f"""<h3>Opération effectuée</h3>
|
||||||
<ul><li><a class="stdlink" href="formsemestre_inscr_passage?formsemestre_id=%s">Continuer les inscriptions</a></li>
|
<ul>
|
||||||
<li><a class="stdlink" href="formsemestre_status?formsemestre_id=%s">Tableau de bord du semestre</a></li>"""
|
<li><a class="stdlink" href="{
|
||||||
% (formsemestre_id, formsemestre_id)
|
url_for("notes.formsemestre_inscr_passage",
|
||||||
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
|
||||||
|
}">Continuer les inscriptions</a>
|
||||||
|
</li>
|
||||||
|
<li><a class="stdlink" href="{
|
||||||
|
url_for("notes.formsemestre_status",
|
||||||
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
|
||||||
|
}">Tableau de bord du semestre</a>
|
||||||
|
</li>"""
|
||||||
)
|
)
|
||||||
partition = sco_groups.formsemestre_get_main_partition(formsemestre_id)
|
partition = sco_groups.formsemestre_get_main_partition(formsemestre_id)
|
||||||
if (
|
if (
|
||||||
@ -420,7 +427,7 @@ def formsemestre_inscr_passage(
|
|||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
def build_page(
|
def _build_page(
|
||||||
sem,
|
sem,
|
||||||
auth_etuds_by_sem,
|
auth_etuds_by_sem,
|
||||||
inscrits,
|
inscrits,
|
||||||
@ -429,6 +436,7 @@ def build_page(
|
|||||||
inscrit_groupes=False,
|
inscrit_groupes=False,
|
||||||
ignore_jury=False,
|
ignore_jury=False,
|
||||||
):
|
):
|
||||||
|
formsemestre: FormSemestre = FormSemestre.query.get(sem["formsemestre_id"])
|
||||||
inscrit_groupes = int(inscrit_groupes)
|
inscrit_groupes = int(inscrit_groupes)
|
||||||
ignore_jury = int(ignore_jury)
|
ignore_jury = int(ignore_jury)
|
||||||
if inscrit_groupes:
|
if inscrit_groupes:
|
||||||
@ -443,27 +451,36 @@ def build_page(
|
|||||||
html_sco_header.html_sem_header(
|
html_sco_header.html_sem_header(
|
||||||
"Passages dans le semestre", with_page_header=False
|
"Passages dans le semestre", with_page_header=False
|
||||||
),
|
),
|
||||||
"""<form name="f" method="post" action="%s">""" % request.base_url,
|
f"""<form name="f" method="post" action="{request.base_url}">
|
||||||
"""<input type="hidden" name="formsemestre_id" value="%(formsemestre_id)s"/>
|
|
||||||
|
<input type="hidden" name="formsemestre_id" value="{sem['formsemestre_id']}"/>
|
||||||
|
|
||||||
<input type="submit" name="submitted" value="Appliquer les modifications"/>
|
<input type="submit" name="submitted" value="Appliquer les modifications"/>
|
||||||
<a href="#help">aide</a>
|
<a href="#help">aide</a>
|
||||||
"""
|
|
||||||
% sem, # "
|
<input name="inscrit_groupes" type="checkbox" value="1"
|
||||||
"""<input name="inscrit_groupes" type="checkbox" value="1" %s>inscrire aux mêmes groupes</input>"""
|
{inscrit_groupes_checked}>inscrire aux mêmes groupes</input>
|
||||||
% inscrit_groupes_checked,
|
|
||||||
"""<input name="ignore_jury" type="checkbox" value="1" onchange="document.f.submit()" %s>inclure tous les étudiants (même sans décision de jury)</input>"""
|
<input name="ignore_jury" type="checkbox" value="1" onchange="document.f.submit()"
|
||||||
% ignore_jury_checked,
|
{ignore_jury_checked}>inclure tous les étudiants (même sans décision de jury)</input>
|
||||||
"""<div class="pas_recap">Actuellement <span id="nbinscrits">%s</span> inscrits
|
|
||||||
et %d candidats supplémentaires
|
<div class="pas_recap">Actuellement <span id="nbinscrits">{len(inscrits)}</span> inscrits
|
||||||
</div>"""
|
et {len(candidats_non_inscrits)} candidats supplémentaires
|
||||||
% (len(inscrits), len(candidats_non_inscrits)),
|
</div>
|
||||||
etuds_select_boxes(auth_etuds_by_sem, inscrits_ailleurs),
|
|
||||||
"""<p/><input type="submit" name="submitted" value="Appliquer les modifications"/>""",
|
<div>{scu.EMO_WARNING} <em>Seuls les semestres dont la date de fin est antérieure à la date de début
|
||||||
formsemestre_inscr_passage_help(sem),
|
de ce semestre ({formsemestre.date_debut.strftime("%d/%m/%Y")}) sont pris en compte.</em></div>
|
||||||
"""</form>""",
|
{etuds_select_boxes(auth_etuds_by_sem, inscrits_ailleurs)}
|
||||||
|
|
||||||
|
<input type="submit" name="submitted" value="Appliquer les modifications"/>
|
||||||
|
|
||||||
|
{formsemestre_inscr_passage_help(sem)}
|
||||||
|
|
||||||
|
</form>
|
||||||
|
""",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Semestres sans etudiants autorisés
|
# Semestres sans étudiants autorisés
|
||||||
empty_sems = []
|
empty_sems = []
|
||||||
for formsemestre_id in auth_etuds_by_sem.keys():
|
for formsemestre_id in auth_etuds_by_sem.keys():
|
||||||
if not auth_etuds_by_sem[formsemestre_id]["etuds"]:
|
if not auth_etuds_by_sem[formsemestre_id]["etuds"]:
|
||||||
@ -473,7 +490,10 @@ def build_page(
|
|||||||
"""<div class="pas_empty_sems"><h3>Autres semestres sans candidats :</h3><ul>"""
|
"""<div class="pas_empty_sems"><h3>Autres semestres sans candidats :</h3><ul>"""
|
||||||
)
|
)
|
||||||
for infos in empty_sems:
|
for infos in empty_sems:
|
||||||
H.append("""<li><a href="%(title_target)s">%(title)s</a></li>""" % infos)
|
H.append(
|
||||||
|
"""<li><a class="stdlink" href="%(title_target)s">%(title)s</a></li>"""
|
||||||
|
% infos
|
||||||
|
)
|
||||||
H.append("""</ul></div>""")
|
H.append("""</ul></div>""")
|
||||||
|
|
||||||
return H
|
return H
|
||||||
|
@ -544,7 +544,9 @@ def _ligne_evaluation(
|
|||||||
if not first_eval:
|
if not first_eval:
|
||||||
H.append("""<tr><td colspan="8"> </td></tr>""")
|
H.append("""<tr><td colspan="8"> </td></tr>""")
|
||||||
tr_class_1 += " mievr_spaced"
|
tr_class_1 += " mievr_spaced"
|
||||||
H.append(f"""<tr class="{tr_class_1}"><td class="mievr_tit" colspan="8">""")
|
H.append(
|
||||||
|
f"""<tr class="{tr_class_1} mievr_tit"><td class="mievr_tit" colspan="8">"""
|
||||||
|
)
|
||||||
coef = evaluation.coefficient
|
coef = evaluation.coefficient
|
||||||
if is_apc:
|
if is_apc:
|
||||||
if not evaluation.get_ue_poids_dict():
|
if not evaluation.get_ue_poids_dict():
|
||||||
@ -588,7 +590,9 @@ def _ligne_evaluation(
|
|||||||
)
|
)
|
||||||
#
|
#
|
||||||
H.append(
|
H.append(
|
||||||
f"""<div class="evaluation_order">
|
f"""
|
||||||
|
</td>
|
||||||
|
<td class="evaluation_order">
|
||||||
<span class="evalindex" title="Indice dans les vecteurs (formules)">{
|
<span class="evalindex" title="Indice dans les vecteurs (formules)">{
|
||||||
eval_index:2}</span>
|
eval_index:2}</span>
|
||||||
<span class="eval_arrows_chld">
|
<span class="eval_arrows_chld">
|
||||||
@ -612,20 +616,6 @@ def _ligne_evaluation(
|
|||||||
else:
|
else:
|
||||||
H.append(arrow_none)
|
H.append(arrow_none)
|
||||||
|
|
||||||
H.append(
|
|
||||||
f"""</span></span></td>
|
|
||||||
</div>
|
|
||||||
</tr>
|
|
||||||
<tr class="{tr_class}">
|
|
||||||
<th class="moduleimpl_evaluations" colspan="2"> </th>
|
|
||||||
<th class="moduleimpl_evaluations">Durée</th>
|
|
||||||
<th class="moduleimpl_evaluations">Coef.</th>
|
|
||||||
<th class="moduleimpl_evaluations">Notes</th>
|
|
||||||
<th class="moduleimpl_evaluations">Abs</th>
|
|
||||||
<th class="moduleimpl_evaluations">N</th>
|
|
||||||
<th class="moduleimpl_evaluations">Moyenne """
|
|
||||||
)
|
|
||||||
|
|
||||||
if etat["evalcomplete"]:
|
if etat["evalcomplete"]:
|
||||||
etat_txt = """(prise en compte)"""
|
etat_txt = """(prise en compte)"""
|
||||||
etat_descr = "notes utilisées dans les moyennes"
|
etat_descr = "notes utilisées dans les moyennes"
|
||||||
@ -648,9 +638,19 @@ def _ligne_evaluation(
|
|||||||
}" title="{etat_descr}">{etat_txt}</a>"""
|
}" title="{etat_descr}">{etat_txt}</a>"""
|
||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
f"""{etat_txt}</th>
|
f"""</span></span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="{tr_class}"><td class="mievr">"""
|
<tr class="{tr_class}">
|
||||||
|
<th class="moduleimpl_evaluations" colspan="2"> </th>
|
||||||
|
<th class="moduleimpl_evaluations">Durée</th>
|
||||||
|
<th class="moduleimpl_evaluations">Coef.</th>
|
||||||
|
<th class="moduleimpl_evaluations">Notes</th>
|
||||||
|
<th class="moduleimpl_evaluations">Abs</th>
|
||||||
|
<th class="moduleimpl_evaluations">N</th>
|
||||||
|
<th class="moduleimpl_evaluations" colspan="2">Moyenne {etat_txt}</th>
|
||||||
|
</tr>
|
||||||
|
<tr class="{tr_class}">
|
||||||
|
<td class="mievr">"""
|
||||||
)
|
)
|
||||||
if can_edit_evals:
|
if can_edit_evals:
|
||||||
H.append(
|
H.append(
|
||||||
@ -726,7 +726,7 @@ def _ligne_evaluation(
|
|||||||
<td class="rightcell mievr_nbnotes">{etat["nb_notes"]} / {etat["nb_inscrits"]}</td>
|
<td class="rightcell mievr_nbnotes">{etat["nb_notes"]} / {etat["nb_inscrits"]}</td>
|
||||||
<td class="rightcell mievr_coef">{etat["nb_abs"]}</td>
|
<td class="rightcell mievr_coef">{etat["nb_abs"]}</td>
|
||||||
<td class="rightcell mievr_coef">{etat["nb_neutre"]}</td>
|
<td class="rightcell mievr_coef">{etat["nb_neutre"]}</td>
|
||||||
<td class="rightcell">"""
|
<td class="rightcell" colspan="2">"""
|
||||||
% etat
|
% etat
|
||||||
)
|
)
|
||||||
if etat["moy"]:
|
if etat["moy"]:
|
||||||
@ -750,11 +750,11 @@ def _ligne_evaluation(
|
|||||||
H.append(f"""<tr class="{tr_class}"><td></td>""")
|
H.append(f"""<tr class="{tr_class}"><td></td>""")
|
||||||
if modimpl.module.is_apc():
|
if modimpl.module.is_apc():
|
||||||
H.append(
|
H.append(
|
||||||
f"""<td colspan="7" class="eval_poids">{
|
f"""<td colspan="8" class="eval_poids">{
|
||||||
evaluation.get_ue_poids_str()}</td>"""
|
evaluation.get_ue_poids_str()}</td>"""
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
H.append('<td colspan="7"></td>')
|
H.append('<td colspan="8"></td>')
|
||||||
H.append("""</tr>""")
|
H.append("""</tr>""")
|
||||||
else: # il y a deja des notes saisies
|
else: # il y a deja des notes saisies
|
||||||
gr_moyennes = etat["gr_moyennes"]
|
gr_moyennes = etat["gr_moyennes"]
|
||||||
@ -773,7 +773,10 @@ def _ligne_evaluation(
|
|||||||
name = "Tous" # tous
|
name = "Tous" # tous
|
||||||
else:
|
else:
|
||||||
name = f"""Groupe {gr_moyenne["group_name"]}"""
|
name = f"""Groupe {gr_moyenne["group_name"]}"""
|
||||||
H.append(f"""<td colspan="2" class="mievr_grtit">{name} </td><td>""")
|
H.append(
|
||||||
|
f"""<td colspan="2" class="mievr_grtit">{name} </td>
|
||||||
|
<td colspan="2">"""
|
||||||
|
)
|
||||||
if gr_moyenne["gr_nb_notes"] > 0:
|
if gr_moyenne["gr_nb_notes"] > 0:
|
||||||
H.append(
|
H.append(
|
||||||
f"""{gr_moyenne["gr_moy"]} (<a href="{
|
f"""{gr_moyenne["gr_moy"]} (<a href="{
|
||||||
|
@ -200,7 +200,7 @@ def etud_photo_html(etud: dict = None, etudid=None, title=None, size="small") ->
|
|||||||
return abort(404, "etudiant inconnu")
|
return abort(404, "etudiant inconnu")
|
||||||
etud = etuds[0]
|
etud = etuds[0]
|
||||||
else:
|
else:
|
||||||
raise ValueError("etud_photo_html: either etud or etudid must be specified")
|
abort(404, "etud_photo_html: either etud or etudid must be specified")
|
||||||
photo_url = etud_photo_url(etud, size=size)
|
photo_url = etud_photo_url(etud, size=size)
|
||||||
nom = etud.get("nomprenom", etud["nom_disp"])
|
nom = etud.get("nomprenom", etud["nom_disp"])
|
||||||
if title is None:
|
if title is None:
|
||||||
@ -244,7 +244,7 @@ def photo_pathname(photo_filename: str, size="orig"):
|
|||||||
elif size == "orig":
|
elif size == "orig":
|
||||||
version = ""
|
version = ""
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid size parameter for photo")
|
abort(404, "invalid size parameter for photo")
|
||||||
if not photo_filename:
|
if not photo_filename:
|
||||||
return False
|
return False
|
||||||
path = os.path.join(PHOTO_DIR, photo_filename) + version + IMAGE_EXT
|
path = os.path.join(PHOTO_DIR, photo_filename) + version + IMAGE_EXT
|
||||||
|
@ -1309,7 +1309,7 @@ def _form_saisie_notes(E, M, groups_infos, destination=""):
|
|||||||
H = []
|
H = []
|
||||||
if nb_decisions > 0:
|
if nb_decisions > 0:
|
||||||
H.append(
|
H.append(
|
||||||
"""<div class="saisie_warn">
|
f"""<div class="saisie_warn">
|
||||||
<ul class="tf-msg">
|
<ul class="tf-msg">
|
||||||
<li class="tf-msg">Attention: il y a déjà des <b>décisions de jury</b> enregistrées pour
|
<li class="tf-msg">Attention: il y a déjà des <b>décisions de jury</b> enregistrées pour
|
||||||
{nb_decisions} étudiants. Après changement des notes, vérifiez la situation !</li>
|
{nb_decisions} étudiants. Après changement des notes, vérifiez la situation !</li>
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
/* Saisie décision de jury BUT */
|
/* Saisie décision de jury BUT */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--color-recorded: rgb(3, 157, 3);
|
||||||
|
--color-explanation: blueviolet;
|
||||||
|
}
|
||||||
|
|
||||||
.jury_but {
|
.jury_but {
|
||||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
}
|
}
|
||||||
@ -18,6 +23,19 @@
|
|||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form#jury_but {
|
||||||
|
margin: 0px 16px 16px 16px;
|
||||||
|
background-color: rgb(253, 253, 231);
|
||||||
|
border: 2px solid rgb(4, 4, 118);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
min-width: var(--sco-content-min-width);
|
||||||
|
max-width: var(--sco-content-max-width);
|
||||||
|
}
|
||||||
|
|
||||||
.but_annee {
|
.but_annee {
|
||||||
margin-left: 32px;
|
margin-left: 32px;
|
||||||
display: inline-grid;
|
display: inline-grid;
|
||||||
@ -112,11 +130,10 @@ div.but_settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.but_explanation {
|
.but_explanation {
|
||||||
color: blueviolet;
|
color: var(--color-explanation);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select:disabled {
|
select:disabled {
|
||||||
@ -130,7 +147,7 @@ select:invalid {
|
|||||||
|
|
||||||
select.but_code option.recorded,
|
select.but_code option.recorded,
|
||||||
div.but_code recorded {
|
div.but_code recorded {
|
||||||
color: rgb(3, 157, 3);
|
color: var(--color-recorded);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,14 +160,14 @@ div.but_code {
|
|||||||
|
|
||||||
div.but_niveau_ue.recorded,
|
div.but_niveau_ue.recorded,
|
||||||
div.but_niveau_rcue.recorded {
|
div.but_niveau_rcue.recorded {
|
||||||
border-color: rgb(0, 169, 0);
|
border-color: var(--color-recorded);
|
||||||
border-width: 3px;
|
border-width: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.but_niveau_ue.recorded_different,
|
div.but_niveau_ue.recorded_different,
|
||||||
div.but_niveau_rcue.recorded_different {
|
div.but_niveau_rcue.recorded_different {
|
||||||
box-shadow: 0 0 0 3px red;
|
box-shadow: 0 0 0 3px red;
|
||||||
outline: dashed 3px rgb(0, 169, 0);
|
outline: dashed 3px var(--color-recorded);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.but_niveau_ue.annee_prec {
|
div.but_niveau_ue.annee_prec {
|
||||||
@ -172,8 +189,16 @@ div.but_buttons span {
|
|||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.but_doc_codes.but_warning_rcue_cap {
|
||||||
|
padding-top: 8px;
|
||||||
|
font-size: 100%;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
div.but_doc_codes {
|
div.but_doc_codes {
|
||||||
margin: 16px;
|
margin: 16px;
|
||||||
|
min-width: var(--sco-content-min-width);
|
||||||
|
max-width: var(--sco-content-max-width);
|
||||||
background-color: rgb(227, 254, 254);
|
background-color: rgb(227, 254, 254);
|
||||||
font-size: 75%;
|
font-size: 75%;
|
||||||
border: 2px solid rgb(4, 4, 118);
|
border: 2px solid rgb(4, 4, 118);
|
||||||
@ -228,3 +253,15 @@ div.but_doc table tr td.amue {
|
|||||||
.but_niveau_rcue .scoplement {
|
.but_niveau_rcue .scoplement {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.but_autorisations_passage {
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-left: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--color-recorded);
|
||||||
|
}
|
||||||
|
|
||||||
|
.but_autorisations_passage.but_explanation {
|
||||||
|
font-weight: normal;
|
||||||
|
color: var(--color-explanation);
|
||||||
|
}
|
@ -1,7 +1,11 @@
|
|||||||
/* # -*- mode: css -*-
|
/* ScoDoc, (c) Emmanuel Viennet 1998 - 2023
|
||||||
ScoDoc, (c) Emmanuel Viennet 1998 - 2021
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--sco-content-min-width: 600px;
|
||||||
|
--sco-content-max-width: 1024px;
|
||||||
|
}
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -1657,6 +1661,11 @@ td.formsemestre_status_inscrits {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td.rcp_titre_sem a.jury_link {
|
||||||
|
margin-left: 8px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
td.formsemestre_status_cell {
|
td.formsemestre_status_cell {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -1728,6 +1737,8 @@ ul.ue_inscr_list li.etud {
|
|||||||
div.moduleimpl_tableaubord {
|
div.moduleimpl_tableaubord {
|
||||||
padding: 7px;
|
padding: 7px;
|
||||||
border: 2px solid gray;
|
border: 2px solid gray;
|
||||||
|
min-width: var(--sco-content-min-width);
|
||||||
|
max-width: var(--sco-content-max-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.moduleimpl_type_sae {
|
div.moduleimpl_type_sae {
|
||||||
@ -1855,11 +1866,19 @@ span.mievr_rattr {
|
|||||||
padding: 1px 3px 1px 3px;
|
padding: 1px 3px 1px 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.mievr td.mievr_tit {
|
tr.mievr_tit td.mievr_tit {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
background-color: #cccccc;
|
|
||||||
border-top-left-radius: 8px;
|
border-top-left-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.mievr.mievr_tit td {
|
||||||
|
background-color: #e1e1e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.mievr_tit td:last-child {
|
||||||
border-top-right-radius: 8px;
|
border-top-right-radius: 8px;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.mievr td {
|
tr.mievr td {
|
||||||
@ -1922,11 +1941,6 @@ span.eval_warning_coef {
|
|||||||
background-color: rgb(255, 225, 0);
|
background-color: rgb(255, 225, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.evaluation_order {
|
|
||||||
position: absolute;
|
|
||||||
right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.evalindex {
|
span.evalindex {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
@ -2580,11 +2594,13 @@ div.bull_head {
|
|||||||
display: grid;
|
display: grid;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
grid-template-columns: auto auto;
|
grid-template-columns: auto auto;
|
||||||
|
min-width: 600px;
|
||||||
|
max-width: 1072px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.bull_photo {
|
div.bull_photo {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 10px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.bulletin_menubar_but {
|
span.bulletin_menubar_but {
|
||||||
|
@ -78,7 +78,10 @@ $(function () {
|
|||||||
} else {
|
} else {
|
||||||
document.querySelector("div.next").innerHTML = "";
|
document.querySelector("div.next").innerHTML = "";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Supprime les liens de navigation
|
||||||
|
document.querySelector("div.prev").innerHTML = "";
|
||||||
|
document.querySelector("div.next").innerHTML = "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -262,10 +262,11 @@
|
|||||||
<b>Textes de référence:</b>
|
<b>Textes de référence:</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://www.enseignementsup-recherche.gouv.fr/fr/bo/21/Special4/ESRS2114777A.htm">Bulletin
|
<li><a href="https://www.enseignementsup-recherche.gouv.fr/fr/bo/21/Special4/ESRS2114777A.htm">Bulletin
|
||||||
officiel spécial n°4 du 17 juin 2021</a></li>
|
officiel spécial n°4 du 26 mai 2022 </a></li>
|
||||||
<li><a
|
<li><a
|
||||||
href="https://cache.media.enseignementsup-recherche.gouv.fr//file/SPE4-MESRI-17-6-2021/19/4/SP4_ESR_17_6_2021_1413194.pdf">Version
|
href="https://cache.media.education.gouv.fr/file/SP4-MESRI-26-5-2022/10/0/spe617_annexe1_1426100.pdf">Version
|
||||||
pdf complète</a></li>
|
pdf de l'arrêté de mai 2022 sur la licence professionnelle « bachelor universitaire de technologie
|
||||||
|
»</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,7 +49,8 @@
|
|||||||
<span class="formation_module_ue">(<a title="UE de rattachement">{{mod.ue.acronyme}}</a>)</span>,
|
<span class="formation_module_ue">(<a title="UE de rattachement">{{mod.ue.acronyme}}</a>)</span>,
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
parcours <b>{{ mod.get_parcours()|map(attribute="code")|join("</b>, <b>")|default('tronc commun', true)|safe
|
- parcours <b>{{ mod.get_parcours()|map(attribute="code")|join("</b>, <b>")|default('tronc commun',
|
||||||
|
true)|safe
|
||||||
}}</b>
|
}}</b>
|
||||||
{% if mod.heures_cours or mod.heures_td or mod.heures_tp %}
|
{% if mod.heures_cours or mod.heures_td or mod.heures_tp %}
|
||||||
({{mod.heures_cours|default(" ",true)|safe}}/{{mod.heures_td|default(" ",true)|safe}}/{{mod.heures_tp|default(" ",true)|safe}},
|
({{mod.heures_cours|default(" ",true)|safe}}/{{mod.heures_td|default(" ",true)|safe}}/{{mod.heures_tp|default(" ",true)|safe}},
|
@ -704,10 +704,15 @@ def formation_list(format=None, formation_id=None, args={}):
|
|||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
@scodoc7func
|
@scodoc7func
|
||||||
def formation_export(formation_id, export_ids=False, format=None):
|
def formation_export(
|
||||||
|
formation_id, export_ids=False, format=None, export_codes_apo=True
|
||||||
|
):
|
||||||
"Export de la formation au format indiqué (xml ou json)"
|
"Export de la formation au format indiqué (xml ou json)"
|
||||||
return sco_formations.formation_export(
|
return sco_formations.formation_export(
|
||||||
formation_id, export_ids=export_ids, format=format
|
formation_id,
|
||||||
|
export_ids=export_ids,
|
||||||
|
format=format,
|
||||||
|
export_codes_apo=export_codes_apo,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -2494,11 +2499,31 @@ def formsemestre_validation_but(
|
|||||||
|
|
||||||
H.append(jury_but_view.show_etud(deca, read_only=read_only))
|
H.append(jury_but_view.show_etud(deca, read_only=read_only))
|
||||||
|
|
||||||
|
autorisations_idx = deca.get_autorisations_passage()
|
||||||
|
div_autorisations_passage = (
|
||||||
|
f"""
|
||||||
|
<div class="but_autorisations_passage">
|
||||||
|
<span>Autorisé à passer en :</span>
|
||||||
|
{ ", ".join( ["S" + str(i) for i in autorisations_idx ] )}
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
if autorisations_idx
|
||||||
|
else """<div class="but_autorisations_passage but_explanation">
|
||||||
|
pas d'autorisations de passage enregistrées.
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
H.append(div_autorisations_passage)
|
||||||
|
|
||||||
if read_only:
|
if read_only:
|
||||||
H.append(
|
H.append(
|
||||||
"""<div class="but_explanation">
|
f"""
|
||||||
Vous n'avez pas la permission de modifier ces décisions.
|
<div class="but_explanation">
|
||||||
Les champs entourés en vert sont enregistrés.</div>"""
|
{"Vous n'avez pas la permission de modifier ces décisions."
|
||||||
|
if formsemestre.etat
|
||||||
|
else "Semestre verrouillé."}
|
||||||
|
Les champs entourés en vert sont enregistrés.
|
||||||
|
</div>"""
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
erase_span = f"""<a href="{
|
erase_span = f"""<a href="{
|
||||||
@ -2508,9 +2533,11 @@ def formsemestre_validation_but(
|
|||||||
H.append(
|
H.append(
|
||||||
f"""<div class="but_settings">
|
f"""<div class="but_settings">
|
||||||
<input type="checkbox" onchange="enable_manual_codes(this)">
|
<input type="checkbox" onchange="enable_manual_codes(this)">
|
||||||
<em>permettre la saisie manuelles des codes d'année et de niveaux.
|
<em>permettre la saisie manuelles des codes
|
||||||
Dans ce cas, il vous revient de vous assurer de la cohérence entre
|
{"d'année et " if deca.jury_annuel else ""}
|
||||||
vos codes d'UE/RCUE/Année !</em>
|
de niveaux.
|
||||||
|
Dans ce cas, assurez-vous de la cohérence entre les codes d'UE/RCUE/Année !
|
||||||
|
</em>
|
||||||
</input>
|
</input>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -2522,7 +2549,15 @@ def formsemestre_validation_but(
|
|||||||
)
|
)
|
||||||
H.append(navigation_div)
|
H.append(navigation_div)
|
||||||
H.append("</form>")
|
H.append("</form>")
|
||||||
|
if deca.a_cheval:
|
||||||
|
H.append(
|
||||||
|
f"""<div class="but_doc_codes but_warning_rcue_cap">
|
||||||
|
{scu.EMO_WARNING} Rappel: pour les redoublants, seules les UE <b>capitalisées</b> (note > 10)
|
||||||
|
lors d'une année précédente peuvent être prise en compte pour former
|
||||||
|
un RCUE (associé à un niveau de compétence du BUT).
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
)
|
||||||
H.append(
|
H.append(
|
||||||
render_template(
|
render_template(
|
||||||
"but/documentation_codes_jury.html",
|
"but/documentation_codes_jury.html",
|
||||||
|
@ -216,7 +216,7 @@ def edit_modules_ue_coefs():
|
|||||||
</h2>
|
</h2>
|
||||||
""",
|
""",
|
||||||
render_template(
|
render_template(
|
||||||
"pn/form_modules_ue_coefs.html",
|
"pn/form_modules_ue_coefs.j2",
|
||||||
formation=formation,
|
formation=formation,
|
||||||
data_source=url_for(
|
data_source=url_for(
|
||||||
"notes.table_modules_ue_coefs",
|
"notes.table_modules_ue_coefs",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.4.31"
|
SCOVERSION = "9.4.32"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ from app.models import GroupDescr
|
|||||||
from app.models import Identite
|
from app.models import Identite
|
||||||
from app.models import ModuleImpl, ModuleImplInscription
|
from app.models import ModuleImpl, ModuleImplInscription
|
||||||
from app.models import Partition
|
from app.models import Partition
|
||||||
from app.models import ScolarFormSemestreValidation
|
from app.models import ScolarAutorisationInscription, ScolarFormSemestreValidation
|
||||||
from app.models.but_refcomp import (
|
from app.models.but_refcomp import (
|
||||||
ApcCompetence,
|
ApcCompetence,
|
||||||
ApcNiveau,
|
ApcNiveau,
|
||||||
@ -101,6 +101,7 @@ def make_shell_context():
|
|||||||
"ResultatsSemestreBUT": ResultatsSemestreBUT,
|
"ResultatsSemestreBUT": ResultatsSemestreBUT,
|
||||||
"Role": Role,
|
"Role": Role,
|
||||||
"scolar": scolar,
|
"scolar": scolar,
|
||||||
|
"ScolarAutorisationInscription": ScolarAutorisationInscription,
|
||||||
"ScolarFormSemestreValidation": ScolarFormSemestreValidation,
|
"ScolarFormSemestreValidation": ScolarFormSemestreValidation,
|
||||||
"ScolarNews": models.ScolarNews,
|
"ScolarNews": models.ScolarNews,
|
||||||
"scu": scu,
|
"scu": scu,
|
||||||
|
@ -1022,3 +1022,84 @@ Etudiants:
|
|||||||
moy_ue: 9.5000
|
moy_ue: 9.5000
|
||||||
moy_ue_with_cap: 12.7600
|
moy_ue_with_cap: 12.7600
|
||||||
decision_annee: AJ
|
decision_annee: AJ
|
||||||
|
geii1000:
|
||||||
|
prenom: etugeii1000
|
||||||
|
civilite: M
|
||||||
|
formsemestres:
|
||||||
|
S1:
|
||||||
|
notes_modules: # on joue avec les SAE seulement car elles sont "diagonales"
|
||||||
|
"S1.1": 12.0000
|
||||||
|
"S1.2": 9.0000
|
||||||
|
attendu: # les codes jury que l'on doit vérifier
|
||||||
|
deca:
|
||||||
|
passage_de_droit: False
|
||||||
|
nb_competences: 2
|
||||||
|
nb_rcue_annee: 0
|
||||||
|
decisions_ues:
|
||||||
|
"UE11":
|
||||||
|
codes: [ "ADM", "..." ]
|
||||||
|
code_valide: ADM
|
||||||
|
moy_ue: 12.0000
|
||||||
|
"UE12":
|
||||||
|
codes: [ "AJ", "..." ]
|
||||||
|
code_valide: AJ
|
||||||
|
decision_jury: AJ
|
||||||
|
moy_ue: 9.0000
|
||||||
|
S2:
|
||||||
|
notes_modules: # on joue avec les SAE seulement car elles sont "diagonales"
|
||||||
|
"S2.1": 12.0000
|
||||||
|
"S2.2": 10.50 # capitalise mais ne compense pas
|
||||||
|
attendu: # les codes jury que l'on doit vérifier
|
||||||
|
deca:
|
||||||
|
passage_de_droit: False
|
||||||
|
nb_competences: 2
|
||||||
|
nb_rcue_annee: 2
|
||||||
|
valide_moitie_rcue: False
|
||||||
|
codes: [ "RED", "..." ]
|
||||||
|
decisions_ues:
|
||||||
|
"UE21":
|
||||||
|
codes: [ "ADM", "..." ]
|
||||||
|
code_valide: ADM
|
||||||
|
moy_ue: 12.0000
|
||||||
|
"UE22":
|
||||||
|
code_valide: ADM
|
||||||
|
moy_ue: 10.5
|
||||||
|
decisions_rcues: # on repère ici les RCUE par l'acronyme de leur 1ere UE (donc du S1)
|
||||||
|
"UE11":
|
||||||
|
code_valide: ADM
|
||||||
|
decision_jury: ADM
|
||||||
|
rcue:
|
||||||
|
moy_rcue: 12.0000
|
||||||
|
est_compensable: False
|
||||||
|
"UE12":
|
||||||
|
code_valide: AJ
|
||||||
|
decision_jury: AJ
|
||||||
|
rcue:
|
||||||
|
moy_rcue: 9.75
|
||||||
|
est_compensable: False
|
||||||
|
decision_annee: RED
|
||||||
|
S1-red:
|
||||||
|
notes_modules: # on joue avec les SAE seulement car elles sont "diagonales"
|
||||||
|
"S1.1": 5.0000
|
||||||
|
"S1.2": 12.0000
|
||||||
|
attendu: # les codes jury que l'on doit vérifier
|
||||||
|
deca:
|
||||||
|
passage_de_droit: False
|
||||||
|
nb_competences: 2
|
||||||
|
nb_rcue_annee: 0
|
||||||
|
decisions_ues:
|
||||||
|
"UE11":
|
||||||
|
code_valide: AJ
|
||||||
|
moy_ue: 5. # LA MOYENNE COURANTE
|
||||||
|
moy_ue_with_cap: 12.0000
|
||||||
|
"UE12":
|
||||||
|
code_valide: ADM
|
||||||
|
decision_jury: ADM
|
||||||
|
moy_ue: 12.0000
|
||||||
|
# RCUE inter-annuel
|
||||||
|
decisions_rcues: # on repère ici les RCUE par l'acronyme de leur 1ere UE (donc du S1)
|
||||||
|
"UE12":
|
||||||
|
code_valide: ADM
|
||||||
|
rcue:
|
||||||
|
moy_rcue: 11.25
|
||||||
|
est_compensable: False
|
||||||
|
@ -33,7 +33,7 @@ DEPT = TestConfig.DEPT_TEST
|
|||||||
@pytest.mark.but_gb
|
@pytest.mark.but_gb
|
||||||
def test_but_jury_GB(test_client):
|
def test_but_jury_GB(test_client):
|
||||||
"""Tests sur un cursus GB
|
"""Tests sur un cursus GB
|
||||||
- construction des semestres et de leurs étudianst à partir du yaml
|
- construction des semestres et de leurs étudiants à partir du yaml
|
||||||
- vérification jury de S1
|
- vérification jury de S1
|
||||||
- vérification jury de S2
|
- vérification jury de S2
|
||||||
- vérification jury de S3
|
- vérification jury de S3
|
||||||
@ -96,7 +96,6 @@ def test_but_jury_GEII_lyon(test_client):
|
|||||||
# Construit la base de test GB une seule fois
|
# Construit la base de test GB une seule fois
|
||||||
# puis lance les tests de jury
|
# puis lance les tests de jury
|
||||||
doc = yaml_setup.setup_from_yaml("tests/unit/cursus_but_geii_lyon.yaml")
|
doc = yaml_setup.setup_from_yaml("tests/unit/cursus_but_geii_lyon.yaml")
|
||||||
|
|
||||||
formsemestres = FormSemestre.query.order_by(
|
formsemestres = FormSemestre.query.order_by(
|
||||||
FormSemestre.date_debut, FormSemestre.semestre_id
|
FormSemestre.date_debut, FormSemestre.semestre_id
|
||||||
).all()
|
).all()
|
||||||
|
Loading…
Reference in New Issue
Block a user