Merge pull request 'master' (#1) from ScoDoc/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/lehmann/ScoDoc-Front/pulls/1
This commit is contained in:
commit
19c736c894
@ -149,9 +149,9 @@ class ResultatsSemestreBUT:
|
||||
"""dict synthèse résultats des modules indiqués,
|
||||
avec évaluations de chacun."""
|
||||
d = {}
|
||||
etud_idx = self.etud_index[etud.id]
|
||||
# etud_idx = self.etud_index[etud.id]
|
||||
for mi in modimpls:
|
||||
mod_idx = self.modimpl_coefs_df.columns.get_loc(mi.id)
|
||||
# mod_idx = self.modimpl_coefs_df.columns.get_loc(mi.id)
|
||||
# # moyennes indicatives (moyennes de moyennes d'UE)
|
||||
# try:
|
||||
# moyennes_etuds = np.nan_to_num(
|
||||
|
@ -111,13 +111,14 @@ def df_load_modimpl_notes(moduleimpl_id: int) -> tuple:
|
||||
|
||||
N'utilise pas de cache ScoDoc.
|
||||
"""
|
||||
# L'index du dataframe est la liste des étudiants inscrits au semestre, sans les démissionnaires
|
||||
etudids = {
|
||||
# L'index du dataframe est la liste des étudiants inscrits au semestre,
|
||||
# sans les démissionnaires
|
||||
etudids = [
|
||||
e.etudid
|
||||
for e in ModuleImpl.query.get(moduleimpl_id).formsemestre.get_inscrits(
|
||||
include_dem=False
|
||||
)
|
||||
}
|
||||
]
|
||||
evaluations = Evaluation.query.filter_by(moduleimpl_id=moduleimpl_id).all()
|
||||
# --- Calcul nombre d'inscrits pour détermnier si évaluation "complete":
|
||||
if evaluations:
|
||||
@ -128,7 +129,8 @@ def df_load_modimpl_notes(moduleimpl_id: int) -> tuple:
|
||||
nb_inscrits_module = len(inscrits_module)
|
||||
else:
|
||||
nb_inscrits_module = 0
|
||||
evals_notes = pd.DataFrame(index=etudids, dtype=float) # empty df with all students
|
||||
# empty df with all students:
|
||||
evals_notes = pd.DataFrame(index=etudids, dtype=float)
|
||||
evaluations_completes = []
|
||||
for evaluation in evaluations:
|
||||
eval_df = pd.read_sql_query(
|
||||
|
@ -76,11 +76,11 @@ class Evaluation(db.Model):
|
||||
db.session.add(copy)
|
||||
return copy
|
||||
|
||||
def set_ue_poids(self, ue, poids: float):
|
||||
def set_ue_poids(self, ue, poids: float) -> None:
|
||||
"""Set poids évaluation vers cette UE"""
|
||||
self.update_ue_poids_dict({ue.id: poids})
|
||||
|
||||
def set_ue_poids_dict(self, ue_poids_dict: dict):
|
||||
def set_ue_poids_dict(self, ue_poids_dict: dict) -> None:
|
||||
"""set poids vers les UE (remplace existants)
|
||||
ue_poids_dict = { ue_id : poids }
|
||||
"""
|
||||
@ -91,16 +91,23 @@ class Evaluation(db.Model):
|
||||
self.ue_poids = L
|
||||
self.moduleimpl.invalidate_evaluations_poids() # inval cache
|
||||
|
||||
def update_ue_poids_dict(self, ue_poids_dict: dict):
|
||||
def update_ue_poids_dict(self, ue_poids_dict: dict) -> None:
|
||||
"""update poids vers UE (ajoute aux existants)"""
|
||||
current = self.get_ue_poids_dict()
|
||||
current.update(ue_poids_dict)
|
||||
self.set_ue_poids_dict(current)
|
||||
|
||||
def get_ue_poids_dict(self):
|
||||
def get_ue_poids_dict(self) -> dict:
|
||||
"""returns { ue_id : poids }"""
|
||||
return {p.ue.id: p.poids for p in self.ue_poids}
|
||||
|
||||
def get_ue_poids_str(self) -> str:
|
||||
"""string describing poids, for excel cells and pdfs
|
||||
Note: si les poids ne sont pas initialisés (poids par défaut),
|
||||
ils ne sont pas affichés.
|
||||
"""
|
||||
return ", ".join([f"{p.ue.acronyme}: {p.poids}" for p in self.ue_poids])
|
||||
|
||||
|
||||
class EvaluationUEPoids(db.Model):
|
||||
"""Poids des évaluations (BUT)
|
||||
|
@ -33,6 +33,7 @@ import json
|
||||
|
||||
from app.but import bulletin_but
|
||||
from app.models.formsemestre import FormSemestre
|
||||
from app.models.etudiants import Identite
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
@ -86,6 +87,7 @@ def formsemestre_bulletinetud_published_dict(
|
||||
from app.scodoc import sco_bulletins
|
||||
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
etud = Identite.query.get(etudid)
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
|
||||
if formsemestre.formation.is_apc():
|
||||
@ -139,6 +141,11 @@ def formsemestre_bulletinetud_published_dict(
|
||||
if not published:
|
||||
return d # stop !
|
||||
|
||||
etat_inscription = etud.etat_inscription(formsemestre.id)
|
||||
if etat_inscription != scu.INSCRIT:
|
||||
d.update(dict_decision_jury(etudid, formsemestre_id, with_decisions=True))
|
||||
return d
|
||||
|
||||
# Groupes:
|
||||
partitions = sco_groups.get_partitions_list(formsemestre_id, with_default=False)
|
||||
partitions_etud_groups = {} # { partition_id : { etudid : group } }
|
||||
|
@ -104,7 +104,10 @@ def do_ue_create(args):
|
||||
# check duplicates
|
||||
ues = ue_list({"formation_id": args["formation_id"], "acronyme": args["acronyme"]})
|
||||
if ues:
|
||||
raise ScoValueError('Acronyme d\'UE "%s" déjà utilisé !' % args["acronyme"])
|
||||
raise ScoValueError(
|
||||
f"""Acronyme d'UE "{args['acronyme']}" déjà utilisé !
|
||||
(chaque UE doit avoir un acronyme unique dans la formation)"""
|
||||
)
|
||||
# create
|
||||
ue_id = _ueEditor.create(cnx, args)
|
||||
|
||||
@ -471,7 +474,7 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
|
||||
raise ScoValueError("invalid formation_id")
|
||||
parcours = formation.get_parcours()
|
||||
is_apc = parcours.APC_SAE
|
||||
locked = sco_formations.formation_has_locked_sems(formation_id)
|
||||
locked = formation.has_locked_sems()
|
||||
if semestre_idx == "all":
|
||||
semestre_idx = None
|
||||
else:
|
||||
@ -541,7 +544,7 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
|
||||
if locked:
|
||||
H.append(
|
||||
f"""<p class="help">Cette formation est verrouillée car
|
||||
{len(locked)} semestres verrouillés s'y réferent.
|
||||
des semestres verrouillés s'y réferent.
|
||||
Si vous souhaitez modifier cette formation (par exemple pour y ajouter un module),
|
||||
vous devez:
|
||||
</p>
|
||||
@ -1146,7 +1149,10 @@ def do_ue_edit(args, bypass_lock=False, dont_invalidate_cache=False):
|
||||
new_acro = args["acronyme"]
|
||||
ues = ue_list({"formation_id": ue["formation_id"], "acronyme": new_acro})
|
||||
if ues and ues[0]["ue_id"] != ue_id:
|
||||
raise ScoValueError('Acronyme d\'UE "%s" déjà utilisé !' % args["acronyme"])
|
||||
raise ScoValueError(
|
||||
f"""Acronyme d'UE "{args['acronyme']}" déjà utilisé !
|
||||
(chaque UE doit avoir un acronyme unique dans la formation)"""
|
||||
)
|
||||
|
||||
# On ne peut pas supprimer le code UE:
|
||||
if "ue_code" in args and not args["ue_code"]:
|
||||
|
@ -109,30 +109,10 @@ def do_evaluation_etat(evaluation_id, partition_id=None, select_first_partition=
|
||||
nb_inscrits = len(
|
||||
sco_groups.do_evaluation_listeetuds_groups(evaluation_id, getallstudents=True)
|
||||
)
|
||||
NotesDB = sco_evaluation_db.do_evaluation_get_all_notes(
|
||||
etuds_notes_dict = sco_evaluation_db.do_evaluation_get_all_notes(
|
||||
evaluation_id
|
||||
) # { etudid : value }
|
||||
notes = [x["value"] for x in NotesDB.values()]
|
||||
nb_abs = len([x for x in notes if x is None])
|
||||
nb_neutre = len([x for x in notes if x == scu.NOTES_NEUTRALISE])
|
||||
nb_att = len([x for x in notes if x == scu.NOTES_ATTENTE])
|
||||
moy_num, median_num, mini_num, maxi_num = notes_moyenne_median_mini_maxi(notes)
|
||||
if moy_num is None:
|
||||
median, moy = "", ""
|
||||
median_num, moy_num = None, None
|
||||
mini, maxi = "", ""
|
||||
mini_num, maxi_num = None, None
|
||||
else:
|
||||
median = scu.fmt_note(median_num)
|
||||
moy = scu.fmt_note(moy_num)
|
||||
mini = scu.fmt_note(mini_num)
|
||||
maxi = scu.fmt_note(maxi_num)
|
||||
# cherche date derniere modif note
|
||||
if len(NotesDB):
|
||||
t = [x["date"] for x in NotesDB.values()]
|
||||
last_modif = max(t)
|
||||
else:
|
||||
last_modif = None
|
||||
) # { etudid : note }
|
||||
|
||||
# ---- Liste des groupes complets et incomplets
|
||||
E = sco_evaluation_db.do_evaluation_list(args={"evaluation_id": evaluation_id})[0]
|
||||
M = sco_moduleimpl.moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
||||
@ -163,8 +143,32 @@ def do_evaluation_etat(evaluation_id, partition_id=None, select_first_partition=
|
||||
|
||||
# Nombre de notes valides d'étudiants inscrits au module
|
||||
# (car il peut y avoir des notes d'étudiants désinscrits depuis l'évaluation)
|
||||
nb_notes = len(insmodset.intersection(NotesDB))
|
||||
nb_notes_total = len(NotesDB)
|
||||
etudids_avec_note = insmodset.intersection(etuds_notes_dict)
|
||||
nb_notes = len(etudids_avec_note)
|
||||
# toutes saisies, y compris chez des non-inscrits:
|
||||
nb_notes_total = len(etuds_notes_dict)
|
||||
|
||||
notes = [etuds_notes_dict[etudid]["value"] for etudid in etudids_avec_note]
|
||||
nb_abs = len([x for x in notes if x is None])
|
||||
nb_neutre = len([x for x in notes if x == scu.NOTES_NEUTRALISE])
|
||||
nb_att = len([x for x in notes if x == scu.NOTES_ATTENTE])
|
||||
moy_num, median_num, mini_num, maxi_num = notes_moyenne_median_mini_maxi(notes)
|
||||
if moy_num is None:
|
||||
median, moy = "", ""
|
||||
median_num, moy_num = None, None
|
||||
mini, maxi = "", ""
|
||||
mini_num, maxi_num = None, None
|
||||
else:
|
||||
median = scu.fmt_note(median_num)
|
||||
moy = scu.fmt_note(moy_num)
|
||||
mini = scu.fmt_note(mini_num)
|
||||
maxi = scu.fmt_note(maxi_num)
|
||||
# cherche date derniere modif note
|
||||
if len(etuds_notes_dict):
|
||||
t = [x["date"] for x in etuds_notes_dict.values()]
|
||||
last_modif = max(t)
|
||||
else:
|
||||
last_modif = None
|
||||
|
||||
# On considere une note "manquante" lorsqu'elle n'existe pas
|
||||
# ou qu'elle est en attente (ATT)
|
||||
@ -181,8 +185,8 @@ def do_evaluation_etat(evaluation_id, partition_id=None, select_first_partition=
|
||||
groups[group["group_id"]] = group
|
||||
#
|
||||
isMissing = False
|
||||
if i["etudid"] in NotesDB:
|
||||
val = NotesDB[i["etudid"]]["value"]
|
||||
if i["etudid"] in etuds_notes_dict:
|
||||
val = etuds_notes_dict[i["etudid"]]["value"]
|
||||
if val == scu.NOTES_ATTENTE:
|
||||
isMissing = True
|
||||
TotalNbAtt += 1
|
||||
|
@ -230,9 +230,10 @@ def formation_import_xml(doc: str, import_tags=True):
|
||||
ue_id = sco_edit_ue.do_ue_create(ue_info[1])
|
||||
if xml_ue_id:
|
||||
ues_old2new[xml_ue_id] = ue_id
|
||||
ue_reference = int(ue_info[1].get("reference"))
|
||||
# élément optionnel présent dans les exports BUT:
|
||||
ue_reference = ue_info[1].get("reference")
|
||||
if ue_reference:
|
||||
ue_reference_to_id[ue_reference] = ue_id
|
||||
ue_reference_to_id[int(ue_reference)] = ue_id
|
||||
# -- create matieres
|
||||
for mat_info in ue_info[2]:
|
||||
assert mat_info[0] == "matiere"
|
||||
|
@ -66,7 +66,9 @@ def do_formsemestre_inscription_list(*args, **kw):
|
||||
|
||||
|
||||
def do_formsemestre_inscription_listinscrits(formsemestre_id):
|
||||
"""Liste les inscrits (état I) à ce semestre et cache le résultat"""
|
||||
"""Liste les inscrits (état I) à ce semestre et cache le résultat.
|
||||
Result: [ { "etudid":, "formsemestre_id": , "etat": , "etape": }]
|
||||
"""
|
||||
r = sco_cache.SemInscriptionsCache.get(formsemestre_id)
|
||||
if r is None:
|
||||
# retreive list
|
||||
|
@ -1210,6 +1210,7 @@ def formsemestre_tableau_modules(
|
||||
)
|
||||
|
||||
if mod.module_type in (
|
||||
None, # ne devrait pas être nécessaire car la migration a remplacé les NULLs
|
||||
ModuleType.STANDARD,
|
||||
ModuleType.RESSOURCE,
|
||||
ModuleType.SAE,
|
||||
@ -1249,7 +1250,7 @@ def formsemestre_tableau_modules(
|
||||
% (modimpl["moduleimpl_id"], nb_malus_notes)
|
||||
)
|
||||
else:
|
||||
raise ValueError("Invalid module_type") # a bug
|
||||
raise ValueError(f"Invalid module_type {mod.module_type}") # a bug
|
||||
|
||||
H.append("</td></tr>")
|
||||
return "\n".join(H)
|
||||
|
@ -35,7 +35,6 @@ Optimisation possible:
|
||||
"""
|
||||
import collections
|
||||
import operator
|
||||
import re
|
||||
import time
|
||||
|
||||
from xml.etree import ElementTree
|
||||
@ -45,6 +44,7 @@ import flask
|
||||
from flask import g, request
|
||||
from flask import url_for, make_response
|
||||
|
||||
from app import db
|
||||
from app.models.groups import Partition
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
|
@ -32,6 +32,7 @@ import flask
|
||||
from flask import url_for, g, request
|
||||
|
||||
from app import models
|
||||
from app.models.evaluations import Evaluation
|
||||
from app.models.moduleimpls import ModuleImpl
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
@ -53,35 +54,34 @@ from app.scodoc.gen_tables import GenTable
|
||||
from app.scodoc.htmlutils import histogram_notes
|
||||
|
||||
|
||||
def do_evaluation_listenotes():
|
||||
def do_evaluation_listenotes(
|
||||
evaluation_id=None, moduleimpl_id=None, format="html"
|
||||
) -> str:
|
||||
"""
|
||||
Affichage des notes d'une évaluation
|
||||
|
||||
args: evaluation_id ou moduleimpl_id
|
||||
(si moduleimpl_id, affiche toutes les évaluations du module)
|
||||
Affichage des notes d'une évaluation (si evaluation_id)
|
||||
ou de toutes les évaluations d'un module (si moduleimpl_id)
|
||||
"""
|
||||
mode = None
|
||||
vals = scu.get_request_args()
|
||||
if "evaluation_id" in vals:
|
||||
evaluation_id = int(vals["evaluation_id"])
|
||||
mode = "eval"
|
||||
evals = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||
if "moduleimpl_id" in vals and vals["moduleimpl_id"]:
|
||||
moduleimpl_id = int(vals["moduleimpl_id"])
|
||||
if moduleimpl_id:
|
||||
mode = "module"
|
||||
evals = sco_evaluation_db.do_evaluation_list({"moduleimpl_id": moduleimpl_id})
|
||||
if not mode:
|
||||
elif evaluation_id:
|
||||
mode = "eval"
|
||||
evals = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})
|
||||
else:
|
||||
raise ValueError("missing argument: evaluation or module")
|
||||
if not evals:
|
||||
return "<p>Aucune évaluation !</p>"
|
||||
|
||||
format = vals.get("format", "html")
|
||||
E = evals[0] # il y a au moins une evaluation
|
||||
modimpl = ModuleImpl.query.get(E["moduleimpl_id"])
|
||||
# description de l'evaluation
|
||||
if mode == "eval":
|
||||
H = [sco_evaluations.evaluation_describe(evaluation_id=evaluation_id)]
|
||||
page_title = f"Notes {E['description'] or modimpl.module.code}"
|
||||
else:
|
||||
H = []
|
||||
page_title = f"Notes {modimpl.module.code}"
|
||||
# groupes
|
||||
groups = sco_groups.do_evaluation_listegroupes(
|
||||
E["evaluation_id"], include_default=True
|
||||
@ -187,7 +187,7 @@ def do_evaluation_listenotes():
|
||||
is_submitted=True, # toujours "soumis" (démarre avec liste complète)
|
||||
)
|
||||
if tf[0] == 0:
|
||||
return "\n".join(H) + "\n" + tf[1]
|
||||
return "\n".join(H) + "\n" + tf[1], page_title
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(
|
||||
"%s/Notes/moduleimpl_status?moduleimpl_id=%s"
|
||||
@ -198,16 +198,19 @@ def do_evaluation_listenotes():
|
||||
note_sur_20 = tf[2]["note_sur_20"]
|
||||
hide_groups = tf[2]["hide_groups"]
|
||||
with_emails = tf[2]["with_emails"]
|
||||
return _make_table_notes(
|
||||
tf[1],
|
||||
evals,
|
||||
format=format,
|
||||
note_sur_20=note_sur_20,
|
||||
anonymous_listing=anonymous_listing,
|
||||
group_ids=tf[2]["group_ids"],
|
||||
hide_groups=hide_groups,
|
||||
with_emails=with_emails,
|
||||
mode=mode,
|
||||
return (
|
||||
_make_table_notes(
|
||||
tf[1],
|
||||
evals,
|
||||
format=format,
|
||||
note_sur_20=note_sur_20,
|
||||
anonymous_listing=anonymous_listing,
|
||||
group_ids=tf[2]["group_ids"],
|
||||
hide_groups=hide_groups,
|
||||
with_emails=with_emails,
|
||||
mode=mode,
|
||||
),
|
||||
page_title,
|
||||
)
|
||||
|
||||
|
||||
@ -393,6 +396,7 @@ def _make_table_notes(
|
||||
key_mgr,
|
||||
note_sur_20,
|
||||
keep_numeric,
|
||||
format=format,
|
||||
)
|
||||
columns_ids.append(e["evaluation_id"])
|
||||
#
|
||||
@ -406,7 +410,7 @@ def _make_table_notes(
|
||||
# Si module, ajoute la (les) "moyenne(s) du module:
|
||||
if mode == "module":
|
||||
if len(evals) > 1:
|
||||
# Moyenne de l'étudant dans le module
|
||||
# Moyenne de l'étudiant dans le module
|
||||
# Affichée même en APC à titre indicatif
|
||||
_add_moymod_column(
|
||||
sem["formsemestre_id"],
|
||||
@ -635,6 +639,7 @@ def _add_eval_columns(
|
||||
K,
|
||||
note_sur_20,
|
||||
keep_numeric,
|
||||
format="html",
|
||||
):
|
||||
"""Add eval e"""
|
||||
nb_notes = 0
|
||||
@ -643,6 +648,7 @@ def _add_eval_columns(
|
||||
sum_notes = 0
|
||||
notes = [] # liste des notes numeriques, pour calcul histogramme uniquement
|
||||
evaluation_id = e["evaluation_id"]
|
||||
e_o = Evaluation.query.get(evaluation_id) # XXX en attendant ré-écriture
|
||||
NotesDB = sco_evaluation_db.do_evaluation_get_all_notes(evaluation_id)
|
||||
for row in rows:
|
||||
etudid = row["etudid"]
|
||||
@ -704,9 +710,12 @@ def _add_eval_columns(
|
||||
|
||||
row_coefs[evaluation_id] = "coef. %s" % e["coefficient"]
|
||||
if is_apc:
|
||||
row_poids[evaluation_id] = _mini_table_eval_ue_poids(
|
||||
evaluation_id, evals_poids, ues
|
||||
)
|
||||
if format == "html":
|
||||
row_poids[evaluation_id] = _mini_table_eval_ue_poids(
|
||||
evaluation_id, evals_poids, ues
|
||||
)
|
||||
else:
|
||||
row_poids[evaluation_id] = e_o.get_ue_poids_str()
|
||||
if note_sur_20:
|
||||
nmax = 20.0
|
||||
else:
|
||||
|
@ -31,9 +31,10 @@ import time
|
||||
|
||||
from flask import g, url_for
|
||||
from flask_login import current_user
|
||||
from app.auth.models import User
|
||||
|
||||
from app.auth.models import User
|
||||
from app.models import ModuleImpl
|
||||
from app.models.evaluations import Evaluation
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
@ -391,8 +392,9 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
)
|
||||
H.append("""<table class="moduleimpl_evaluations">""")
|
||||
eval_index = len(mod_evals) - 1
|
||||
first = True
|
||||
first_eval = True
|
||||
for eval in mod_evals:
|
||||
evaluation = Evaluation.query.get(eval["evaluation_id"]) # TODO unifier
|
||||
etat = sco_evaluations.do_evaluation_etat(
|
||||
eval["evaluation_id"],
|
||||
partition_id=partition_id,
|
||||
@ -406,9 +408,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
else:
|
||||
tr_class = "mievr"
|
||||
tr_class_1 = "mievr"
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
if not first_eval:
|
||||
H.append("""<tr><td colspan="8"> </td></tr>""")
|
||||
tr_class_1 += " mievr_spaced"
|
||||
H.append("""<tr class="%s"><td class="mievr_tit" colspan="8">""" % tr_class_1)
|
||||
@ -586,19 +586,35 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
H.append("""</td></tr>""")
|
||||
#
|
||||
if etat["nb_notes"] == 0:
|
||||
H.append("""<tr class="%s"><td colspan="8"> """ % tr_class)
|
||||
H.append("""</td></tr>""")
|
||||
H.append("""<tr class="%s"><td></td>""" % tr_class)
|
||||
if modimpl.module.is_apc():
|
||||
H.append(
|
||||
f"""<td colspan="7" class="eval_poids">{
|
||||
evaluation.get_ue_poids_str()}</td>"""
|
||||
)
|
||||
else:
|
||||
H.append('<td colspan="7"></td>')
|
||||
H.append("""</tr>""")
|
||||
else: # il y a deja des notes saisies
|
||||
gr_moyennes = etat["gr_moyennes"]
|
||||
first_group = True
|
||||
for gr_moyenne in gr_moyennes:
|
||||
H.append("""<tr class="%s">""" % tr_class)
|
||||
H.append("""<td colspan="2"> </td>""")
|
||||
H.append("""<td> </td>""")
|
||||
if first_group and modimpl.module.is_apc():
|
||||
H.append(
|
||||
f"""<td class="eval_poids" colspan="3">{
|
||||
evaluation.get_ue_poids_str()}</td>"""
|
||||
)
|
||||
else:
|
||||
H.append("""<td colspan="3"></td>""")
|
||||
first_group = False
|
||||
if gr_moyenne["group_name"] is None:
|
||||
name = "Tous" # tous
|
||||
else:
|
||||
name = "Groupe %s" % gr_moyenne["group_name"]
|
||||
H.append(
|
||||
"""<td colspan="5" class="mievr_grtit">%s </td><td>""" % name
|
||||
"""<td colspan="3" class="mievr_grtit">%s </td><td>""" % name
|
||||
)
|
||||
if gr_moyenne["gr_nb_notes"] > 0:
|
||||
H.append("%(gr_moy)s" % gr_moyenne)
|
||||
@ -637,6 +653,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
||||
H.append("""</a>""")
|
||||
H.append("</span>")
|
||||
H.append("""</td></tr>""")
|
||||
first_eval = False
|
||||
|
||||
#
|
||||
if caneditevals or not sem["etat"]:
|
||||
|
@ -37,7 +37,8 @@ from flask import make_response
|
||||
|
||||
from app import log
|
||||
from app.but import bulletin_but
|
||||
from app.models import FormSemestre, UniteEns, Module, ModuleImpl
|
||||
from app.models import FormSemestre
|
||||
from app.models.etudiants import Identite
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc import html_sco_header
|
||||
@ -937,6 +938,9 @@ def _formsemestre_recapcomplet_json(
|
||||
:param force_publishing: donne les bulletins même si non "publiés sur portail"
|
||||
:returns: dict, "", "json"
|
||||
"""
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
is_apc = formsemestre.formation.is_apc()
|
||||
|
||||
if xml_nodate:
|
||||
docdate = ""
|
||||
else:
|
||||
@ -958,14 +962,18 @@ def _formsemestre_recapcomplet_json(
|
||||
T = nt.get_table_moyennes_triees()
|
||||
for t in T:
|
||||
etudid = t[-1]
|
||||
bulletins.append(
|
||||
sco_bulletins_json.formsemestre_bulletinetud_published_dict(
|
||||
if is_apc:
|
||||
etud = Identite.query.get(etudid)
|
||||
r = bulletin_but.ResultatsSemestreBUT(formsemestre)
|
||||
bul = r.bulletin_etud(etud, formsemestre)
|
||||
else:
|
||||
bul = sco_bulletins_json.formsemestre_bulletinetud_published_dict(
|
||||
formsemestre_id,
|
||||
etudid,
|
||||
force_publishing=force_publishing,
|
||||
xml_with_decisions=xml_with_decisions,
|
||||
)
|
||||
)
|
||||
bulletins.append(bul)
|
||||
return J, "", "json"
|
||||
|
||||
|
||||
|
@ -408,7 +408,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
|
||||
|
||||
if not dialog_confirmed:
|
||||
nb_changed, nb_suppress, existing_decisions = notes_add(
|
||||
current_user, evaluation_id, notes, do_it=False
|
||||
current_user, evaluation_id, notes, do_it=False, check_inscription=False
|
||||
)
|
||||
msg = (
|
||||
"<p>Confirmer la suppression des %d notes ? <em>(peut affecter plusieurs groupes)</em></p>"
|
||||
@ -426,7 +426,11 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
|
||||
|
||||
# modif
|
||||
nb_changed, nb_suppress, existing_decisions = notes_add(
|
||||
current_user, evaluation_id, notes, comment="effacer tout"
|
||||
current_user,
|
||||
evaluation_id,
|
||||
notes,
|
||||
comment="effacer tout",
|
||||
check_inscription=False,
|
||||
)
|
||||
assert nb_changed == nb_suppress
|
||||
H = ["<p>%s notes supprimées</p>" % nb_suppress]
|
||||
@ -454,7 +458,14 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
|
||||
return html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer()
|
||||
|
||||
|
||||
def notes_add(user, evaluation_id: int, notes: list, comment=None, do_it=True) -> tuple:
|
||||
def notes_add(
|
||||
user,
|
||||
evaluation_id: int,
|
||||
notes: list,
|
||||
comment=None,
|
||||
do_it=True,
|
||||
check_inscription=True,
|
||||
) -> tuple:
|
||||
"""
|
||||
Insert or update notes
|
||||
notes is a list of tuples (etudid,value)
|
||||
@ -475,7 +486,7 @@ def notes_add(user, evaluation_id: int, notes: list, comment=None, do_it=True) -
|
||||
)
|
||||
}
|
||||
for (etudid, value) in notes:
|
||||
if etudid not in inscrits:
|
||||
if check_inscription and (etudid not in inscrits):
|
||||
raise NoteProcessError("etudiant non inscrit dans ce module")
|
||||
if not ((value is None) or (type(value) == type(1.0))):
|
||||
raise NoteProcessError(
|
||||
|
@ -16,7 +16,7 @@ main{
|
||||
--couleurPrincipale: rgb(240,250,255);
|
||||
--couleurFondTitresUE: rgb(206,255,235);
|
||||
--couleurFondTitresRes: rgb(125, 170, 255);
|
||||
--couleurFondTitresSAE: rgb(255, 190, 69);
|
||||
--couleurFondTitresSAE: rgb(211, 255, 255);
|
||||
--couleurSecondaire: #fec;
|
||||
--couleurIntense: #c09;
|
||||
--couleurSurlignage: rgba(232, 255, 132, 0.47);
|
||||
|
@ -1476,6 +1476,9 @@ span.evalindex {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
table.moduleimpl_evaluations td.eval_poids {
|
||||
color:rgb(0, 0, 255);
|
||||
}
|
||||
|
||||
/* Formulaire edition des partitions */
|
||||
form#editpart table {
|
||||
|
@ -12,7 +12,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{% if title %}{{ title }} - ScoDoc{% else %}Welcome to ScoDoc{% endif %}
|
||||
{% if title %}{{ title }} - ScoDoc{% else %}ScoDoc{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
@ -31,9 +31,9 @@
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% if sco.sem %}
|
||||
{% block formsemestre_header %}
|
||||
{% include "formsemestre_header.html" %}
|
||||
{% endblock %}
|
||||
{% block formsemestre_header %}
|
||||
{% include "formsemestre_header.html" %}
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% block app_content %}
|
||||
|
@ -285,6 +285,8 @@ def formsemestre_bulletinetud(
|
||||
prefer_mail_perso=False,
|
||||
code_nip=None,
|
||||
):
|
||||
if not formsemestre_id:
|
||||
flask.abort(404, "argument manquant: formsemestre_id")
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
if formsemestre.formation.is_apc() and format != "oldjson":
|
||||
if etudid:
|
||||
@ -299,7 +301,7 @@ def formsemestre_bulletinetud(
|
||||
elif format == "html":
|
||||
return render_template(
|
||||
"but/bulletin.html",
|
||||
title="Bulletin BUT",
|
||||
title=f"Bul. {etud.nom} - BUT",
|
||||
bul_url=url_for(
|
||||
"notes.formsemestre_bulletinetud",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
@ -1726,27 +1728,33 @@ def evaluation_create(moduleimpl_id):
|
||||
@scodoc7func
|
||||
def evaluation_listenotes():
|
||||
"""Affichage des notes d'une évaluation"""
|
||||
if request.args.get("format", "html") == "html":
|
||||
evaluation_id = None
|
||||
moduleimpl_id = None
|
||||
vals = scu.get_request_args()
|
||||
if "evaluation_id" in vals:
|
||||
evaluation_id = int(vals["evaluation_id"])
|
||||
mode = "eval"
|
||||
if "moduleimpl_id" in vals and vals["moduleimpl_id"]:
|
||||
moduleimpl_id = int(vals["moduleimpl_id"])
|
||||
mode = "module"
|
||||
|
||||
format = vals.get("format", "html")
|
||||
B, page_title = sco_liste_notes.do_evaluation_listenotes(
|
||||
evaluation_id=evaluation_id, moduleimpl_id=moduleimpl_id, format=format
|
||||
)
|
||||
if format == "html":
|
||||
H = html_sco_header.sco_header(
|
||||
page_title=page_title,
|
||||
cssstyles=["css/verticalhisto.css"],
|
||||
javascripts=["js/etud_info.js"],
|
||||
init_qtip=True,
|
||||
)
|
||||
F = html_sco_header.sco_footer()
|
||||
else:
|
||||
H, F = "", ""
|
||||
B = sco_liste_notes.do_evaluation_listenotes()
|
||||
if H:
|
||||
return H + B + F
|
||||
else:
|
||||
return B
|
||||
|
||||
|
||||
sco_publish(
|
||||
"/do_evaluation_listenotes",
|
||||
sco_liste_notes.do_evaluation_listenotes,
|
||||
Permission.ScoView,
|
||||
)
|
||||
sco_publish(
|
||||
"/evaluation_list_operations",
|
||||
sco_undo_notes.evaluation_list_operations,
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.1.10"
|
||||
SCOVERSION = "9.1.11"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user