forked from ScoDoc/ScoDoc
Import utilisateurs: strip champs
This commit is contained in:
parent
c94fea9f9e
commit
07c2f00277
@ -973,7 +973,7 @@ class FormSemestre(models.ScoDocModel):
|
|||||||
|
|
||||||
def etudids_actifs(self) -> tuple[list[int], set[int]]:
|
def etudids_actifs(self) -> tuple[list[int], set[int]]:
|
||||||
"""Liste les etudids inscrits (incluant DEM et DEF),
|
"""Liste les etudids inscrits (incluant DEM et DEF),
|
||||||
qui ser al'index des dataframes de notes
|
qui sera l'index des dataframes de notes
|
||||||
et donne l'ensemble des inscrits non DEM ni DEF.
|
et donne l'ensemble des inscrits non DEM ni DEF.
|
||||||
"""
|
"""
|
||||||
return [inscr.etudid for inscr in self.inscriptions], {
|
return [inscr.etudid for inscr in self.inscriptions], {
|
||||||
|
@ -140,7 +140,7 @@ def read_users_excel_file(datafile, titles=TITLES) -> list[dict]:
|
|||||||
for line in data[1:]:
|
for line in data[1:]:
|
||||||
d = {}
|
d = {}
|
||||||
for i, field in enumerate(xls_titles):
|
for i, field in enumerate(xls_titles):
|
||||||
d[field] = line[i]
|
d[field] = (line[i] or "").strip()
|
||||||
users.append(d)
|
users.append(d)
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
@ -70,13 +70,21 @@ def moduleimpl_evaluation_menu(evaluation: Evaluation, nbnotes: int = 0) -> str:
|
|||||||
|
|
||||||
menu_eval = [
|
menu_eval = [
|
||||||
{
|
{
|
||||||
"title": "Saisir notes",
|
"title": "Saisir les notes",
|
||||||
"endpoint": "notes.saisie_notes",
|
"endpoint": "notes.saisie_notes",
|
||||||
"args": {
|
"args": {
|
||||||
"evaluation_id": evaluation_id,
|
"evaluation_id": evaluation_id,
|
||||||
},
|
},
|
||||||
"enabled": can_edit_notes_ens,
|
"enabled": can_edit_notes_ens,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Saisir par fichier tableur",
|
||||||
|
"id": "menu_saisie_tableur",
|
||||||
|
"endpoint": "notes.saisie_notes_tableur",
|
||||||
|
"args": {
|
||||||
|
"evaluation_id": evaluation.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Modifier évaluation",
|
"title": "Modifier évaluation",
|
||||||
"endpoint": "notes.evaluation_edit",
|
"endpoint": "notes.evaluation_edit",
|
||||||
|
@ -29,12 +29,15 @@
|
|||||||
|
|
||||||
Formulaire revu en juillet 2016
|
Formulaire revu en juillet 2016
|
||||||
"""
|
"""
|
||||||
|
import html
|
||||||
import time
|
import time
|
||||||
import psycopg2
|
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import g, url_for, request
|
from flask import g, url_for, request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
from flask_sqlalchemy.query import Query
|
||||||
|
import psycopg2
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
@ -75,8 +78,6 @@ import app.scodoc.sco_utils as scu
|
|||||||
from app.scodoc.sco_utils import json_error
|
from app.scodoc.sco_utils import json_error
|
||||||
from app.scodoc.sco_utils import ModuleType
|
from app.scodoc.sco_utils import ModuleType
|
||||||
|
|
||||||
from flask_sqlalchemy.query import Query
|
|
||||||
|
|
||||||
|
|
||||||
def convert_note_from_string(
|
def convert_note_from_string(
|
||||||
note: str,
|
note: str,
|
||||||
@ -115,7 +116,7 @@ def convert_note_from_string(
|
|||||||
return note_value, invalid
|
return note_value, invalid
|
||||||
|
|
||||||
|
|
||||||
def _displayNote(val):
|
def _display_note(val):
|
||||||
"""Convert note from DB to viewable string.
|
"""Convert note from DB to viewable string.
|
||||||
Utilisé seulement pour I/O vers formulaires (sans perte de precision)
|
Utilisé seulement pour I/O vers formulaires (sans perte de precision)
|
||||||
(Utiliser fmt_note pour les affichages)
|
(Utiliser fmt_note pour les affichages)
|
||||||
@ -272,7 +273,7 @@ def do_evaluation_upload_xls():
|
|||||||
diag.append("Notes invalides pour: " + ", ".join(etudsnames))
|
diag.append("Notes invalides pour: " + ", ".join(etudsnames))
|
||||||
raise InvalidNoteValue()
|
raise InvalidNoteValue()
|
||||||
else:
|
else:
|
||||||
etudids_changed, nb_suppress, etudids_with_decisions = notes_add(
|
etudids_changed, nb_suppress, etudids_with_decisions, messages = notes_add(
|
||||||
current_user, evaluation_id, valid_notes, comment
|
current_user, evaluation_id, valid_notes, comment
|
||||||
)
|
)
|
||||||
# news
|
# news
|
||||||
@ -292,9 +293,19 @@ def do_evaluation_upload_xls():
|
|||||||
max_frequency=30 * 60, # 30 minutes
|
max_frequency=30 * 60, # 30 minutes
|
||||||
)
|
)
|
||||||
|
|
||||||
msg = f"""<p>{len(etudids_changed)} notes changées ({len(withoutnotes)} sans notes, {
|
msg = f"""<p>
|
||||||
len(absents)} absents, {nb_suppress} note supprimées)
|
{len(etudids_changed)} notes changées ({len(withoutnotes)} sans notes,
|
||||||
|
{len(absents)} absents, {nb_suppress} note supprimées)
|
||||||
</p>"""
|
</p>"""
|
||||||
|
if messages:
|
||||||
|
msg += f"""<div class="warning">Attention :
|
||||||
|
<ul>
|
||||||
|
<li>{
|
||||||
|
'</li><li>'.join(messages)
|
||||||
|
}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>"""
|
||||||
if etudids_with_decisions:
|
if etudids_with_decisions:
|
||||||
msg += """<p class="warning">Important: il y avait déjà des décisions de jury
|
msg += """<p class="warning">Important: il y avait déjà des décisions de jury
|
||||||
enregistrées, qui sont peut-être à revoir suite à cette modification !</p>
|
enregistrées, qui sont peut-être à revoir suite à cette modification !</p>
|
||||||
@ -322,7 +333,7 @@ def do_evaluation_set_etud_note(evaluation: Evaluation, etud: Identite, value) -
|
|||||||
# Convert and check value
|
# Convert and check value
|
||||||
L, invalids, _, _, _ = _check_notes([(etud.id, value)], evaluation)
|
L, invalids, _, _, _ = _check_notes([(etud.id, value)], evaluation)
|
||||||
if len(invalids) == 0:
|
if len(invalids) == 0:
|
||||||
etudids_changed, _, _ = notes_add(
|
etudids_changed, _, _, _ = notes_add(
|
||||||
current_user, evaluation.id, L, "Initialisation notes"
|
current_user, evaluation.id, L, "Initialisation notes"
|
||||||
)
|
)
|
||||||
if len(etudids_changed) == 1:
|
if len(etudids_changed) == 1:
|
||||||
@ -398,7 +409,9 @@ def do_evaluation_set_missing(
|
|||||||
)
|
)
|
||||||
# ok
|
# ok
|
||||||
comment = "Initialisation notes manquantes"
|
comment = "Initialisation notes manquantes"
|
||||||
etudids_changed, _, _ = notes_add(current_user, evaluation_id, valid_notes, comment)
|
etudids_changed, _, _, _ = notes_add(
|
||||||
|
current_user, evaluation_id, valid_notes, comment
|
||||||
|
)
|
||||||
# news
|
# news
|
||||||
url = url_for(
|
url = url_for(
|
||||||
"notes.moduleimpl_status",
|
"notes.moduleimpl_status",
|
||||||
@ -456,7 +469,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
etudids_changed, nb_suppress, existing_decisions = notes_add(
|
etudids_changed, nb_suppress, existing_decisions, _ = notes_add(
|
||||||
current_user, evaluation_id, notes, do_it=False, check_inscription=False
|
current_user, evaluation_id, notes, do_it=False, check_inscription=False
|
||||||
)
|
)
|
||||||
msg = f"""<p>Confirmer la suppression des {nb_suppress} notes ?
|
msg = f"""<p>Confirmer la suppression des {nb_suppress} notes ?
|
||||||
@ -477,7 +490,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# modif
|
# modif
|
||||||
etudids_changed, nb_suppress, existing_decisions = notes_add(
|
etudids_changed, nb_suppress, existing_decisions, _ = notes_add(
|
||||||
current_user,
|
current_user,
|
||||||
evaluation_id,
|
evaluation_id,
|
||||||
notes,
|
notes,
|
||||||
@ -519,7 +532,7 @@ def notes_add(
|
|||||||
comment=None,
|
comment=None,
|
||||||
do_it=True,
|
do_it=True,
|
||||||
check_inscription=True,
|
check_inscription=True,
|
||||||
) -> tuple[list[int], int, list[int]]:
|
) -> tuple[list[int], int, list[int], list[str]]:
|
||||||
"""
|
"""
|
||||||
Insert or update notes
|
Insert or update notes
|
||||||
notes is a list of tuples (etudid,value)
|
notes is a list of tuples (etudid,value)
|
||||||
@ -528,30 +541,48 @@ def notes_add(
|
|||||||
Nota:
|
Nota:
|
||||||
- si la note existe deja avec valeur distincte, ajoute une entree au log (notes_notes_log)
|
- si la note existe deja avec valeur distincte, ajoute une entree au log (notes_notes_log)
|
||||||
|
|
||||||
Return: tuple (etudids_changed, nb_suppress, etudids_with_decision)
|
Return: tuple (etudids_changed, nb_suppress, etudids_with_decision, messages)
|
||||||
|
|
||||||
|
messages = list de messages d'avertissement/information pour l'utilisateur
|
||||||
"""
|
"""
|
||||||
evaluation = Evaluation.get_evaluation(evaluation_id)
|
evaluation = Evaluation.get_evaluation(evaluation_id)
|
||||||
now = psycopg2.Timestamp(*time.localtime()[:6])
|
now = psycopg2.Timestamp(*time.localtime()[:6])
|
||||||
|
messages = []
|
||||||
# Vérifie inscription et valeur note
|
# Vérifie inscription au module (même DEM/DEF)
|
||||||
inscrits = {
|
etudids_inscrits_mod = {
|
||||||
x[0]
|
x[0]
|
||||||
for x in sco_groups.do_evaluation_listeetuds_groups(
|
for x in sco_groups.do_evaluation_listeetuds_groups(
|
||||||
evaluation_id, getallstudents=True, include_demdef=True
|
evaluation_id, getallstudents=True, include_demdef=True
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
# Les étudiants inscrits au semestre ni DEM ni DEF
|
# Les étudiants inscrits au semestre et ceux "actifs" (ni DEM ni DEF)
|
||||||
_, etudids_actifs = evaluation.moduleimpl.formsemestre.etudids_actifs()
|
etudids_inscrits_sem, etudids_actifs = (
|
||||||
|
evaluation.moduleimpl.formsemestre.etudids_actifs()
|
||||||
|
)
|
||||||
for etudid, value in notes:
|
for etudid, value in notes:
|
||||||
if check_inscription and (
|
|
||||||
(etudid not in inscrits) or (etudid not in etudids_actifs)
|
if check_inscription:
|
||||||
):
|
msg_err, msg_warn = "", ""
|
||||||
log(f"notes_add: {etudid} non inscrit ou DEM/DEF: aborting")
|
if etudid not in etudids_inscrits_sem:
|
||||||
raise NoteProcessError(f"étudiant {etudid} non inscrit dans ce module")
|
msg_err = "non inscrit au semestre"
|
||||||
|
elif etudid not in etudids_inscrits_mod:
|
||||||
|
msg_err = "non inscrit au module"
|
||||||
|
elif etudid not in etudids_actifs:
|
||||||
|
# DEM ou DEF
|
||||||
|
msg_warn = "démissionnaire ou défaillant (note enregistrée)"
|
||||||
|
if msg_err or msg_warn:
|
||||||
|
etud = Identite.query.get(etudid) if isinstance(etudid, int) else None
|
||||||
|
msg = f"étudiant {etud.nomprenom if etud else etudid} {msg_err or msg_warn}"
|
||||||
|
if msg_err:
|
||||||
|
log(f"notes_add: {etudid} non inscrit ou DEM/DEF: aborting")
|
||||||
|
raise NoteProcessError(msg)
|
||||||
|
if msg_warn:
|
||||||
|
messages.append(msg)
|
||||||
if (value is not None) and not isinstance(value, float):
|
if (value is not None) and not isinstance(value, float):
|
||||||
log(f"notes_add: {etudid} valeur de note invalide ({value}): aborting")
|
log(f"notes_add: {etudid} valeur de note invalide ({value}): aborting")
|
||||||
|
etud = Identite.query.get(etudid) if isinstance(etudid, int) else None
|
||||||
raise NoteProcessError(
|
raise NoteProcessError(
|
||||||
f"etudiant {etudid}: valeur de note invalide ({value})"
|
f"etudiant {etud.nomprenom if etud else etudid}: valeur de note invalide ({value})"
|
||||||
)
|
)
|
||||||
# Recherche notes existantes
|
# Recherche notes existantes
|
||||||
notes_db = sco_evaluation_db.do_evaluation_get_all_notes(evaluation_id)
|
notes_db = sco_evaluation_db.do_evaluation_get_all_notes(evaluation_id)
|
||||||
@ -566,102 +597,20 @@ def notes_add(
|
|||||||
etudids_with_decision = []
|
etudids_with_decision = []
|
||||||
try:
|
try:
|
||||||
for etudid, value in notes:
|
for etudid, value in notes:
|
||||||
changed = False
|
changed, suppressed = _record_note(
|
||||||
if etudid not in notes_db:
|
cursor,
|
||||||
# nouvelle note
|
notes_db,
|
||||||
if value != scu.NOTES_SUPPRESS:
|
etudid,
|
||||||
if do_it:
|
evaluation_id,
|
||||||
args = {
|
value,
|
||||||
"etudid": etudid,
|
comment=comment,
|
||||||
"evaluation_id": evaluation_id,
|
user=user,
|
||||||
"value": value,
|
date=now,
|
||||||
"comment": comment,
|
do_it=do_it,
|
||||||
"uid": user.id,
|
)
|
||||||
"date": now,
|
if suppressed:
|
||||||
}
|
nb_suppress += 1
|
||||||
ndb.quote_dict(args)
|
|
||||||
# Note: le conflit ci-dessous peut arriver si un autre thread
|
|
||||||
# a modifié la base après qu'on ait lu notes_db
|
|
||||||
cursor.execute(
|
|
||||||
"""INSERT INTO notes_notes
|
|
||||||
(etudid, evaluation_id, value, comment, date, uid)
|
|
||||||
VALUES
|
|
||||||
(%(etudid)s,%(evaluation_id)s,%(value)s,
|
|
||||||
%(comment)s,%(date)s,%(uid)s)
|
|
||||||
ON CONFLICT ON CONSTRAINT notes_notes_etudid_evaluation_id_key
|
|
||||||
DO UPDATE SET etudid=%(etudid)s, evaluation_id=%(evaluation_id)s,
|
|
||||||
value=%(value)s, comment=%(comment)s, date=%(date)s, uid=%(uid)s
|
|
||||||
""",
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
changed = True
|
|
||||||
else:
|
|
||||||
# il y a deja une note
|
|
||||||
oldval = notes_db[etudid]["value"]
|
|
||||||
if type(value) != type(oldval):
|
|
||||||
changed = True
|
|
||||||
elif isinstance(value, float) and (
|
|
||||||
abs(value - oldval) > scu.NOTES_PRECISION
|
|
||||||
):
|
|
||||||
changed = True
|
|
||||||
elif value != oldval:
|
|
||||||
changed = True
|
|
||||||
if changed:
|
|
||||||
# recopie l'ancienne note dans notes_notes_log, puis update
|
|
||||||
if do_it:
|
|
||||||
cursor.execute(
|
|
||||||
"""INSERT INTO notes_notes_log
|
|
||||||
(etudid,evaluation_id,value,comment,date,uid)
|
|
||||||
SELECT etudid, evaluation_id, value, comment, date, uid
|
|
||||||
FROM notes_notes
|
|
||||||
WHERE etudid=%(etudid)s
|
|
||||||
and evaluation_id=%(evaluation_id)s
|
|
||||||
""",
|
|
||||||
{"etudid": etudid, "evaluation_id": evaluation_id},
|
|
||||||
)
|
|
||||||
args = {
|
|
||||||
"etudid": etudid,
|
|
||||||
"evaluation_id": evaluation_id,
|
|
||||||
"value": value,
|
|
||||||
"date": now,
|
|
||||||
"comment": comment,
|
|
||||||
"uid": user.id,
|
|
||||||
}
|
|
||||||
ndb.quote_dict(args)
|
|
||||||
if value != scu.NOTES_SUPPRESS:
|
|
||||||
if do_it:
|
|
||||||
cursor.execute(
|
|
||||||
"""UPDATE notes_notes
|
|
||||||
SET value=%(value)s, comment=%(comment)s, date=%(date)s, uid=%(uid)s
|
|
||||||
WHERE etudid = %(etudid)s
|
|
||||||
and evaluation_id = %(evaluation_id)s
|
|
||||||
""",
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
else: # suppression ancienne note
|
|
||||||
if do_it:
|
|
||||||
log(
|
|
||||||
f"""notes_add, suppress, evaluation_id={evaluation_id}, etudid={
|
|
||||||
etudid}, oldval={oldval}"""
|
|
||||||
)
|
|
||||||
cursor.execute(
|
|
||||||
"""DELETE FROM notes_notes
|
|
||||||
WHERE etudid = %(etudid)s
|
|
||||||
AND evaluation_id = %(evaluation_id)s
|
|
||||||
""",
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
# garde trace de la suppression dans l'historique:
|
|
||||||
args["value"] = scu.NOTES_SUPPRESS
|
|
||||||
cursor.execute(
|
|
||||||
"""INSERT INTO notes_notes_log
|
|
||||||
(etudid,evaluation_id,value,comment,date,uid)
|
|
||||||
VALUES
|
|
||||||
(%(etudid)s, %(evaluation_id)s, %(value)s, %(comment)s, %(date)s, %(uid)s)
|
|
||||||
""",
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
nb_suppress += 1
|
|
||||||
if changed:
|
if changed:
|
||||||
etudids_changed.append(etudid)
|
etudids_changed.append(etudid)
|
||||||
if res.etud_has_decision(etudid, include_rcues=False):
|
if res.etud_has_decision(etudid, include_rcues=False):
|
||||||
@ -678,7 +627,108 @@ def notes_add(
|
|||||||
cnx.commit()
|
cnx.commit()
|
||||||
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre.id)
|
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre.id)
|
||||||
sco_cache.EvaluationCache.delete(evaluation_id)
|
sco_cache.EvaluationCache.delete(evaluation_id)
|
||||||
return etudids_changed, nb_suppress, etudids_with_decision
|
return etudids_changed, nb_suppress, etudids_with_decision, messages
|
||||||
|
|
||||||
|
|
||||||
|
def _record_note(
|
||||||
|
cursor,
|
||||||
|
notes_db,
|
||||||
|
etudid: int,
|
||||||
|
evaluation_id: int,
|
||||||
|
value: float,
|
||||||
|
comment: str = "",
|
||||||
|
user: User = None,
|
||||||
|
date=None,
|
||||||
|
do_it=False,
|
||||||
|
):
|
||||||
|
"Enregistrement de la note en base"
|
||||||
|
changed = False
|
||||||
|
suppressed = False
|
||||||
|
args = {
|
||||||
|
"etudid": etudid,
|
||||||
|
"evaluation_id": evaluation_id,
|
||||||
|
"value": value,
|
||||||
|
# convention scodoc7 quote comment:
|
||||||
|
"comment": (html.escape(comment) if isinstance(comment, str) else comment),
|
||||||
|
"uid": user.id,
|
||||||
|
"date": date,
|
||||||
|
}
|
||||||
|
if etudid not in notes_db:
|
||||||
|
# nouvelle note
|
||||||
|
if value != scu.NOTES_SUPPRESS:
|
||||||
|
if do_it:
|
||||||
|
# Note: le conflit ci-dessous peut arriver si un autre thread
|
||||||
|
# a modifié la base après qu'on ait lu notes_db
|
||||||
|
cursor.execute(
|
||||||
|
"""INSERT INTO notes_notes
|
||||||
|
(etudid, evaluation_id, value, comment, date, uid)
|
||||||
|
VALUES
|
||||||
|
(%(etudid)s,%(evaluation_id)s,%(value)s,
|
||||||
|
%(comment)s,%(date)s,%(uid)s)
|
||||||
|
ON CONFLICT ON CONSTRAINT notes_notes_etudid_evaluation_id_key
|
||||||
|
DO UPDATE SET etudid=%(etudid)s, evaluation_id=%(evaluation_id)s,
|
||||||
|
value=%(value)s, comment=%(comment)s, date=%(date)s, uid=%(uid)s
|
||||||
|
""",
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
changed = True
|
||||||
|
else:
|
||||||
|
# il y a deja une note
|
||||||
|
oldval = notes_db[etudid]["value"]
|
||||||
|
if type(value) != type(oldval):
|
||||||
|
changed = True
|
||||||
|
elif isinstance(value, float) and (abs(value - oldval) > scu.NOTES_PRECISION):
|
||||||
|
changed = True
|
||||||
|
elif value != oldval:
|
||||||
|
changed = True
|
||||||
|
if changed:
|
||||||
|
# recopie l'ancienne note dans notes_notes_log, puis update
|
||||||
|
if do_it:
|
||||||
|
cursor.execute(
|
||||||
|
"""INSERT INTO notes_notes_log
|
||||||
|
(etudid,evaluation_id,value,comment,date,uid)
|
||||||
|
SELECT etudid, evaluation_id, value, comment, date, uid
|
||||||
|
FROM notes_notes
|
||||||
|
WHERE etudid=%(etudid)s
|
||||||
|
and evaluation_id=%(evaluation_id)s
|
||||||
|
""",
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
if value != scu.NOTES_SUPPRESS:
|
||||||
|
if do_it:
|
||||||
|
cursor.execute(
|
||||||
|
"""UPDATE notes_notes
|
||||||
|
SET value=%(value)s, comment=%(comment)s, date=%(date)s, uid=%(uid)s
|
||||||
|
WHERE etudid = %(etudid)s
|
||||||
|
and evaluation_id = %(evaluation_id)s
|
||||||
|
""",
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
else: # suppression ancienne note
|
||||||
|
if do_it:
|
||||||
|
log(
|
||||||
|
f"""notes_add, suppress, evaluation_id={evaluation_id}, etudid={
|
||||||
|
etudid}, oldval={oldval}"""
|
||||||
|
)
|
||||||
|
cursor.execute(
|
||||||
|
"""DELETE FROM notes_notes
|
||||||
|
WHERE etudid = %(etudid)s
|
||||||
|
AND evaluation_id = %(evaluation_id)s
|
||||||
|
""",
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
# garde trace de la suppression dans l'historique:
|
||||||
|
args["value"] = scu.NOTES_SUPPRESS
|
||||||
|
cursor.execute(
|
||||||
|
"""INSERT INTO notes_notes_log
|
||||||
|
(etudid,evaluation_id,value,comment,date,uid)
|
||||||
|
VALUES
|
||||||
|
(%(etudid)s, %(evaluation_id)s, %(value)s, %(comment)s, %(date)s, %(uid)s)
|
||||||
|
""",
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
suppressed = True
|
||||||
|
return changed, suppressed
|
||||||
|
|
||||||
|
|
||||||
def saisie_notes_tableur(evaluation_id, group_ids=()):
|
def saisie_notes_tableur(evaluation_id, group_ids=()):
|
||||||
@ -703,7 +753,7 @@ def saisie_notes_tableur(evaluation_id, group_ids=()):
|
|||||||
)
|
)
|
||||||
|
|
||||||
page_title = "Saisie des notes" + (
|
page_title = "Saisie des notes" + (
|
||||||
f"""de {evaluation.description}""" if evaluation.description else ""
|
f""" de {evaluation.description}""" if evaluation.description else ""
|
||||||
)
|
)
|
||||||
|
|
||||||
# Informations sur les groupes à afficher:
|
# Informations sur les groupes à afficher:
|
||||||
@ -797,9 +847,13 @@ def saisie_notes_tableur(evaluation_id, group_ids=()):
|
|||||||
}">
|
}">
|
||||||
Revenir au tableau de bord du module</a>
|
Revenir au tableau de bord du module</a>
|
||||||
|
|
||||||
|
<a class="stdlink" href="{url_for("notes.saisie_notes_tableur",
|
||||||
|
scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
|
||||||
|
}">Charger un autre fichier de notes</a>
|
||||||
|
|
||||||
<a class="stdlink" href="{url_for("notes.saisie_notes",
|
<a class="stdlink" href="{url_for("notes.saisie_notes",
|
||||||
scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
|
scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
|
||||||
}">Charger d'autres notes dans cette évaluation</a>
|
}">Formulaire de saisie des notes</a>
|
||||||
</p>"""
|
</p>"""
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -1015,7 +1069,7 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
|
|||||||
"Autres opérations",
|
"Autres opérations",
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"title": "Saisie par fichier tableur",
|
"title": "Saisir par fichier tableur",
|
||||||
"id": "menu_saisie_tableur",
|
"id": "menu_saisie_tableur",
|
||||||
"endpoint": "notes.saisie_notes_tableur",
|
"endpoint": "notes.saisie_notes_tableur",
|
||||||
"args": {
|
"args": {
|
||||||
@ -1126,7 +1180,7 @@ def _get_sorted_etuds(evaluation: Evaluation, etudids: list, formsemestre_id: in
|
|||||||
|
|
||||||
# Note actuelle de l'étudiant:
|
# Note actuelle de l'étudiant:
|
||||||
if etudid in notes_db:
|
if etudid in notes_db:
|
||||||
e["val"] = _displayNote(notes_db[etudid]["value"])
|
e["val"] = _display_note(notes_db[etudid]["value"])
|
||||||
comment = notes_db[etudid]["comment"]
|
comment = notes_db[etudid]["comment"]
|
||||||
if comment is None:
|
if comment is None:
|
||||||
comment = ""
|
comment = ""
|
||||||
@ -1368,7 +1422,7 @@ def save_notes(
|
|||||||
#
|
#
|
||||||
valid_notes, _, _, _, _ = _check_notes(notes, evaluation)
|
valid_notes, _, _, _, _ = _check_notes(notes, evaluation)
|
||||||
if valid_notes:
|
if valid_notes:
|
||||||
etudids_changed, _, etudids_with_decision = notes_add(
|
etudids_changed, _, etudids_with_decision, messages = notes_add(
|
||||||
current_user, evaluation.id, valid_notes, comment=comment, do_it=True
|
current_user, evaluation.id, valid_notes, comment=comment, do_it=True
|
||||||
)
|
)
|
||||||
ScolarNews.add(
|
ScolarNews.add(
|
||||||
@ -1386,12 +1440,14 @@ def save_notes(
|
|||||||
etudid: get_note_history_menu(evaluation.id, etudid)
|
etudid: get_note_history_menu(evaluation.id, etudid)
|
||||||
for etudid in etudids_changed
|
for etudid in etudids_changed
|
||||||
},
|
},
|
||||||
|
"messages": messages,
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
result = {
|
result = {
|
||||||
"etudids_changed": [],
|
"etudids_changed": [],
|
||||||
"etudids_with_decision": [],
|
"etudids_with_decision": [],
|
||||||
"history_menu": [],
|
"history_menu": [],
|
||||||
|
"messages": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -1420,7 +1476,7 @@ def get_note_history_menu(evaluation_id: int, etudid: int) -> str:
|
|||||||
first = True
|
first = True
|
||||||
for i in history:
|
for i in history:
|
||||||
jt = i["date"].strftime("le %d/%m/%Y à %H:%M") + " (%s)" % i["user_name"]
|
jt = i["date"].strftime("le %d/%m/%Y à %H:%M") + " (%s)" % i["user_name"]
|
||||||
dispnote = _displayNote(i["value"])
|
dispnote = _display_note(i["value"])
|
||||||
if first:
|
if first:
|
||||||
nv = "" # ne repete pas la valeur de la note courante
|
nv = "" # ne repete pas la valeur de la note courante
|
||||||
else:
|
else:
|
||||||
|
@ -180,7 +180,7 @@ def external_ue_inscrit_et_note(
|
|||||||
description="note externe",
|
description="note externe",
|
||||||
)
|
)
|
||||||
# Saisie des notes
|
# Saisie des notes
|
||||||
_, _, _ = sco_saisie_notes.notes_add(
|
_, _, _, _ = sco_saisie_notes.notes_add(
|
||||||
current_user,
|
current_user,
|
||||||
evaluation.id,
|
evaluation.id,
|
||||||
list(notes_etuds.items()),
|
list(notes_etuds.items()),
|
||||||
|
@ -35,7 +35,7 @@ from flask import url_for, g, request
|
|||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
|
|
||||||
from app import db, Departement
|
from app import Departement
|
||||||
|
|
||||||
from app.auth.models import Permission, Role, User, UserRole
|
from app.auth.models import Permission, Role, User, UserRole
|
||||||
from app.models import ScoDocSiteConfig, USERNAME_STR_LEN
|
from app.models import ScoDocSiteConfig, USERNAME_STR_LEN
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.6.975"
|
SCOVERSION = "9.6.976"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
Vérif moyennes de modules des bulletins
|
Vérif moyennes de modules des bulletins
|
||||||
et aussi moyennes modules et UE internes (via nt)
|
et aussi moyennes modules et UE internes (via nt)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from flask import g
|
from flask import g
|
||||||
@ -107,16 +108,16 @@ def test_notes_modules(test_client):
|
|||||||
# --- Notes ordinaires
|
# --- Notes ordinaires
|
||||||
note_1 = 12.0
|
note_1 = 12.0
|
||||||
note_2 = 13.0
|
note_2 = 13.0
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etuds[0]["etudid"], note=note_1
|
evaluation_id=e1["evaluation_id"], etudid=etuds[0]["etudid"], note=note_1
|
||||||
)
|
)
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etuds[0]["etudid"], note=note_2
|
evaluation_id=e2["evaluation_id"], etudid=etuds[0]["etudid"], note=note_2
|
||||||
)
|
)
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etuds[1]["etudid"], note=note_1 / 2
|
evaluation_id=e1["evaluation_id"], etudid=etuds[1]["etudid"], note=note_1 / 2
|
||||||
)
|
)
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etuds[1]["etudid"], note=note_2 / 3
|
evaluation_id=e2["evaluation_id"], etudid=etuds[1]["etudid"], note=note_2 / 3
|
||||||
)
|
)
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
@ -139,22 +140,20 @@ def test_notes_modules(test_client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Absence à une évaluation
|
# Absence à une évaluation
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etudid, note=None
|
evaluation_id=e1["evaluation_id"], etudid=etudid, note=None
|
||||||
) # abs
|
) # abs
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e2["evaluation_id"], etudid=etudid, note=note_2)
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etudid, note=note_2
|
|
||||||
)
|
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
note_th = (coef_1 * 0.0 + coef_2 * note_2) / (coef_1 + coef_2)
|
note_th = (coef_1 * 0.0 + coef_2 * note_2) / (coef_1 + coef_2)
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(note_th)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(note_th)
|
||||||
# Absences aux deux évaluations
|
# Absences aux deux évaluations
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etudid, note=None
|
evaluation_id=e1["evaluation_id"], etudid=etudid, note=None
|
||||||
) # abs
|
) # abs
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etudid, note=None
|
evaluation_id=e2["evaluation_id"], etudid=etudid, note=None
|
||||||
) # abs
|
) # abs
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
@ -171,10 +170,8 @@ def test_notes_modules(test_client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Note excusée EXC <-> scu.NOTES_NEUTRALISE
|
# Note excusée EXC <-> scu.NOTES_NEUTRALISE
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e1["evaluation_id"], etudid=etudid, note=note_1)
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etudid, note=note_1
|
_ = G.create_note(
|
||||||
)
|
|
||||||
_, _, _ = G.create_note(
|
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
||||||
) # EXC
|
) # EXC
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
@ -190,10 +187,8 @@ def test_notes_modules(test_client):
|
|||||||
expected_moy_ue=note_1,
|
expected_moy_ue=note_1,
|
||||||
)
|
)
|
||||||
# Note en attente ATT <-> scu.NOTES_ATTENTE
|
# Note en attente ATT <-> scu.NOTES_ATTENTE
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e1["evaluation_id"], etudid=etudid, note=note_1)
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etudid, note=note_1
|
_ = G.create_note(
|
||||||
)
|
|
||||||
_, _, _ = G.create_note(
|
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_ATTENTE
|
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_ATTENTE
|
||||||
) # ATT
|
) # ATT
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
@ -209,10 +204,10 @@ def test_notes_modules(test_client):
|
|||||||
expected_moy_ue=note_1,
|
expected_moy_ue=note_1,
|
||||||
)
|
)
|
||||||
# Neutralisation (EXC) des 2 évals
|
# Neutralisation (EXC) des 2 évals
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
evaluation_id=e1["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
||||||
) # EXC
|
) # EXC
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
||||||
) # EXC
|
) # EXC
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
@ -228,10 +223,10 @@ def test_notes_modules(test_client):
|
|||||||
expected_moy_ue=np.nan,
|
expected_moy_ue=np.nan,
|
||||||
)
|
)
|
||||||
# Attente (ATT) sur les 2 evals
|
# Attente (ATT) sur les 2 evals
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etudid, note=scu.NOTES_ATTENTE
|
evaluation_id=e1["evaluation_id"], etudid=etudid, note=scu.NOTES_ATTENTE
|
||||||
) # ATT
|
) # ATT
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_ATTENTE
|
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_ATTENTE
|
||||||
) # ATT
|
) # ATT
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
@ -290,7 +285,7 @@ def test_notes_modules(test_client):
|
|||||||
{"etudid": etudid, "moduleimpl_id": moduleimpl_id},
|
{"etudid": etudid, "moduleimpl_id": moduleimpl_id},
|
||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
)
|
)
|
||||||
_, _, _ = G.create_note(evaluation_id=e1["evaluation_id"], etudid=etudid, note=12.5)
|
_ = G.create_note(evaluation_id=e1["evaluation_id"], etudid=etudid, note=12.5)
|
||||||
|
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
mod_stats = nt.get_mod_stats(moduleimpl_id)
|
mod_stats = nt.get_mod_stats(moduleimpl_id)
|
||||||
@ -318,9 +313,7 @@ def test_notes_modules(test_client):
|
|||||||
description="evaluation mod 2",
|
description="evaluation mod 2",
|
||||||
coefficient=1.0,
|
coefficient=1.0,
|
||||||
)
|
)
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e_m2["evaluation_id"], etudid=etudid, note=19.5)
|
||||||
evaluation_id=e_m2["evaluation_id"], etudid=etudid, note=19.5
|
|
||||||
)
|
|
||||||
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
ue_status = nt.get_etud_ue_status(etudid, ue_id)
|
ue_status = nt.get_etud_ue_status(etudid, ue_id)
|
||||||
@ -328,22 +321,20 @@ def test_notes_modules(test_client):
|
|||||||
# Moyenne d'UE si l'un des modules est EXC ("NA")
|
# Moyenne d'UE si l'un des modules est EXC ("NA")
|
||||||
# 2 modules, notes EXC dans le premier, note valide n dans le second
|
# 2 modules, notes EXC dans le premier, note valide n dans le second
|
||||||
# la moyenne de l'UE doit être n
|
# la moyenne de l'UE doit être n
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
evaluation_id=e1["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
||||||
) # EXC
|
) # EXC
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
evaluation_id=e2["evaluation_id"], etudid=etudid, note=scu.NOTES_NEUTRALISE
|
||||||
) # EXC
|
) # EXC
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e_m2["evaluation_id"], etudid=etudid, note=12.5)
|
||||||
evaluation_id=e_m2["evaluation_id"], etudid=etudid, note=12.5
|
_ = G.create_note(
|
||||||
)
|
|
||||||
_, _, _ = G.create_note(
|
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etuds[1]["etudid"], note=11.0
|
evaluation_id=e1["evaluation_id"], etudid=etuds[1]["etudid"], note=11.0
|
||||||
)
|
)
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e2["evaluation_id"], etudid=etuds[1]["etudid"], note=11.0
|
evaluation_id=e2["evaluation_id"], etudid=etuds[1]["etudid"], note=11.0
|
||||||
)
|
)
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e_m2["evaluation_id"], etudid=etuds[1]["etudid"], note=11.0
|
evaluation_id=e_m2["evaluation_id"], etudid=etuds[1]["etudid"], note=11.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -407,12 +398,12 @@ def test_notes_modules_att_dem(test_client):
|
|||||||
coefficient=coef_1,
|
coefficient=coef_1,
|
||||||
)
|
)
|
||||||
# Attente (ATT) sur les 2 evals
|
# Attente (ATT) sur les 2 evals
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"],
|
evaluation_id=e1["evaluation_id"],
|
||||||
etudid=etuds[0]["etudid"],
|
etudid=etuds[0]["etudid"],
|
||||||
note=scu.NOTES_ATTENTE,
|
note=scu.NOTES_ATTENTE,
|
||||||
) # ATT
|
) # ATT
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"],
|
evaluation_id=e1["evaluation_id"],
|
||||||
etudid=etuds[1]["etudid"],
|
etudid=etuds[1]["etudid"],
|
||||||
note=scu.NOTES_ATTENTE,
|
note=scu.NOTES_ATTENTE,
|
||||||
@ -455,7 +446,7 @@ def test_notes_modules_att_dem(test_client):
|
|||||||
assert note_e1 == scu.NOTES_ATTENTE # XXXX un peu contestable
|
assert note_e1 == scu.NOTES_ATTENTE # XXXX un peu contestable
|
||||||
|
|
||||||
# Saisie note ABS pour le deuxième etud
|
# Saisie note ABS pour le deuxième etud
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e1["evaluation_id"], etudid=etuds[1]["etudid"], note=None
|
evaluation_id=e1["evaluation_id"], etudid=etuds[1]["etudid"], note=None
|
||||||
)
|
)
|
||||||
nt = check_nt(
|
nt = check_nt(
|
||||||
|
@ -72,8 +72,8 @@ def test_notes_rattrapage(test_client):
|
|||||||
evaluation_type=Evaluation.EVALUATION_RATTRAPAGE,
|
evaluation_type=Evaluation.EVALUATION_RATTRAPAGE,
|
||||||
)
|
)
|
||||||
etud = etuds[0]
|
etud = etuds[0]
|
||||||
_, _, _ = G.create_note(evaluation_id=e["id"], etudid=etud["etudid"], note=12.0)
|
_ = G.create_note(evaluation_id=e["id"], etudid=etud["etudid"], note=12.0)
|
||||||
_, _, _ = G.create_note(evaluation_id=e_rat["id"], etudid=etud["etudid"], note=11.0)
|
_ = G.create_note(evaluation_id=e_rat["id"], etudid=etud["etudid"], note=11.0)
|
||||||
|
|
||||||
# --- Vérifications internes structures ScoDoc
|
# --- Vérifications internes structures ScoDoc
|
||||||
formsemestre = db.session.get(FormSemestre, formsemestre_id)
|
formsemestre = db.session.get(FormSemestre, formsemestre_id)
|
||||||
@ -98,23 +98,21 @@ def test_notes_rattrapage(test_client):
|
|||||||
# Note moyenne: ici le ratrapage est inférieur à la note:
|
# Note moyenne: ici le ratrapage est inférieur à la note:
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(12.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(12.0)
|
||||||
# rattrapage > moyenne:
|
# rattrapage > moyenne:
|
||||||
_, _, _ = G.create_note(evaluation_id=e_rat["id"], etudid=etud["etudid"], note=18.0)
|
_ = G.create_note(evaluation_id=e_rat["id"], etudid=etud["etudid"], note=18.0)
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(18.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(18.0)
|
||||||
# rattrapage vs absences
|
# rattrapage vs absences
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e["id"], etudid=etud["etudid"], note=None) # abs
|
||||||
evaluation_id=e["id"], etudid=etud["etudid"], note=None
|
_ = G.create_note(evaluation_id=e_rat["id"], etudid=etud["etudid"], note=17.0)
|
||||||
) # abs
|
|
||||||
_, _, _ = G.create_note(evaluation_id=e_rat["id"], etudid=etud["etudid"], note=17.0)
|
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(17.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(17.0)
|
||||||
# et sans note de rattrapage
|
# et sans note de rattrapage
|
||||||
_, _, _ = G.create_note(evaluation_id=e["id"], etudid=etud["etudid"], note=10.0)
|
_ = G.create_note(evaluation_id=e["id"], etudid=etud["etudid"], note=10.0)
|
||||||
_, _, _ = G.create_note(evaluation_id=e_rat["id"], etudid=etud["etudid"], note=None)
|
_ = G.create_note(evaluation_id=e_rat["id"], etudid=etud["etudid"], note=None)
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
@ -159,18 +157,14 @@ def test_notes_rattrapage(test_client):
|
|||||||
assert len(mod_res.get_evaluations_completes(moduleimpl)) == 2
|
assert len(mod_res.get_evaluations_completes(moduleimpl)) == 2
|
||||||
|
|
||||||
# Saisie note session 2:
|
# Saisie note session 2:
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e_session2["id"], etudid=etud["etudid"], note=5.0)
|
||||||
evaluation_id=e_session2["id"], etudid=etud["etudid"], note=5.0
|
|
||||||
)
|
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
# Note moyenne: utilise session 2 même si inférieure
|
# Note moyenne: utilise session 2 même si inférieure
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(5.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(5.0)
|
||||||
|
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e_session2["id"], etudid=etud["etudid"], note=20.0)
|
||||||
evaluation_id=e_session2["id"], etudid=etud["etudid"], note=20.0
|
|
||||||
)
|
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
@ -178,16 +172,14 @@ def test_notes_rattrapage(test_client):
|
|||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(20.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(20.0)
|
||||||
|
|
||||||
# Met la note session2 à ABS (None)
|
# Met la note session2 à ABS (None)
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e_session2["id"], etudid=etud["etudid"], note=None)
|
||||||
evaluation_id=e_session2["id"], etudid=etud["etudid"], note=None
|
|
||||||
)
|
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
# Note moyenne: zéro car ABS
|
# Note moyenne: zéro car ABS
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(0.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(0.0)
|
||||||
# Supprime note session 2
|
# Supprime note session 2
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(
|
||||||
evaluation_id=e_session2["id"], etudid=etud["etudid"], note=scu.NOTES_SUPPRESS
|
evaluation_id=e_session2["id"], etudid=etud["etudid"], note=scu.NOTES_SUPPRESS
|
||||||
)
|
)
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
@ -216,18 +208,14 @@ def test_notes_rattrapage(test_client):
|
|||||||
# Note moyenne sans bonus
|
# Note moyenne sans bonus
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(10.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(10.0)
|
||||||
# Saisie note bonus
|
# Saisie note bonus
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e_bonus["id"], etudid=etud["etudid"], note=1.0)
|
||||||
evaluation_id=e_bonus["id"], etudid=etud["etudid"], note=1.0
|
|
||||||
)
|
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
# Note moyenne sans bonus
|
# Note moyenne sans bonus
|
||||||
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(11.0)
|
assert b["ues"][0]["modules"][0]["mod_moy_txt"] == scu.fmt_note(11.0)
|
||||||
# Négatif, avec clip à zéro
|
# Négatif, avec clip à zéro
|
||||||
_, _, _ = G.create_note(
|
_ = G.create_note(evaluation_id=e_bonus["id"], etudid=etud["etudid"], note=-20.0)
|
||||||
evaluation_id=e_bonus["id"], etudid=etud["etudid"], note=-20.0
|
|
||||||
)
|
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||||
sem["formsemestre_id"], etud["etudid"]
|
sem["formsemestre_id"], etud["etudid"]
|
||||||
)
|
)
|
||||||
|
@ -105,7 +105,7 @@ def run_sco_basic(verbose=False, dept=None) -> FormSemestre:
|
|||||||
|
|
||||||
# --- Saisie toutes les notes de l'évaluation
|
# --- Saisie toutes les notes de l'évaluation
|
||||||
for idx, etud in enumerate(etuds):
|
for idx, etud in enumerate(etuds):
|
||||||
etudids_changed, nb_suppress, existing_decisions = G.create_note(
|
etudids_changed, nb_suppress, existing_decisions, messages = G.create_note(
|
||||||
evaluation_id=e1.id,
|
evaluation_id=e1.id,
|
||||||
etudid=etud["etudid"],
|
etudid=etud["etudid"],
|
||||||
note=NOTES_T[idx % len(NOTES_T)],
|
note=NOTES_T[idx % len(NOTES_T)],
|
||||||
@ -113,6 +113,7 @@ def run_sco_basic(verbose=False, dept=None) -> FormSemestre:
|
|||||||
assert not existing_decisions
|
assert not existing_decisions
|
||||||
assert nb_suppress == 0
|
assert nb_suppress == 0
|
||||||
assert len(etudids_changed) == 1
|
assert len(etudids_changed) == 1
|
||||||
|
assert messages == []
|
||||||
|
|
||||||
# --- Vérifie que les notes sont prises en compte:
|
# --- Vérifie que les notes sont prises en compte:
|
||||||
b = sco_bulletins.formsemestre_bulletinetud_dict(formsemestre_id, etud["etudid"])
|
b = sco_bulletins.formsemestre_bulletinetud_dict(formsemestre_id, etud["etudid"])
|
||||||
@ -139,11 +140,12 @@ def run_sco_basic(verbose=False, dept=None) -> FormSemestre:
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
# Saisie les notes des 5 premiers étudiants:
|
# Saisie les notes des 5 premiers étudiants:
|
||||||
for idx, etud in enumerate(etuds[:5]):
|
for idx, etud in enumerate(etuds[:5]):
|
||||||
etudids_changed, nb_suppress, existing_decisions = G.create_note(
|
etudids_changed, nb_suppress, existing_decisions, messages = G.create_note(
|
||||||
evaluation_id=e2.id,
|
evaluation_id=e2.id,
|
||||||
etudid=etud["etudid"],
|
etudid=etud["etudid"],
|
||||||
note=NOTES_T[idx % len(NOTES_T)],
|
note=NOTES_T[idx % len(NOTES_T)],
|
||||||
)
|
)
|
||||||
|
assert messages == []
|
||||||
# Cette éval n'est pas complète
|
# Cette éval n'est pas complète
|
||||||
etat = sco_evaluations.do_evaluation_etat(e2.id)
|
etat = sco_evaluations.do_evaluation_etat(e2.id)
|
||||||
assert etat["evalcomplete"] is False
|
assert etat["evalcomplete"] is False
|
||||||
@ -162,11 +164,12 @@ def run_sco_basic(verbose=False, dept=None) -> FormSemestre:
|
|||||||
|
|
||||||
# Saisie des notes qui manquent:
|
# Saisie des notes qui manquent:
|
||||||
for idx, etud in enumerate(etuds[5:]):
|
for idx, etud in enumerate(etuds[5:]):
|
||||||
etudids_changed, nb_suppress, existing_decisions = G.create_note(
|
etudids_changed, nb_suppress, existing_decisions, messages = G.create_note(
|
||||||
evaluation_id=e2.id,
|
evaluation_id=e2.id,
|
||||||
etudid=etud["etudid"],
|
etudid=etud["etudid"],
|
||||||
note=NOTES_T[idx % len(NOTES_T)],
|
note=NOTES_T[idx % len(NOTES_T)],
|
||||||
)
|
)
|
||||||
|
assert messages == []
|
||||||
etat = sco_evaluations.do_evaluation_etat(e2.id)
|
etat = sco_evaluations.do_evaluation_etat(e2.id)
|
||||||
assert etat["evalcomplete"]
|
assert etat["evalcomplete"]
|
||||||
assert etat["nb_att"] == 0
|
assert etat["nb_att"] == 0
|
||||||
|
Loading…
Reference in New Issue
Block a user