forked from ScoDoc/ScoDoc
Merge branch 'refactor_nt' of https://scodoc.org/git/ScoDoc/ScoDoc into entreprises
This commit is contained in:
commit
2cc5e1f164
@ -41,7 +41,6 @@ from app import db
|
||||
from app.models import ModuleImpl, Evaluation, EvaluationUEPoids
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc.sco_codes_parcours import UE_SPORT
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
|
||||
from app.scodoc.sco_utils import ModuleType
|
||||
|
||||
@ -92,6 +91,10 @@ class ModuleImplResults:
|
||||
ne donnent pas de coef vers cette UE.
|
||||
"""
|
||||
self.load_notes()
|
||||
self.etuds_use_session2 = pd.Series(False, index=self.evals_notes.index)
|
||||
"""1 bool par etud, indique si sa moyenne de module vient de la session2"""
|
||||
self.etuds_use_rattrapage = pd.Series(False, index=self.evals_notes.index)
|
||||
"""1 bool par etud, indique si sa moyenne de module utilise la note de rattrapage"""
|
||||
|
||||
def load_notes(self): # ré-écriture de df_load_modimpl_notes
|
||||
"""Charge toutes les notes de toutes les évaluations du module.
|
||||
@ -135,8 +138,11 @@ class ModuleImplResults:
|
||||
eval_df = self._load_evaluation_notes(evaluation)
|
||||
# is_complete ssi tous les inscrits (non dem) au semestre ont une note
|
||||
# ou évaluation déclarée "à prise en compte immédiate"
|
||||
is_complete = evaluation.publish_incomplete or (
|
||||
not (inscrits_module - set(eval_df.index))
|
||||
# Les évaluations de rattrapage et 2eme session sont toujours incomplètes
|
||||
# car on calcule leur moyenne à part.
|
||||
is_complete = (evaluation.evaluation_type == scu.EVALUATION_NORMALE) and (
|
||||
evaluation.publish_incomplete
|
||||
or (not (inscrits_module - set(eval_df.index)))
|
||||
)
|
||||
self.evaluations_completes.append(is_complete)
|
||||
self.evaluations_completes_dict[evaluation.id] = is_complete
|
||||
@ -212,6 +218,33 @@ class ModuleImplResults:
|
||||
self.evals_notes.values > scu.NOTES_ABSENCE, self.evals_notes.values, 0.0
|
||||
) / [e.note_max / 20.0 for e in moduleimpl.evaluations]
|
||||
|
||||
def get_evaluation_rattrapage(self, moduleimpl: ModuleImpl):
|
||||
"""L'évaluation de rattrapage de ce module, ou None s'il n'en a pas.
|
||||
Rattrapage: la moyenne du module est la meilleure note entre moyenne
|
||||
des autres évals et la note eval rattrapage.
|
||||
"""
|
||||
eval_list = [
|
||||
e
|
||||
for e in moduleimpl.evaluations
|
||||
if e.evaluation_type == scu.EVALUATION_RATTRAPAGE
|
||||
]
|
||||
if eval_list:
|
||||
return eval_list[0]
|
||||
return None
|
||||
|
||||
def get_evaluation_session2(self, moduleimpl: ModuleImpl):
|
||||
"""L'évaluation de deuxième session de ce module, ou None s'il n'en a pas.
|
||||
Session 2: remplace la note de moyenne des autres évals.
|
||||
"""
|
||||
eval_list = [
|
||||
e
|
||||
for e in moduleimpl.evaluations
|
||||
if e.evaluation_type == scu.EVALUATION_SESSION2
|
||||
]
|
||||
if eval_list:
|
||||
return eval_list[0]
|
||||
return None
|
||||
|
||||
|
||||
class ModuleImplResultsAPC(ModuleImplResults):
|
||||
"Calcul des moyennes de modules à la mode BUT"
|
||||
@ -229,7 +262,7 @@ class ModuleImplResultsAPC(ModuleImplResults):
|
||||
ou NaN si les évaluations (dans lesquelles l'étudiant a des notes)
|
||||
ne donnent pas de coef vers cette UE.
|
||||
"""
|
||||
moduleimpl = ModuleImpl.query.get(self.moduleimpl_id)
|
||||
modimpl = ModuleImpl.query.get(self.moduleimpl_id)
|
||||
nb_etuds, nb_evals = self.evals_notes.shape
|
||||
nb_ues = evals_poids_df.shape[1]
|
||||
assert evals_poids_df.shape[0] == nb_evals # compat notes/poids
|
||||
@ -237,11 +270,11 @@ class ModuleImplResultsAPC(ModuleImplResults):
|
||||
return pd.DataFrame(index=[], columns=evals_poids_df.columns)
|
||||
if nb_ues == 0:
|
||||
return pd.DataFrame(index=self.evals_notes.index, columns=[])
|
||||
evals_coefs = self.get_evaluations_coefs(moduleimpl)
|
||||
evals_coefs = self.get_evaluations_coefs(modimpl)
|
||||
evals_poids = evals_poids_df.values * evals_coefs
|
||||
# -> evals_poids shape : (nb_evals, nb_ues)
|
||||
assert evals_poids.shape == (nb_evals, nb_ues)
|
||||
evals_notes_20 = self.get_eval_notes_sur_20(moduleimpl)
|
||||
evals_notes_20 = self.get_eval_notes_sur_20(modimpl)
|
||||
|
||||
# Les poids des évals pour chaque étudiant: là où il a des notes
|
||||
# non neutralisées
|
||||
@ -262,6 +295,45 @@ class ModuleImplResultsAPC(ModuleImplResults):
|
||||
etuds_moy_module = np.sum(
|
||||
evals_poids_etuds * evals_notes_stacked, axis=1
|
||||
) / np.sum(evals_poids_etuds, axis=1)
|
||||
|
||||
# Session2 : quand elle existe, remplace la note de module
|
||||
eval_session2 = self.get_evaluation_session2(modimpl)
|
||||
if eval_session2:
|
||||
notes_session2 = self.evals_notes[eval_session2.id].values
|
||||
# n'utilise que les notes valides (pas ATT, EXC, ABS, NaN)
|
||||
etuds_use_session2 = notes_session2 > scu.NOTES_ABSENCE
|
||||
etuds_moy_module = np.where(
|
||||
etuds_use_session2[:, np.newaxis],
|
||||
np.tile(
|
||||
(notes_session2 / (eval_session2.note_max / 20.0))[:, np.newaxis],
|
||||
nb_ues,
|
||||
),
|
||||
etuds_moy_module,
|
||||
)
|
||||
self.etuds_use_session2 = pd.Series(
|
||||
etuds_use_session2, index=self.evals_notes.index
|
||||
)
|
||||
else:
|
||||
# Rattrapage: remplace la note de module ssi elle est supérieure
|
||||
eval_rat = self.get_evaluation_rattrapage(modimpl)
|
||||
if eval_rat:
|
||||
notes_rat = self.evals_notes[eval_rat.id].values
|
||||
# remplace les notes invalides (ATT, EXC...) par des NaN
|
||||
notes_rat = np.where(
|
||||
notes_rat > scu.NOTES_ABSENCE,
|
||||
notes_rat / (eval_rat.note_max / 20.0),
|
||||
np.nan,
|
||||
)
|
||||
# prend le max
|
||||
etuds_use_rattrapage = notes_rat > etuds_moy_module
|
||||
etuds_moy_module = np.where(
|
||||
etuds_use_rattrapage[:, np.newaxis],
|
||||
np.tile(notes_rat[:, np.newaxis], nb_ues),
|
||||
etuds_moy_module,
|
||||
)
|
||||
self.etuds_use_rattrapage = pd.Series(
|
||||
etuds_use_rattrapage, index=self.evals_notes.index
|
||||
)
|
||||
self.etuds_moy_module = pd.DataFrame(
|
||||
etuds_moy_module,
|
||||
index=self.evals_notes.index,
|
||||
@ -371,8 +443,42 @@ class ModuleImplResultsClassic(ModuleImplResults):
|
||||
evals_coefs_etuds * evals_notes_20, axis=1
|
||||
) / np.sum(evals_coefs_etuds, axis=1)
|
||||
|
||||
# Session2 : quand elle existe, remplace la note de module
|
||||
eval_session2 = self.get_evaluation_session2(modimpl)
|
||||
if eval_session2:
|
||||
notes_session2 = self.evals_notes[eval_session2.id].values
|
||||
# n'utilise que les notes valides (pas ATT, EXC, ABS, NaN)
|
||||
etuds_use_session2 = notes_session2 > scu.NOTES_ABSENCE
|
||||
etuds_moy_module = np.where(
|
||||
etuds_use_session2,
|
||||
notes_session2 / (eval_session2.note_max / 20.0),
|
||||
etuds_moy_module,
|
||||
)
|
||||
self.etuds_use_session2 = pd.Series(
|
||||
etuds_use_session2, index=self.evals_notes.index
|
||||
)
|
||||
else:
|
||||
# Rattrapage: remplace la note de module ssi elle est supérieure
|
||||
eval_rat = self.get_evaluation_rattrapage(modimpl)
|
||||
if eval_rat:
|
||||
notes_rat = self.evals_notes[eval_rat.id].values
|
||||
# remplace les notes invalides (ATT, EXC...) par des NaN
|
||||
notes_rat = np.where(
|
||||
notes_rat > scu.NOTES_ABSENCE,
|
||||
notes_rat / (eval_rat.note_max / 20.0),
|
||||
np.nan,
|
||||
)
|
||||
# prend le max
|
||||
etuds_use_rattrapage = notes_rat > etuds_moy_module
|
||||
etuds_moy_module = np.where(
|
||||
etuds_use_rattrapage, notes_rat, etuds_moy_module
|
||||
)
|
||||
self.etuds_use_rattrapage = pd.Series(
|
||||
etuds_use_rattrapage, index=self.evals_notes.index
|
||||
)
|
||||
self.etuds_moy_module = pd.Series(
|
||||
etuds_moy_module,
|
||||
index=self.evals_notes.index,
|
||||
)
|
||||
|
||||
return self.etuds_moy_module
|
||||
|
@ -162,6 +162,7 @@ class NotesTableCompat(ResultatsSemestre):
|
||||
_cached_attrs = ResultatsSemestre._cached_attrs + (
|
||||
"bonus",
|
||||
"bonus_ues",
|
||||
"malus",
|
||||
)
|
||||
|
||||
def __init__(self, formsemestre: FormSemestre):
|
||||
|
@ -22,6 +22,7 @@ from app.models.etudiants import Identite
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc import sco_preferences
|
||||
from app.scodoc.sco_vdi import ApoEtapeVDI
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
|
||||
class FormSemestre(db.Model):
|
||||
@ -169,14 +170,24 @@ class FormSemestre(db.Model):
|
||||
else:
|
||||
modimpls.sort(
|
||||
key=lambda m: (
|
||||
m.module.ue.numero,
|
||||
m.module.matiere.numero,
|
||||
m.module.numero,
|
||||
m.module.code,
|
||||
m.module.ue.numero or 0,
|
||||
m.module.matiere.numero or 0,
|
||||
m.module.numero or 0,
|
||||
m.module.code or "",
|
||||
)
|
||||
)
|
||||
return modimpls
|
||||
|
||||
def can_be_edited_by(self, user):
|
||||
"""Vrai si user peut modifier ce semestre"""
|
||||
if not user.has_permission(Permission.ScoImplement): # pas chef
|
||||
if not self.resp_can_edit or user.id not in [
|
||||
resp.id for resp in self.responsables
|
||||
]:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def est_courant(self) -> bool:
|
||||
"""Vrai si la date actuelle (now) est dans le semestre
|
||||
(les dates de début et fin sont incluses)
|
||||
@ -425,7 +436,7 @@ class FormSemestreUECoef(db.Model):
|
||||
|
||||
|
||||
class FormSemestreUEComputationExpr(db.Model):
|
||||
"""Formules utilisateurs pour calcul moyenne UE"""
|
||||
"""Formules utilisateurs pour calcul moyenne UE (désactivées en 9.2+)."""
|
||||
|
||||
__tablename__ = "notes_formsemestre_ue_computation_expr"
|
||||
__table_args__ = (db.UniqueConstraint("formsemestre_id", "ue_id"),)
|
||||
|
@ -619,7 +619,7 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
|
||||
prefs=prefs,
|
||||
)
|
||||
|
||||
if nbeval: # boite autour des evaluations (en pdf)
|
||||
if nbeval: # boite autour des évaluations (en pdf)
|
||||
P[-1]["_pdf_style"].append(
|
||||
("BOX", (1, 1 - nbeval), (-1, 0), 0.2, self.PDF_LIGHT_GRAY)
|
||||
)
|
||||
|
@ -289,7 +289,10 @@ def module_create(
|
||||
"type": "int",
|
||||
"title": "UE de rattachement",
|
||||
"explanation": "utilisée notamment pour les malus",
|
||||
"labels": [f"{u.acronyme} {u.titre}" for u in ues],
|
||||
"labels": [
|
||||
f"S{u.semestre_idx if u.semestre_idx is not None else '.'} / {u.acronyme} {u.titre}"
|
||||
for u in ues
|
||||
],
|
||||
"allowed_values": [u.id for u in ues],
|
||||
},
|
||||
),
|
||||
|
@ -231,13 +231,17 @@ def do_ue_delete(ue_id, delete_validations=False, force=False):
|
||||
return None
|
||||
|
||||
|
||||
def ue_create(formation_id=None):
|
||||
"""Creation d'une UE"""
|
||||
return ue_edit(create=True, formation_id=formation_id)
|
||||
def ue_create(formation_id=None, default_semestre_idx=None):
|
||||
"""Formulaire création d'une UE"""
|
||||
return ue_edit(
|
||||
create=True,
|
||||
formation_id=formation_id,
|
||||
default_semestre_idx=default_semestre_idx,
|
||||
)
|
||||
|
||||
|
||||
def ue_edit(ue_id=None, create=False, formation_id=None):
|
||||
"""Modification ou création d'une UE"""
|
||||
def ue_edit(ue_id=None, create=False, formation_id=None, default_semestre_idx=None):
|
||||
"""Formulaire modification ou création d'une UE"""
|
||||
create = int(create)
|
||||
if not create:
|
||||
U = ue_list(args={"ue_id": ue_id})
|
||||
@ -250,7 +254,7 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
||||
submitlabel = "Modifier les valeurs"
|
||||
else:
|
||||
title = "Création d'une UE"
|
||||
initvalues = {}
|
||||
initvalues = {"semestre_idx": default_semestre_idx}
|
||||
submitlabel = "Créer cette UE"
|
||||
formation = Formation.query.get(formation_id)
|
||||
if not formation:
|
||||
|
@ -207,7 +207,7 @@ def evaluation_create_form(
|
||||
{
|
||||
"size": 6,
|
||||
"type": "float",
|
||||
"explanation": "coef. dans le module (choisi librement par l'enseignant)",
|
||||
"explanation": "coef. dans le module (choisi librement par l'enseignant, non utilisé pour rattrapage et 2ème session)",
|
||||
"allow_null": False,
|
||||
},
|
||||
)
|
||||
|
@ -118,10 +118,16 @@ def formsemestre_editwithmodules(formsemestre_id):
|
||||
vals = scu.get_request_args()
|
||||
if not vals.get("tf_submitted", False):
|
||||
H.append(
|
||||
"""<p class="help">Seuls les modules cochés font partie de ce semestre. Pour les retirer, les décocher et appuyer sur le bouton "modifier".
|
||||
</p>
|
||||
<p class="help">Attention : s'il y a déjà des évaluations dans un module, il ne peut pas être supprimé !</p>
|
||||
<p class="help">Les modules ont toujours un responsable. Par défaut, c'est le directeur des études.</p>"""
|
||||
"""<p class="help">Seuls les modules cochés font partie de ce semestre.
|
||||
Pour les retirer, les décocher et appuyer sur le bouton "modifier".
|
||||
</p>
|
||||
<p class="help">Attention : s'il y a déjà des évaluations dans un module,
|
||||
il ne peut pas être supprimé !</p>
|
||||
<p class="help">Les modules ont toujours un responsable.
|
||||
Par défaut, c'est le directeur des études.</p>
|
||||
<p class="help">Un semestre ne peut comporter qu'une seule UE "bonus
|
||||
sport/culture"</p>
|
||||
"""
|
||||
)
|
||||
|
||||
return "\n".join(H) + html_sco_header.sco_footer()
|
||||
@ -739,6 +745,7 @@ def do_formsemestre_createwithmodules(edit=False):
|
||||
# Modules sélectionnés:
|
||||
# (retire le "MI" du début du nom de champs)
|
||||
module_ids_checked = [int(x[2:]) for x in tf[2]["tf-checked"]]
|
||||
_formsemestre_check_ue_bonus_unicity(module_ids_checked)
|
||||
if not edit:
|
||||
if formation.is_apc():
|
||||
_formsemestre_check_module_list(
|
||||
@ -882,6 +889,18 @@ def _formsemestre_check_module_list(module_ids, semestre_idx):
|
||||
)
|
||||
|
||||
|
||||
def _formsemestre_check_ue_bonus_unicity(module_ids):
|
||||
"""Vérifie qu'il n'y a qu'une seule UE bonus associée aux modules choisis"""
|
||||
ues = [Module.query.get_or_404(module_id).ue for module_id in module_ids]
|
||||
ues_bonus = {ue.id for ue in ues if ue.type == sco_codes_parcours.UE_SPORT}
|
||||
if len(ues_bonus) > 1:
|
||||
raise ScoValueError(
|
||||
"""Les modules de bonus sélectionnés ne sont pas tous dans la même UE bonus.
|
||||
Changez la sélection ou modifiez la structure du programme de formation.""",
|
||||
dest_url="javascript:history.back();",
|
||||
)
|
||||
|
||||
|
||||
def formsemestre_delete_moduleimpls(formsemestre_id, module_ids_to_del):
|
||||
"""Delete moduleimpls
|
||||
module_ids_to_del: list of module_id (warning: not moduleimpl)
|
||||
|
@ -1152,30 +1152,19 @@ def formsemestre_tableau_modules(
|
||||
f"""<tr class="formsemestre_status_ue"><td colspan="4">
|
||||
<span class="status_ue_acro">{ue["acronyme"]}</span>
|
||||
<span class="status_ue_title">{titre}</span>
|
||||
</td><td>"""
|
||||
</td><td colspan="2">"""
|
||||
)
|
||||
if can_edit:
|
||||
H.append(
|
||||
' <a href="edit_ue_expr?formsemestre_id=%s&ue_id=%s">'
|
||||
% (formsemestre_id, ue["ue_id"])
|
||||
)
|
||||
H.append(
|
||||
scu.icontag(
|
||||
"formula",
|
||||
title="Mode calcul moyenne d'UE",
|
||||
style="vertical-align:middle",
|
||||
)
|
||||
)
|
||||
if can_edit:
|
||||
H.append("</a>")
|
||||
|
||||
expr = sco_compute_moy.get_ue_expression(
|
||||
formsemestre_id, ue["ue_id"], html_quote=True
|
||||
)
|
||||
if expr:
|
||||
H.append(
|
||||
""" <span class="formula" title="mode de calcul de la moyenne d'UE">%s</span>"""
|
||||
% expr
|
||||
f""" <span class="formula" title="mode de calcul de la moyenne d'UE">{expr}</span>
|
||||
<span class="warning">formule inutilisée en 9.2: <a href="{
|
||||
url_for("notes.delete_ue_expr", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, ue_id=ue["ue_id"] )
|
||||
}
|
||||
">supprimer</a></span>"""
|
||||
)
|
||||
|
||||
H.append("</td></tr>")
|
||||
|
@ -46,16 +46,17 @@
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
{% if editable %}
|
||||
<ul>
|
||||
<li class="notes_ue_list notes_ue_list_add"><a class="stdlink" href="{{
|
||||
url_for('notes.ue_create',
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formation_id=formation.id,
|
||||
default_semestre_idx=semestre_idx,
|
||||
)}}"
|
||||
>ajouter une UE</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
@ -30,23 +30,19 @@ Module notes: issu de ScoDoc7 / ZNotes.py
|
||||
|
||||
Emmanuel Viennet, 2021
|
||||
"""
|
||||
import sys
|
||||
import time
|
||||
import datetime
|
||||
import pprint
|
||||
|
||||
from operator import itemgetter
|
||||
from xml.etree import ElementTree
|
||||
|
||||
import flask
|
||||
from flask import url_for, jsonify, render_template
|
||||
from flask import flash, jsonify, render_template, url_for
|
||||
from flask import current_app, g, request
|
||||
from flask_login import current_user
|
||||
from werkzeug.utils import redirect
|
||||
from app.models.formsemestre import FormSemestre
|
||||
from app.models.formsemestre import FormSemestreUEComputationExpr
|
||||
from app.models.ues import UniteEns
|
||||
|
||||
from config import Config
|
||||
|
||||
from app import api
|
||||
from app import db
|
||||
from app import models
|
||||
@ -1245,76 +1241,28 @@ def view_module_abs(moduleimpl_id, format="html"):
|
||||
return "\n".join(H) + tab.html() + html_sco_header.sco_footer()
|
||||
|
||||
|
||||
@bp.route("/edit_ue_expr", methods=["GET", "POST"])
|
||||
@bp.route("/delete_ue_expr/<int:formsemestre_id>/<int:ue_id>", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
@scodoc7func
|
||||
def edit_ue_expr(formsemestre_id, ue_id):
|
||||
"""Edition formule calcul moyenne UE"""
|
||||
# Check access
|
||||
sem = sco_formsemestre_edit.can_edit_sem(formsemestre_id)
|
||||
if not sem:
|
||||
def delete_ue_expr(formsemestre_id: int, ue_id: int):
|
||||
"""Efface une expression de calcul d'UE"""
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
if not formsemestre.can_be_edited_by(current_user):
|
||||
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
|
||||
cnx = ndb.GetDBConnexion()
|
||||
#
|
||||
ue = sco_edit_ue.ue_list({"ue_id": ue_id})[0]
|
||||
H = [
|
||||
html_sco_header.html_sem_header(
|
||||
"Modification règle de calcul de l'UE %s (%s)"
|
||||
% (ue["acronyme"], ue["titre"]),
|
||||
),
|
||||
_EXPR_HELP % {"target": "de l'UE", "objs": "modules", "ordre": ""},
|
||||
]
|
||||
el = sco_compute_moy.formsemestre_ue_computation_expr_list(
|
||||
cnx, {"formsemestre_id": formsemestre_id, "ue_id": ue_id}
|
||||
)
|
||||
if el:
|
||||
initvalues = el[0]
|
||||
else:
|
||||
initvalues = {}
|
||||
form = [
|
||||
("ue_id", {"input_type": "hidden"}),
|
||||
("formsemestre_id", {"input_type": "hidden"}),
|
||||
(
|
||||
"computation_expr",
|
||||
{
|
||||
"title": "Formule de calcul",
|
||||
"input_type": "textarea",
|
||||
"rows": 4,
|
||||
"cols": 60,
|
||||
"explanation": "formule de calcul (expérimental)",
|
||||
},
|
||||
),
|
||||
]
|
||||
tf = TrivialFormulator(
|
||||
request.base_url,
|
||||
scu.get_request_args(),
|
||||
form,
|
||||
submitlabel="Modifier formule de calcul",
|
||||
cancelbutton="Annuler",
|
||||
initvalues=initvalues,
|
||||
)
|
||||
if tf[0] == 0:
|
||||
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(
|
||||
"formsemestre_status?formsemestre_id=" + str(formsemestre_id)
|
||||
)
|
||||
else:
|
||||
if el:
|
||||
el[0]["computation_expr"] = tf[2]["computation_expr"]
|
||||
sco_compute_moy.formsemestre_ue_computation_expr_edit(cnx, el[0])
|
||||
else:
|
||||
sco_compute_moy.formsemestre_ue_computation_expr_create(cnx, tf[2])
|
||||
|
||||
sco_cache.invalidate_formsemestre(
|
||||
formsemestre_id=formsemestre_id
|
||||
) # > modif regle calcul
|
||||
return flask.redirect(
|
||||
"formsemestre_status?formsemestre_id="
|
||||
+ str(formsemestre_id)
|
||||
+ "&head_message=règle%20de%20calcul%20modifiée"
|
||||
expr = FormSemestreUEComputationExpr.query.filter_by(
|
||||
formsemestre_id=formsemestre_id, ue_id=ue_id
|
||||
).first()
|
||||
if expr is not None:
|
||||
db.session.delete(expr)
|
||||
db.session.commit()
|
||||
flash("formule supprimée")
|
||||
return flask.redirect(
|
||||
url_for(
|
||||
"notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre_id,
|
||||
head_message="formule supprimée",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/formsemestre_enseignants_list")
|
||||
|
@ -269,7 +269,6 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
|
||||
for i in range(len(displayed_roles_strings)):
|
||||
if displayed_roles_strings[i] not in editable_roles_strings:
|
||||
disabled_roles[i] = True
|
||||
breakpoint()
|
||||
descr = [
|
||||
("edit", {"input_type": "hidden", "default": edit}),
|
||||
("nom", {"title": "Nom", "size": 20, "allow_null": False}),
|
||||
|
Loading…
Reference in New Issue
Block a user