forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -5,7 +5,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
from flask import g, url_for
|
from flask import abort, g, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
@ -241,6 +241,25 @@ class Evaluation(db.Model):
|
|||||||
if k != "_sa_instance_state" and k != "id" and k in data:
|
if k != "_sa_instance_state" and k != "id" and k in data:
|
||||||
setattr(self, k, data[k])
|
setattr(self, k, data[k])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_evaluation(
|
||||||
|
cls, evaluation_id: int | str, dept_id: int = None
|
||||||
|
) -> "Evaluation":
|
||||||
|
"""Evaluation ou 404, cherche uniquement dans le département spécifié ou le courant."""
|
||||||
|
from app.models import FormSemestre, ModuleImpl
|
||||||
|
|
||||||
|
if not isinstance(evaluation_id, int):
|
||||||
|
try:
|
||||||
|
evaluation_id = int(evaluation_id)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
abort(404, "evaluation_id invalide")
|
||||||
|
if g.scodoc_dept:
|
||||||
|
dept_id = dept_id if dept_id is not None else g.scodoc_dept_id
|
||||||
|
query = cls.query.filter_by(id=evaluation_id)
|
||||||
|
if dept_id is not None:
|
||||||
|
query = query.join(ModuleImpl).join(FormSemestre).filter_by(dept_id=dept_id)
|
||||||
|
return query.first_or_404()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_max_numero(cls, moduleimpl_id: int) -> int:
|
def get_max_numero(cls, moduleimpl_id: int) -> int:
|
||||||
"""Return max numero among evaluations in this
|
"""Return max numero among evaluations in this
|
||||||
@ -265,7 +284,9 @@ class Evaluation(db.Model):
|
|||||||
evaluations = moduleimpl.evaluations.order_by(
|
evaluations = moduleimpl.evaluations.order_by(
|
||||||
Evaluation.date_debut, Evaluation.numero
|
Evaluation.date_debut, Evaluation.numero
|
||||||
).all()
|
).all()
|
||||||
all_numbered = all(e.numero is not None for e in evaluations)
|
numeros_distincts = {e.numero for e in evaluations if e.numero is not None}
|
||||||
|
# pas de None, pas de dupliqués
|
||||||
|
all_numbered = len(numeros_distincts) == len(evaluations)
|
||||||
if all_numbered and only_if_unumbered:
|
if all_numbered and only_if_unumbered:
|
||||||
return # all ok
|
return # all ok
|
||||||
|
|
||||||
|
@ -162,50 +162,48 @@ def do_evaluation_get_all_notes(
|
|||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
def moduleimpl_evaluation_move(evaluation_id: int, after=0, redirect=1):
|
def moduleimpl_evaluation_move(evaluation_id: int, after=0):
|
||||||
"""Move before/after previous one (decrement/increment numero)
|
"""Move before/after previous one (decrement/increment numero)
|
||||||
(published)
|
(published)
|
||||||
"""
|
"""
|
||||||
evaluation: Evaluation = Evaluation.query.get_or_404(evaluation_id)
|
evaluation = Evaluation.get_evaluation(evaluation_id)
|
||||||
redirect = int(redirect)
|
|
||||||
# access: can change eval ?
|
# access: can change eval ?
|
||||||
if not evaluation.moduleimpl.can_edit_evaluation(current_user):
|
if not evaluation.moduleimpl.can_edit_evaluation(current_user):
|
||||||
raise AccessDenied(
|
raise AccessDenied(
|
||||||
f"Modification évaluation impossible pour {current_user.get_nomplogin()}"
|
f"Modification évaluation impossible pour {current_user.get_nomplogin()}"
|
||||||
)
|
)
|
||||||
Evaluation.moduleimpl_evaluation_renumber(
|
|
||||||
evaluation.moduleimpl, only_if_unumbered=True
|
|
||||||
)
|
|
||||||
e = get_evaluations_dict(args={"evaluation_id": evaluation_id})[0]
|
|
||||||
|
|
||||||
after = int(after) # 0: deplace avant, 1 deplace apres
|
after = int(after) # 0: deplace avant, 1 deplace apres
|
||||||
if after not in (0, 1):
|
if after not in (0, 1):
|
||||||
raise ValueError('invalid value for "after"')
|
raise ValueError('invalid value for "after"')
|
||||||
mod_evals = get_evaluations_dict({"moduleimpl_id": e["moduleimpl_id"]})
|
|
||||||
if len(mod_evals) > 1:
|
Evaluation.moduleimpl_evaluation_renumber(
|
||||||
idx = [p["evaluation_id"] for p in mod_evals].index(evaluation_id)
|
evaluation.moduleimpl, only_if_unumbered=True
|
||||||
|
)
|
||||||
|
mod_evaluations = evaluation.moduleimpl.evaluations.all()
|
||||||
|
if len(mod_evaluations) > 1:
|
||||||
|
idx = [e.id for e in mod_evaluations].index(evaluation.id)
|
||||||
neigh = None # object to swap with
|
neigh = None # object to swap with
|
||||||
if after == 0 and idx > 0:
|
if after == 0 and idx > 0:
|
||||||
neigh = mod_evals[idx - 1]
|
neigh = mod_evaluations[idx - 1]
|
||||||
elif after == 1 and idx < len(mod_evals) - 1:
|
elif after == 1 and idx < len(mod_evaluations) - 1:
|
||||||
neigh = mod_evals[idx + 1]
|
neigh = mod_evaluations[idx + 1]
|
||||||
if neigh: #
|
if neigh: #
|
||||||
if neigh["numero"] == e["numero"]:
|
if neigh.numero == evaluation.numero:
|
||||||
log("Warning: moduleimpl_evaluation_move: forcing renumber")
|
log("Warning: moduleimpl_evaluation_move: forcing renumber")
|
||||||
Evaluation.moduleimpl_evaluation_renumber(
|
Evaluation.moduleimpl_evaluation_renumber(
|
||||||
evaluation.moduleimpl, only_if_unumbered=False
|
evaluation.moduleimpl, only_if_unumbered=False
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# swap numero with neighbor
|
# swap numero with neighbor
|
||||||
e["numero"], neigh["numero"] = neigh["numero"], e["numero"]
|
evaluation.numero, neigh.numero = neigh.numero, evaluation.numero
|
||||||
do_evaluation_edit(e)
|
db.session.add(evaluation)
|
||||||
do_evaluation_edit(neigh)
|
db.session.add(neigh)
|
||||||
|
db.session.commit()
|
||||||
# redirect to moduleimpl page:
|
# redirect to moduleimpl page:
|
||||||
if redirect:
|
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
url_for(
|
url_for(
|
||||||
"notes.moduleimpl_status",
|
"notes.moduleimpl_status",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
moduleimpl_id=e["moduleimpl_id"],
|
moduleimpl_id=evaluation.moduleimpl.id,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -37,7 +37,7 @@ from flask_login import current_user
|
|||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app.models import Evaluation, FormSemestre, ModuleImpl
|
from app.models import Evaluation, Module, ModuleImpl
|
||||||
from app.models.evaluations import heure_to_time
|
from app.models.evaluations import heure_to_time
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
@ -47,7 +47,6 @@ from app.scodoc.TrivialFormulator import TrivialFormulator
|
|||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
from app.scodoc import sco_moduleimpl
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
|
|
||||||
@ -58,27 +57,20 @@ def evaluation_create_form(
|
|||||||
page_title="Évaluation",
|
page_title="Évaluation",
|
||||||
):
|
):
|
||||||
"Formulaire création/édition d'une évaluation (pas de ses notes)"
|
"Formulaire création/édition d'une évaluation (pas de ses notes)"
|
||||||
|
evaluation: Evaluation
|
||||||
if evaluation_id is not None:
|
if evaluation_id is not None:
|
||||||
evaluation: Evaluation = db.session.get(Evaluation, evaluation_id)
|
evaluation = db.session.get(Evaluation, evaluation_id)
|
||||||
if evaluation is None:
|
if evaluation is None:
|
||||||
raise ScoValueError("Cette évaluation n'existe pas ou plus !")
|
raise ScoValueError("Cette évaluation n'existe pas ou plus !")
|
||||||
moduleimpl_id = evaluation.moduleimpl_id
|
moduleimpl_id = evaluation.moduleimpl_id
|
||||||
#
|
#
|
||||||
modimpl: ModuleImpl = (
|
modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
|
||||||
ModuleImpl.query.filter_by(id=moduleimpl_id)
|
formsemestre_id = modimpl.formsemestre_id
|
||||||
.join(FormSemestre)
|
|
||||||
.filter_by(dept_id=g.scodoc_dept_id)
|
|
||||||
.first_or_404()
|
|
||||||
)
|
|
||||||
modimpl_o = sco_moduleimpl.moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[
|
|
||||||
0
|
|
||||||
]
|
|
||||||
mod = modimpl_o["module"]
|
|
||||||
formsemestre_id = modimpl_o["formsemestre_id"]
|
|
||||||
formsemestre = modimpl.formsemestre
|
formsemestre = modimpl.formsemestre
|
||||||
|
module: Module = modimpl.module
|
||||||
sem_ues = formsemestre.get_ues(with_sport=False)
|
sem_ues = formsemestre.get_ues(with_sport=False)
|
||||||
is_malus = mod["module_type"] == ModuleType.MALUS
|
is_malus = module.module_type == ModuleType.MALUS
|
||||||
is_apc = mod["module_type"] in (ModuleType.RESSOURCE, ModuleType.SAE)
|
is_apc = module.module_type in (ModuleType.RESSOURCE, ModuleType.SAE)
|
||||||
preferences = sco_preferences.SemPreferences(formsemestre.id)
|
preferences = sco_preferences.SemPreferences(formsemestre.id)
|
||||||
can_edit_poids = not preferences["but_disable_edit_poids_evaluations"]
|
can_edit_poids = not preferences["but_disable_edit_poids_evaluations"]
|
||||||
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible
|
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible
|
||||||
@ -99,8 +91,9 @@ def evaluation_create_form(
|
|||||||
if moduleimpl_id is None:
|
if moduleimpl_id is None:
|
||||||
raise ValueError("missing moduleimpl_id parameter")
|
raise ValueError("missing moduleimpl_id parameter")
|
||||||
initvalues = {
|
initvalues = {
|
||||||
"note_max": 20,
|
|
||||||
"jour": time.strftime("%d/%m/%Y", time.localtime()),
|
"jour": time.strftime("%d/%m/%Y", time.localtime()),
|
||||||
|
"note_max": 20,
|
||||||
|
"numero": max(e.numero or 0 for e in modimpl.evaluations) + 1,
|
||||||
"publish_incomplete": is_malus,
|
"publish_incomplete": is_malus,
|
||||||
"visibulletin": 1,
|
"visibulletin": 1,
|
||||||
}
|
}
|
||||||
@ -128,18 +121,7 @@ def evaluation_create_form(
|
|||||||
min_note_max_str = scu.fmt_note(min_note_max)
|
min_note_max_str = scu.fmt_note(min_note_max)
|
||||||
else:
|
else:
|
||||||
min_note_max_str = "0"
|
min_note_max_str = "0"
|
||||||
#
|
|
||||||
H = [
|
|
||||||
f"""<h3>{action} en
|
|
||||||
{scu.MODULE_TYPE_NAMES[mod["module_type"]]} <a class="stdlink" href="{
|
|
||||||
url_for("notes.moduleimpl_status",
|
|
||||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id)
|
|
||||||
}">{mod["code"] or "module sans code"} {mod["titre"]}</a> {link}</h3>
|
|
||||||
"""
|
|
||||||
]
|
|
||||||
|
|
||||||
heures = [f"{h:02d}h{m:02d}" for h in range(8, 19) for m in (0, 30)]
|
|
||||||
#
|
|
||||||
initvalues["coefficient"] = initvalues.get("coefficient", 1.0)
|
initvalues["coefficient"] = initvalues.get("coefficient", 1.0)
|
||||||
vals = scu.get_request_args()
|
vals = scu.get_request_args()
|
||||||
#
|
#
|
||||||
@ -164,6 +146,7 @@ def evaluation_create_form(
|
|||||||
("evaluation_id", {"default": evaluation_id, "input_type": "hidden"}),
|
("evaluation_id", {"default": evaluation_id, "input_type": "hidden"}),
|
||||||
("formsemestre_id", {"default": formsemestre_id, "input_type": "hidden"}),
|
("formsemestre_id", {"default": formsemestre_id, "input_type": "hidden"}),
|
||||||
("moduleimpl_id", {"default": moduleimpl_id, "input_type": "hidden"}),
|
("moduleimpl_id", {"default": moduleimpl_id, "input_type": "hidden"}),
|
||||||
|
("numero", {"default": initvalues["numero"], "input_type": "hidden"}),
|
||||||
(
|
(
|
||||||
"jour",
|
"jour",
|
||||||
{
|
{
|
||||||
@ -323,6 +306,16 @@ def evaluation_create_form(
|
|||||||
dest_url = url_for(
|
dest_url = url_for(
|
||||||
"notes.moduleimpl_status", scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id
|
"notes.moduleimpl_status", scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id
|
||||||
)
|
)
|
||||||
|
H = [
|
||||||
|
f"""<h3>{action} en
|
||||||
|
{scu.MODULE_TYPE_NAMES[module.module_type]} <a class="stdlink" href="{
|
||||||
|
url_for("notes.moduleimpl_status",
|
||||||
|
scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id)
|
||||||
|
}">{module.code or "module sans code"} {
|
||||||
|
module.titre or module.abbrev or "(sans titre)"
|
||||||
|
}</a> {link}</h3>
|
||||||
|
"""
|
||||||
|
]
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
head = html_sco_header.sco_header(page_title=page_title)
|
head = html_sco_header.sco_header(page_title=page_title)
|
||||||
return (
|
return (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.6.93"
|
SCOVERSION = "9.6.931"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user