Améliore import/export formations APC.
This commit is contained in:
parent
f46e3f6db5
commit
4d0ea06559
@ -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(
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user