2020-09-26 16:19:37 +02:00
|
|
|
# -*- mode: python -*-
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
#
|
|
|
|
# Gestion scolarite IUT
|
|
|
|
#
|
2023-12-31 23:04:06 +01:00
|
|
|
# Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved.
|
2020-09-26 16:19:37 +02:00
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
#
|
|
|
|
# Emmanuel Viennet emmanuel.viennet@viennet.net
|
|
|
|
#
|
|
|
|
##############################################################################
|
|
|
|
|
2024-10-11 14:06:02 +02:00
|
|
|
"""Ajout/Modification/Suppression matieres
|
2020-09-26 16:19:37 +02:00
|
|
|
"""
|
2021-08-01 10:16:16 +02:00
|
|
|
import flask
|
2024-10-11 14:06:02 +02:00
|
|
|
from flask import flash, g, render_template, request, url_for
|
2023-07-11 06:57:38 +02:00
|
|
|
|
|
|
|
from app import db, log
|
2024-10-11 14:06:02 +02:00
|
|
|
from app.models import Matiere, UniteEns
|
2021-08-01 10:16:16 +02:00
|
|
|
|
2021-06-19 23:21:37 +02:00
|
|
|
import app.scodoc.sco_utils as scu
|
2023-07-11 06:57:38 +02:00
|
|
|
|
2021-06-19 23:21:37 +02:00
|
|
|
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
2022-01-04 20:03:38 +01:00
|
|
|
from app.scodoc.sco_exceptions import (
|
|
|
|
ScoValueError,
|
|
|
|
ScoLockedFormError,
|
|
|
|
ScoNonEmptyFormationObject,
|
|
|
|
)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
2021-09-27 10:20:10 +02:00
|
|
|
def matiere_create(ue_id=None):
|
2024-10-11 14:06:02 +02:00
|
|
|
"""Formulaire création d'une matiere"""
|
2023-07-10 14:32:16 +02:00
|
|
|
ue: UniteEns = UniteEns.query.get_or_404(ue_id)
|
|
|
|
default_numero = max([mat.numero for mat in ue.matieres] or [9]) + 1
|
2020-09-26 16:19:37 +02:00
|
|
|
H = [
|
2024-02-13 13:55:16 +01:00
|
|
|
f"""<h2>Création d'une matière dans l'UE {ue.titre or ''} ({ue.acronyme})</h2>
|
2023-07-10 14:32:16 +02:00
|
|
|
<p class="help">Les matières sont des groupes de modules dans une UE
|
2020-09-26 16:19:37 +02:00
|
|
|
d'une formation donnée. Les matières servent surtout pour la
|
|
|
|
présentation (bulletins, etc) mais <em>n'ont pas de rôle dans le calcul
|
|
|
|
des notes.</em>
|
2023-12-31 23:04:06 +01:00
|
|
|
</p>
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
<p class="help">Si votre formation n'utilise pas la notion de
|
|
|
|
"matières", créez une matière par UE, et donnez lui le même nom que l'UE
|
|
|
|
(en effet, tout module doit appartenir à une matière).
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<p class="help">Comme les UE, les matières n'ont pas de coefficient
|
|
|
|
associé.
|
|
|
|
</p>""",
|
|
|
|
]
|
|
|
|
tf = TrivialFormulator(
|
2021-09-18 10:10:02 +02:00
|
|
|
request.base_url,
|
2021-09-27 16:42:14 +02:00
|
|
|
scu.get_request_args(),
|
2020-09-26 16:19:37 +02:00
|
|
|
(
|
|
|
|
("ue_id", {"input_type": "hidden", "default": ue_id}),
|
2023-07-10 14:32:16 +02:00
|
|
|
(
|
|
|
|
"titre",
|
|
|
|
{
|
|
|
|
"size": 30,
|
|
|
|
"explanation": "nom de la matière.",
|
|
|
|
},
|
|
|
|
),
|
2020-09-26 16:19:37 +02:00
|
|
|
(
|
|
|
|
"numero",
|
|
|
|
{
|
|
|
|
"size": 2,
|
|
|
|
"explanation": "numéro (1,2,3,4...) pour affichage",
|
|
|
|
"type": "int",
|
2023-07-10 14:32:16 +02:00
|
|
|
"default": default_numero,
|
|
|
|
"allow_null": False,
|
2020-09-26 16:19:37 +02:00
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
submitlabel="Créer cette matière",
|
|
|
|
)
|
|
|
|
|
2021-08-09 10:09:04 +02:00
|
|
|
dest_url = url_for(
|
2023-07-10 14:32:16 +02:00
|
|
|
"notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=ue.formation_id
|
2021-08-09 10:09:04 +02:00
|
|
|
)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
if tf[0] == 0:
|
2024-08-24 18:26:51 +02:00
|
|
|
return render_template(
|
|
|
|
"sco_page.j2", title="Création d'une matière", content="\n".join(H) + tf[1]
|
|
|
|
)
|
|
|
|
if tf[0] == -1:
|
2021-07-31 18:01:10 +02:00
|
|
|
return flask.redirect(dest_url)
|
2024-08-24 18:26:51 +02:00
|
|
|
# check unicity
|
2024-10-11 14:06:02 +02:00
|
|
|
nb_mats = Matiere.query.filter_by(ue_id=ue_id, titre=tf[2]["titre"]).count()
|
|
|
|
if nb_mats:
|
2024-08-24 18:26:51 +02:00
|
|
|
return render_template(
|
|
|
|
"sco_page.j2",
|
|
|
|
title="Création d'une matière",
|
|
|
|
content=(
|
2020-09-26 16:19:37 +02:00
|
|
|
"\n".join(H)
|
|
|
|
+ tf_error_message("Titre de matière déjà existant dans cette UE")
|
|
|
|
+ tf[1]
|
2024-08-24 18:26:51 +02:00
|
|
|
),
|
|
|
|
)
|
2024-10-11 14:06:02 +02:00
|
|
|
Matiere.create_from_dict(tf[2])
|
2024-08-24 18:26:51 +02:00
|
|
|
return flask.redirect(dest_url)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
|
2021-09-27 10:20:10 +02:00
|
|
|
def matiere_delete(matiere_id=None):
|
2024-10-11 14:06:02 +02:00
|
|
|
"""Form delete matière"""
|
|
|
|
matiere = Matiere.get_instance(matiere_id)
|
|
|
|
if not matiere.can_be_deleted():
|
2022-01-04 20:03:38 +01:00
|
|
|
# il y a au moins un modimpl dans un module de cette matière
|
|
|
|
raise ScoNonEmptyFormationObject(
|
|
|
|
"Matière",
|
|
|
|
matiere.titre,
|
|
|
|
dest_url=url_for(
|
|
|
|
"notes.ue_table",
|
|
|
|
formation_id=matiere.ue.formation_id,
|
|
|
|
semestre_idx=matiere.ue.semestre_idx,
|
|
|
|
scodoc_dept=g.scodoc_dept,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
2020-09-26 16:19:37 +02:00
|
|
|
H = [
|
2024-10-11 14:06:02 +02:00
|
|
|
f"""<h2>Suppression de la matière {matiere.titre}
|
|
|
|
dans l'UE {matiere.ue.acronyme}</h2>""",
|
2020-09-26 16:19:37 +02:00
|
|
|
]
|
2021-10-22 23:09:15 +02:00
|
|
|
dest_url = url_for(
|
|
|
|
"notes.ue_table",
|
|
|
|
scodoc_dept=g.scodoc_dept,
|
2024-10-11 14:06:02 +02:00
|
|
|
formation_id=matiere.ue.formation_id,
|
2021-10-22 23:09:15 +02:00
|
|
|
)
|
2020-09-26 16:19:37 +02:00
|
|
|
tf = TrivialFormulator(
|
2021-09-18 10:10:02 +02:00
|
|
|
request.base_url,
|
2021-09-27 16:42:14 +02:00
|
|
|
scu.get_request_args(),
|
2020-09-26 16:19:37 +02:00
|
|
|
(("matiere_id", {"input_type": "hidden"}),),
|
2024-10-11 14:06:02 +02:00
|
|
|
initvalues=matiere.to_dict(),
|
2020-09-26 16:19:37 +02:00
|
|
|
submitlabel="Confirmer la suppression",
|
|
|
|
cancelbutton="Annuler",
|
|
|
|
)
|
|
|
|
if tf[0] == 0:
|
2024-08-24 18:26:51 +02:00
|
|
|
return render_template(
|
|
|
|
"sco_page.j2",
|
|
|
|
title="Suppression d'une matière",
|
|
|
|
content="\n".join(H) + tf[1],
|
|
|
|
)
|
|
|
|
if tf[0] == -1:
|
2021-07-31 18:01:10 +02:00
|
|
|
return flask.redirect(dest_url)
|
2020-09-26 16:19:37 +02:00
|
|
|
|
2024-10-11 14:06:02 +02:00
|
|
|
matiere.delete()
|
2024-08-24 18:26:51 +02:00
|
|
|
return flask.redirect(dest_url)
|
|
|
|
|
2020-09-26 16:19:37 +02:00
|
|
|
|
2021-09-27 10:20:10 +02:00
|
|
|
def matiere_edit(matiere_id=None):
|
2024-10-11 14:06:02 +02:00
|
|
|
"""Form edit matiere"""
|
|
|
|
matiere: Matiere = Matiere.get_instance(matiere_id)
|
|
|
|
if matiere.is_locked():
|
|
|
|
raise ScoLockedFormError()
|
|
|
|
ue = matiere.ue
|
|
|
|
formation = ue.formation
|
|
|
|
ues = matiere.ue.formation.ues
|
|
|
|
ue_names = [f"{u.acronyme} ({u.titre or ''})" for u in ues]
|
|
|
|
ue_ids = [u.id for u in ues]
|
2020-09-26 16:19:37 +02:00
|
|
|
H = [
|
2024-10-11 14:06:02 +02:00
|
|
|
f"""<h2>Modification de la matière {matiere.titre or 'sans titre'}
|
|
|
|
(formation ({formation.acronyme}, version {formation.version})</h2>""",
|
2020-09-26 16:19:37 +02:00
|
|
|
]
|
2024-08-24 18:26:51 +02:00
|
|
|
help_msg = """<p class="help">Les matières sont des groupes de modules dans une UE
|
2020-09-26 16:19:37 +02:00
|
|
|
d'une formation donnée. Les matières servent surtout pour la
|
|
|
|
présentation (bulletins, etc) mais <em>n'ont pas de rôle dans le calcul
|
|
|
|
des notes.</em>
|
2023-12-31 23:04:06 +01:00
|
|
|
</p>
|
2020-09-26 16:19:37 +02:00
|
|
|
|
|
|
|
<p class="help">Si votre formation n'utilise pas la notion de
|
|
|
|
"matières", créez une matière par UE, et donnez lui le même nom que l'UE
|
|
|
|
(en effet, tout module doit appartenir à une matière).
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<p class="help">Comme les UE, les matières n'ont pas de coefficient
|
|
|
|
associé.
|
|
|
|
</p>"""
|
|
|
|
tf = TrivialFormulator(
|
2021-09-18 10:10:02 +02:00
|
|
|
request.base_url,
|
2021-09-27 16:42:14 +02:00
|
|
|
scu.get_request_args(),
|
2020-09-26 16:19:37 +02:00
|
|
|
(
|
|
|
|
("matiere_id", {"input_type": "hidden"}),
|
|
|
|
(
|
|
|
|
"ue_id",
|
2022-09-23 11:23:48 +02:00
|
|
|
{
|
|
|
|
"input_type": "menu",
|
|
|
|
"allowed_values": ue_ids,
|
|
|
|
"labels": ue_names,
|
|
|
|
"title": "UE",
|
|
|
|
},
|
2020-09-26 16:19:37 +02:00
|
|
|
),
|
|
|
|
("titre", {"size": 30, "explanation": "nom de cette matière"}),
|
|
|
|
(
|
|
|
|
"numero",
|
|
|
|
{
|
|
|
|
"size": 2,
|
|
|
|
"explanation": "numéro (1,2,3,4...) pour affichage",
|
|
|
|
"type": "int",
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
2024-10-11 14:06:02 +02:00
|
|
|
initvalues=matiere.to_dict(),
|
2020-09-26 16:19:37 +02:00
|
|
|
submitlabel="Modifier les valeurs",
|
|
|
|
)
|
|
|
|
|
2021-10-22 23:09:15 +02:00
|
|
|
dest_url = url_for(
|
|
|
|
"notes.ue_table",
|
|
|
|
scodoc_dept=g.scodoc_dept,
|
2024-10-11 14:06:02 +02:00
|
|
|
formation_id=formation.id,
|
2021-10-22 23:09:15 +02:00
|
|
|
)
|
2020-09-26 16:19:37 +02:00
|
|
|
if tf[0] == 0:
|
2024-08-24 18:26:51 +02:00
|
|
|
return render_template(
|
|
|
|
"sco_page.j2",
|
|
|
|
title="Modification d'une matière",
|
|
|
|
content="\n".join(H) + tf[1] + help_msg,
|
|
|
|
)
|
2020-09-26 16:19:37 +02:00
|
|
|
elif tf[0] == -1:
|
2021-07-31 18:01:10 +02:00
|
|
|
return flask.redirect(dest_url)
|
2020-09-26 16:19:37 +02:00
|
|
|
else:
|
|
|
|
# check unicity
|
2024-10-11 14:06:02 +02:00
|
|
|
mats = Matiere.query.filter_by(ue_id=tf[2]["ue_id"], titre=tf[2]["titre"]).all()
|
|
|
|
if len(mats) > 1 or (len(mats) == 1 and mats[0].id != matiere_id):
|
2024-08-24 18:26:51 +02:00
|
|
|
return render_template(
|
|
|
|
"sco_page.j2",
|
|
|
|
title="Modification d'une matière",
|
|
|
|
content=(
|
|
|
|
"\n".join(H)
|
|
|
|
+ tf_error_message("Titre de matière déjà existant dans cette UE")
|
|
|
|
+ tf[1]
|
|
|
|
),
|
2020-09-26 16:19:37 +02:00
|
|
|
)
|
|
|
|
|
2024-10-11 14:06:02 +02:00
|
|
|
modif = False
|
2020-09-26 16:19:37 +02:00
|
|
|
# changement d'UE ?
|
2024-10-11 14:06:02 +02:00
|
|
|
if tf[2]["ue_id"] != ue.id:
|
|
|
|
log(f"attaching mat {matiere_id} to new UE id={tf[2]['ue_id']}")
|
|
|
|
new_ue = UniteEns.get_ue(tf[2]["ue_id"])
|
|
|
|
if new_ue.formation_id != formation.id:
|
|
|
|
raise ScoValueError("UE does not belong to the same formation")
|
|
|
|
matiere.ue = new_ue
|
|
|
|
modif = True
|
|
|
|
modif |= matiere.from_dict(tf[2])
|
|
|
|
if modif:
|
|
|
|
db.session.commit()
|
|
|
|
matiere.ue.formation.invalidate_cached_sems()
|
|
|
|
flash("Matière modifiée", "info")
|
2021-07-31 18:01:10 +02:00
|
|
|
return flask.redirect(dest_url)
|