# -*- mode: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2024 Emmanuel Viennet. All rights reserved. # # 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 # ############################################################################## """Ajout/Modification/Suppression matieres """ import flask from flask import flash, g, render_template, request, url_for from app import db, log from app.models import Matiere, UniteEns import app.scodoc.sco_utils as scu from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message from app.scodoc.sco_exceptions import ( ScoValueError, ScoLockedFormError, ScoNonEmptyFormationObject, ) def matiere_create(ue_id=None): """Formulaire création d'une matiere""" ue: UniteEns = UniteEns.query.get_or_404(ue_id) default_numero = max([mat.numero for mat in ue.matieres] or [9]) + 1 H = [ f"""<h2>Création d'une matière dans l'UE {ue.titre or ''} ({ue.acronyme})</h2> <p class="help">Les matières sont des groupes de modules dans une UE 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> </p> <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( request.base_url, scu.get_request_args(), ( ("ue_id", {"input_type": "hidden", "default": ue_id}), ( "titre", { "size": 30, "explanation": "nom de la matière.", }, ), ( "numero", { "size": 2, "explanation": "numéro (1,2,3,4...) pour affichage", "type": "int", "default": default_numero, "allow_null": False, }, ), ), submitlabel="Créer cette matière", ) dest_url = url_for( "notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=ue.formation_id ) if tf[0] == 0: return render_template( "sco_page.j2", title="Création d'une matière", content="\n".join(H) + tf[1] ) if tf[0] == -1: return flask.redirect(dest_url) # check unicity nb_mats = Matiere.query.filter_by(ue_id=ue_id, titre=tf[2]["titre"]).count() if nb_mats: return render_template( "sco_page.j2", title="Création d'une matière", content=( "\n".join(H) + tf_error_message("Titre de matière déjà existant dans cette UE") + tf[1] ), ) Matiere.create_from_dict(tf[2]) return flask.redirect(dest_url) def matiere_delete(matiere_id=None): """Form delete matière""" matiere = Matiere.get_instance(matiere_id) if not matiere.can_be_deleted(): # 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, ), ) H = [ f"""<h2>Suppression de la matière {matiere.titre} dans l'UE {matiere.ue.acronyme}</h2>""", ] dest_url = url_for( "notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=matiere.ue.formation_id, ) tf = TrivialFormulator( request.base_url, scu.get_request_args(), (("matiere_id", {"input_type": "hidden"}),), initvalues=matiere.to_dict(), submitlabel="Confirmer la suppression", cancelbutton="Annuler", ) if tf[0] == 0: return render_template( "sco_page.j2", title="Suppression d'une matière", content="\n".join(H) + tf[1], ) if tf[0] == -1: return flask.redirect(dest_url) matiere.delete() return flask.redirect(dest_url) def matiere_edit(matiere_id=None): """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] H = [ f"""<h2>Modification de la matière {matiere.titre or 'sans titre'} (formation ({formation.acronyme}, version {formation.version})</h2>""", ] help_msg = """<p class="help">Les matières sont des groupes de modules dans une UE 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> </p> <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( request.base_url, scu.get_request_args(), ( ("matiere_id", {"input_type": "hidden"}), ( "ue_id", { "input_type": "menu", "allowed_values": ue_ids, "labels": ue_names, "title": "UE", }, ), ("titre", {"size": 30, "explanation": "nom de cette matière"}), ( "numero", { "size": 2, "explanation": "numéro (1,2,3,4...) pour affichage", "type": "int", }, ), ), initvalues=matiere.to_dict(), submitlabel="Modifier les valeurs", ) dest_url = url_for( "notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formation.id, ) if tf[0] == 0: return render_template( "sco_page.j2", title="Modification d'une matière", content="\n".join(H) + tf[1] + help_msg, ) elif tf[0] == -1: return flask.redirect(dest_url) else: # check unicity 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): 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] ), ) modif = False # changement d'UE ? 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") return flask.redirect(dest_url)