ScoDoc/app/views/refcomp.py

200 lines
6.6 KiB
Python

"""
PN / Référentiel de compétences
Emmanuel Viennet, 2021
"""
from flask import url_for, flash
from flask import jsonify
from flask import current_app, g, request
from flask.templating import render_template
from flask_login import current_user
from werkzeug.utils import redirect
from werkzeug.utils import secure_filename
from config import Config
from app import db
from app import models
from app.decorators import scodoc, permission_required
from app.models.formations import Formation
from app.models.but_refcomp import ApcReferentielCompetences
from app.but.import_refcomp import orebut_import_refcomp
from app.but.forms.refcomp_forms import FormationRefCompForm, RefCompLoadForm
from app.scodoc.gen_tables import GenTable
from app.scodoc import html_sidebar
from app.scodoc import sco_utils as scu
from app.scodoc.sco_exceptions import ScoFormatError
from app.scodoc.sco_permissions import Permission
from app.views import notes_bp as bp
from app.views import ScoData
@bp.route("/referentiel/comp/get/<int:refcomp_id>")
@scodoc
@permission_required(Permission.ScoView)
def refcomp(refcomp_id):
ref = ApcReferentielCompetences.query.get_or_404(refcomp_id)
return jsonify(ref.to_dict())
@bp.route("/referentiel/comp/show/<int:refcomp_id>")
@scodoc
@permission_required(Permission.ScoView)
def refcomp_show(refcomp_id):
ref = ApcReferentielCompetences.query.get_or_404(refcomp_id)
return render_template(
"but/refcomp_show.html",
ref=ref,
title="Référentiel de compétences",
sco=ScoData(),
)
@bp.route("/referentiel/comp/delete/<int:refcomp_id>", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoChangeFormation)
def refcomp_delete(refcomp_id):
ref = ApcReferentielCompetences.query.get_or_404(refcomp_id)
db.session.delete(ref)
db.session.commit()
flash("référentiel de compétences supprimé")
return redirect(url_for("notes.refcomp_table", scodoc_dept=g.scodoc_dept))
@bp.route("/referentiel/comp/table")
@scodoc
@permission_required(Permission.ScoView)
def refcomp_table():
"""Liste html des ref. comp. chargés dans ce département"""
refs = ApcReferentielCompetences.query.filter_by(dept_id=g.scodoc_dept_id)
columns_ids = ("type_titre", "specialite_long", "json", "nb_formations")
if current_user.has_permission(Permission.ScoChangeFormation):
columns_ids = ("suppr",) + columns_ids
suppr_icon = scu.icontag(
"delete_small_img", border="0", alt="supprimer", title="Supprimer"
)
tab = GenTable(
columns_ids=columns_ids,
titles={
"suppr": "",
"type_titre": "Type",
"specialite_long": "Spécialité",
"json": "Export",
"nb_formations": "Formations",
},
rows=[
{
"type_titre": ref.type_titre,
"specialite_long": ref.specialite_long,
"_specialite_long_target": url_for(
"notes.refcomp_show", scodoc_dept=g.scodoc_dept, refcomp_id=ref.id
),
"json": "json",
"_json_target": url_for(
"notes.refcomp", scodoc_dept=g.scodoc_dept, refcomp_id=ref.id
),
"nb_formations": len(ref.formations),
"suppr": suppr_icon,
"_suppr_target": url_for(
"notes.refcomp_delete", scodoc_dept=g.scodoc_dept, refcomp_id=ref.id
),
}
for ref in refs
],
)
return render_template(
"but/refcomp_table.html",
tab=tab,
title="Référentiels de compétences",
sco=ScoData(),
)
@bp.route(
"/referentiel/comp/assoc_formation/<int:formation_id>", methods=["GET", "POST"]
)
@scodoc
@permission_required(Permission.ScoChangeFormation)
def refcomp_assoc_formation(formation_id: int):
"""Formulaire association ref. compétence"""
formation = Formation.query.get_or_404(formation_id)
form = FormationRefCompForm()
form.referentiel_competence.choices = [
(r.id, f"{r.type_titre} {r.specialite_long}")
for r in ApcReferentielCompetences.query.filter_by(dept_id=g.scodoc_dept_id)
]
if request.method == "POST" and form.cancel.data: # cancel button
return redirect(
url_for(
"notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formation_id
)
)
if form.validate_on_submit():
referentiel_competence_id = form.referentiel_competence.data
assert (
ApcReferentielCompetences.query.get(referentiel_competence_id) is not None
)
formation.referentiel_competence_id = referentiel_competence_id
db.session.add(formation)
db.session.commit()
flash("nouveau référentiel de compétences associé")
return redirect(
url_for(
"notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formation_id
)
)
return render_template(
"but/refcomp_assoc.html",
form=form,
referentiel_competence_id=formation.referentiel_competence_id,
formation=formation,
title="Association réf. compétences",
)
@bp.route(
"/referentiel/comp/load", defaults={"formation_id": None}, methods=["GET", "POST"]
)
@bp.route("/referentiel/comp/load/<int:formation_id>", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoChangeFormation)
def refcomp_load(formation_id=None):
"""Formulaire association ref. compétence"""
if formation_id is not None:
formation = Formation.query.get_or_404(formation_id)
else:
formation = None
form = RefCompLoadForm()
if form.validate_on_submit():
f = form.upload.data
filename = secure_filename(f.filename)
try:
xml_data = f.read()
ref = orebut_import_refcomp(
xml_data, dept_id=g.scodoc_dept_id, orig_filename=filename
)
except TypeError as exc:
raise ScoFormatError("fichier XML Orébut invalide") from exc
except ScoFormatError:
raise
if formation is not None:
return redirect(
url_for(
"notes.refcomp_assoc_formation",
scodoc_dept=g.scodoc_dept,
formation_id=formation.formation_id,
)
)
else:
return redirect(url_for("notes.index_html", scodoc_dept=g.scodoc_dept))
return render_template(
"but/refcomp_load.html",
form=form,
formation=formation,
title="Chargement réf. compétences",
)