1
0
Fork 0
mirror of https://codeberg.org/Mo8it/AdvLabDB.git synced 2024-12-04 22:40:30 +00:00

Compare commits

...

6 commits

Author SHA1 Message Date
a2162363b9 Implemented semester done logic 2022-09-17 15:55:49 +02:00
d18579059a Add post-login 2022-09-17 15:55:09 +02:00
6dd02d3fbc Only allow to choose semesters not done for assistants 2022-09-16 23:01:17 +02:00
56cedaa308 Remove setActiveSemester and its route 2022-09-16 22:59:42 +02:00
c0b0e18332 Migrate to fsqla_v3 2022-09-16 20:04:42 +02:00
28e80c27fa Add done to models 2022-09-16 20:02:55 +02:00
5 changed files with 80 additions and 41 deletions

View file

@ -128,7 +128,7 @@ class UserView(SecureAdminModelView):
@staticmethod
def semesterQueryFactory():
return Semester.query.order_by(Semester.id.desc())
return Semester.query.order_by(Semester.id.desc()).where(Semester.done == False)
@staticmethod
def default_roles():
@ -288,6 +288,8 @@ class UserView(SecureAdminModelView):
f"{model.email} registered with role(s): {', '.join(role.name for role in model.roles)}.",
category="success",
)
else:
flash(f"Active semester is {model.active_semester}.", "warning")
class SemesterView(SecureAdminModelView):
@ -331,13 +333,13 @@ class SemesterView(SecureAdminModelView):
default=True,
)
can_edit = False
can_delete = False
column_display_all_relations = True
column_list = [
"label",
"year",
"done",
"parts",
]
column_searchable_list = [
@ -345,8 +347,11 @@ class SemesterView(SecureAdminModelView):
"year",
]
column_default_sort = [
("year", True),
("label", True),
("id", True),
]
form_columns = [
"done",
]
column_formatters = {
@ -361,6 +366,12 @@ class SemesterView(SecureAdminModelView):
"groups": str_without_semester_formatter,
}
form_args = {
"done": {
"description": "Marking a semester as done does not let assistants work in the semester anymore. This is useful if all marks are already set and prevents assistants from changing or even seeing them after the semester is marked as done. Setting a semester as done sets older semesters as done, too. Only set the semester as done if all marks in the semester and all previous semesters are already set."
},
}
def customCreateModel(self, form):
return Semester.initFromOldSemester(
label=form.label.data,
@ -370,8 +381,32 @@ class SemesterView(SecureAdminModelView):
transferAssistants=form.transfer_assistants.data,
)
def after_model_change(self, form, model, is_created):
current_user.setActiveSemester(model)
def on_model_change(self, form, model, is_created):
if is_created:
current_user.active_semester = model
flash(f"Active semester changed to the new semester {model}!", "warning")
else:
if model.done:
next_semester = db.session.get(Semester, model.id + 1)
set_next_semester = next_semester is not None
# Set all previous semesters as done
for id in range(1, model.id + 1):
semester = db.session.get(Semester, id)
if semester == model or not semester.done:
semester.done = True
if set_next_semester:
# Set active_semester to next_semester
users_in_semester_done = db.session.execute(
select(User).where(User.active_semester == semester)
).scalars()
for user in users_in_semester_done:
user.active_semester = next_semester
if user == current_user:
flash(f"Active semester changed to the next semester {next_semester}!", "warning")
def programQueryFactory():

View file

@ -189,7 +189,7 @@ class AssistantUserView(SecureAssistantModelView):
@staticmethod
def semesterQueryFactory():
# Show only last two semesters to assistants
return Semester.query.order_by(Semester.id.desc()).limit(2)
return Semester.query.order_by(Semester.id.desc()).limit(2).where(Semester.done == False)
active_semester = QuerySelectField(
"Active Semester",

View file

@ -81,4 +81,5 @@ def set_config(app, data_dir: Path):
}
app.config["SECURITY_PASSWORD_SALT"] = secrets["SECURITY_PASSWORD_SALT"]
app.config["SECURITY_PASSWORD_LENGTH_MIN"] = settings.getint("SECURITY_PASSWORD_LENGTH_MIN", 15)
app.config["SECURITY_POST_LOGIN_VIEW"] = "/post-login"
# TODO: app.config["SECURITY_LOGIN_USER_TEMPLATE"] =

View file

@ -10,8 +10,7 @@ from decimal import ROUND_HALF_UP, Decimal
from flask import flash
from flask_login import current_user
from flask_security.models import fsqla_v2 as fsqla
from flask_security.models.fsqla_v2 import FsRoleMixin, FsUserMixin
from flask_security.models.fsqla_v3 import FsModels, FsRoleMixin, FsUserMixin
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import func, select
@ -30,7 +29,7 @@ MIN_PART_NUMBER = 1
db = SQLAlchemy()
# For Flask-Security-Too
fsqla.FsModels.set_db_info(db)
FsModels.set_db_info(db)
def get_count(table):
@ -515,6 +514,8 @@ class Semester(db.Model):
id = db.Column(db.Integer, primary_key=True)
label = db.Column(db.String(10), db.CheckConstraint("label IN ('WS', 'SS')"), nullable=False)
year = db.Column(db.Integer, db.CheckConstraint(f"year BETWEEN {MIN_YEAR} AND {MAX_YEAR}"), nullable=False)
# Assistants can not work in semesters that are done
done = db.Column(db.Boolean, default=False, nullable=False)
parts = db.relationship("Part", back_populates="semester", lazy=True)
semester_experiments = db.relationship("SemesterExperiment", back_populates="semester", lazy=True)
@ -688,22 +689,6 @@ class User(db.Model, FsUserMixin):
def __str__(self):
return self.str()
def setActiveSemester(self, semester):
if semester is None:
flash("Can not change the active semester to None!", "error")
return
if self.active_semester != semester:
try:
self.active_semester = semester
db.session.commit()
except Exception as ex:
flash(str(ex), "error")
db.session.rollback()
else:
flash(f"Active semester changed to {semester}!", "warning")
class Role(db.Model, FsRoleMixin):
def str(self):

View file

@ -25,24 +25,42 @@ def index():
else:
return redirect(url_for("security.login"))
url = url_for(endpoint_base + ".index")
return redirect(url)
@bp.route("/post-login")
@auth_required()
def post_login():
current_active_semester = current_user.active_semester
if current_active_semester.done:
last_semester = Semester.lastSemester()
if not last_semester.done:
try:
current_user.active_semester = last_semester
db.session.commit()
except Exception as ex:
flash(str(ex), "error")
db.session.rollback()
else:
flash(
f"Active semester changed to {last_semester} because the semester {current_active_semester} was marked as done!",
"warning",
)
if current_user.has_role("admin"):
endpoint_base = "admin"
else:
endpoint_base = "assistant"
if current_user.login_count == 1:
url = url_for(endpoint_base + "_docs.index")
else:
url = url_for(endpoint_base + ".index")
return redirect(url)
@bp.route("/set_semester")
@auth_required()
def set_semester():
try:
semesterId = int(request.args.get("semester_id"))
except Exception as ex:
flash(str(ex), "error")
else:
semester = db.session.get(Semester, semesterId)
current_user.setActiveSemester(semester)
red = request.referrer or url_for("main.index")
return redirect(red)