forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -5,7 +5,7 @@
|
||||
import datetime
|
||||
from operator import attrgetter
|
||||
|
||||
from flask import g, url_for
|
||||
from flask import abort, g, url_for
|
||||
from flask_login import current_user
|
||||
import sqlalchemy as sa
|
||||
|
||||
@ -241,6 +241,25 @@ class Evaluation(db.Model):
|
||||
if k != "_sa_instance_state" and k != "id" and k in data:
|
||||
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
|
||||
def get_max_numero(cls, moduleimpl_id: int) -> int:
|
||||
"""Return max numero among evaluations in this
|
||||
@ -265,7 +284,9 @@ class Evaluation(db.Model):
|
||||
evaluations = moduleimpl.evaluations.order_by(
|
||||
Evaluation.date_debut, Evaluation.numero
|
||||
).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:
|
||||
return # all ok
|
||||
|
||||
|
@ -162,50 +162,48 @@ def do_evaluation_get_all_notes(
|
||||
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)
|
||||
(published)
|
||||
"""
|
||||
evaluation: Evaluation = Evaluation.query.get_or_404(evaluation_id)
|
||||
redirect = int(redirect)
|
||||
evaluation = Evaluation.get_evaluation(evaluation_id)
|
||||
# access: can change eval ?
|
||||
if not evaluation.moduleimpl.can_edit_evaluation(current_user):
|
||||
raise AccessDenied(
|
||||
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
|
||||
if after not in (0, 1):
|
||||
raise ValueError('invalid value for "after"')
|
||||
mod_evals = get_evaluations_dict({"moduleimpl_id": e["moduleimpl_id"]})
|
||||
if len(mod_evals) > 1:
|
||||
idx = [p["evaluation_id"] for p in mod_evals].index(evaluation_id)
|
||||
|
||||
Evaluation.moduleimpl_evaluation_renumber(
|
||||
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
|
||||
if after == 0 and idx > 0:
|
||||
neigh = mod_evals[idx - 1]
|
||||
elif after == 1 and idx < len(mod_evals) - 1:
|
||||
neigh = mod_evals[idx + 1]
|
||||
neigh = mod_evaluations[idx - 1]
|
||||
elif after == 1 and idx < len(mod_evaluations) - 1:
|
||||
neigh = mod_evaluations[idx + 1]
|
||||
if neigh: #
|
||||
if neigh["numero"] == e["numero"]:
|
||||
if neigh.numero == evaluation.numero:
|
||||
log("Warning: moduleimpl_evaluation_move: forcing renumber")
|
||||
Evaluation.moduleimpl_evaluation_renumber(
|
||||
evaluation.moduleimpl, only_if_unumbered=False
|
||||
)
|
||||
else:
|
||||
# swap numero with neighbor
|
||||
e["numero"], neigh["numero"] = neigh["numero"], e["numero"]
|
||||
do_evaluation_edit(e)
|
||||
do_evaluation_edit(neigh)
|
||||
evaluation.numero, neigh.numero = neigh.numero, evaluation.numero
|
||||
db.session.add(evaluation)
|
||||
db.session.add(neigh)
|
||||
db.session.commit()
|
||||
# redirect to moduleimpl page:
|
||||
if redirect:
|
||||
return flask.redirect(
|
||||
url_for(
|
||||
"notes.moduleimpl_status",
|
||||
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 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
|
||||
|
||||
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 sco_cache
|
||||
from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_moduleimpl
|
||||
from app.scodoc import sco_preferences
|
||||
|
||||
|
||||
@ -58,27 +57,20 @@ def evaluation_create_form(
|
||||
page_title="Évaluation",
|
||||
):
|
||||
"Formulaire création/édition d'une évaluation (pas de ses notes)"
|
||||
evaluation: Evaluation
|
||||
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:
|
||||
raise ScoValueError("Cette évaluation n'existe pas ou plus !")
|
||||
moduleimpl_id = evaluation.moduleimpl_id
|
||||
#
|
||||
modimpl: ModuleImpl = (
|
||||
ModuleImpl.query.filter_by(id=moduleimpl_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"]
|
||||
modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
|
||||
formsemestre_id = modimpl.formsemestre_id
|
||||
formsemestre = modimpl.formsemestre
|
||||
module: Module = modimpl.module
|
||||
sem_ues = formsemestre.get_ues(with_sport=False)
|
||||
is_malus = mod["module_type"] == ModuleType.MALUS
|
||||
is_apc = mod["module_type"] in (ModuleType.RESSOURCE, ModuleType.SAE)
|
||||
is_malus = module.module_type == ModuleType.MALUS
|
||||
is_apc = module.module_type in (ModuleType.RESSOURCE, ModuleType.SAE)
|
||||
preferences = sco_preferences.SemPreferences(formsemestre.id)
|
||||
can_edit_poids = not preferences["but_disable_edit_poids_evaluations"]
|
||||
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible
|
||||
@ -99,8 +91,9 @@ def evaluation_create_form(
|
||||
if moduleimpl_id is None:
|
||||
raise ValueError("missing moduleimpl_id parameter")
|
||||
initvalues = {
|
||||
"note_max": 20,
|
||||
"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,
|
||||
"visibulletin": 1,
|
||||
}
|
||||
@ -128,18 +121,7 @@ def evaluation_create_form(
|
||||
min_note_max_str = scu.fmt_note(min_note_max)
|
||||
else:
|
||||
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)
|
||||
vals = scu.get_request_args()
|
||||
#
|
||||
@ -164,6 +146,7 @@ def evaluation_create_form(
|
||||
("evaluation_id", {"default": evaluation_id, "input_type": "hidden"}),
|
||||
("formsemestre_id", {"default": formsemestre_id, "input_type": "hidden"}),
|
||||
("moduleimpl_id", {"default": moduleimpl_id, "input_type": "hidden"}),
|
||||
("numero", {"default": initvalues["numero"], "input_type": "hidden"}),
|
||||
(
|
||||
"jour",
|
||||
{
|
||||
@ -323,6 +306,16 @@ def evaluation_create_form(
|
||||
dest_url = url_for(
|
||||
"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:
|
||||
head = html_sco_header.sco_header(page_title=page_title)
|
||||
return (
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.6.93"
|
||||
SCOVERSION = "9.6.931"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user