update endpoint of generating term of defence and add endpoint of clear all term of defences

This commit is contained in:
dominik24c 2022-11-23 23:45:51 +01:00
parent 62599214dc
commit 5c2e5dcba3
2 changed files with 64 additions and 56 deletions

View File

@ -1,5 +1,4 @@
import datetime import datetime
from itertools import islice
from apiflask import APIBlueprint from apiflask import APIBlueprint
from flask import abort, current_app from flask import abort, current_app
@ -8,7 +7,7 @@ from flask_sqlalchemy import get_debug_queries
from ..schemas import MessageSchema, TermOfDefenceSchema, TermOfDefenceListSchema, \ from ..schemas import MessageSchema, TermOfDefenceSchema, TermOfDefenceListSchema, \
TemporaryAvailabilityListSchema, AssignedGroupToTermOfDefenceListSchema, GroupIdSchema TemporaryAvailabilityListSchema, AssignedGroupToTermOfDefenceListSchema, GroupIdSchema
from ...examination_schedule.models import ExaminationSchedule, TermOfDefence, TemporaryAvailability from ...examination_schedule.models import TermOfDefence, TemporaryAvailability, committee
from ...students.models import YearGroup from ...students.models import YearGroup
from ...project_supervisor.models import ProjectSupervisor from ...project_supervisor.models import ProjectSupervisor
from ...dependencies import db from ...dependencies import db
@ -23,56 +22,66 @@ bp = APIBlueprint("enrollments", __name__, url_prefix="/enrollments")
@bp.output(MessageSchema) @bp.output(MessageSchema)
def generate_term_of_defence_for_this_examination_schedule(examination_schedule_id: int) -> dict: def generate_term_of_defence_for_this_examination_schedule(examination_schedule_id: int) -> dict:
ex = get_examination_schedule_by_id(examination_schedule_id) ex = get_examination_schedule_by_id(examination_schedule_id)
# print(ex.start_date.date())
# print(ex.end_date.date())
dates = generate_range_dates(ex.start_date, ex.end_date, ex.duration_time)
# print(dates)
limit = current_app.config.get('LIMIT_MEMBERS_PER_COMMITTEE', 3) limit = current_app.config.get('LIMIT_MEMBERS_PER_COMMITTEE', 3)
# in future optimize sql query term_of_defences = TermOfDefence.query. \
# project_supervisor cache in memory (flyweight) filter(TermOfDefence.examination_schedule_id == examination_schedule_id).first()
# while True: if term_of_defences is not None:
# sliced_dates = islice(dates, 1) abort(400,
# list_of_dates = list(sliced_dates) "First you have to delete all term of defences for this examination schedule to generate them again!")
#
# if len(list_of_dates) == 0: temporary_availabilities = TemporaryAvailability.query. \
# break filter(TemporaryAvailability.examination_schedule_id == examination_schedule_id). \
join(TemporaryAvailability.project_supervisor). \
all()
if len(temporary_availabilities) == 0:
abort(404, "Not found temporary availabilities for project supervisors")
dates = generate_range_dates(ex.start_date, ex.end_date, ex.duration_time)
print(temporary_availabilities)
for d in dates: for d in dates:
e = d + datetime.timedelta(minutes=ex.duration_time) e = d + datetime.timedelta(minutes=ex.duration_time)
# print(f"{d} - {e}") t = list(filter(lambda ta: ta.start_date <= d and ta.end_date >= e, temporary_availabilities))
temporary_availabilities = TemporaryAvailability.query.filter( if len(t) >= limit:
TemporaryAvailability.examination_schedule_id == examination_schedule_id). \ print(f'{d} -- {e}')
filter(TemporaryAvailability.start_date <= d, print(t)
TemporaryAvailability.end_date >= e).all() print("IN")
if len(temporary_availabilities) >= limit: projects_supervisors = [t[i].project_supervisor for i in range(limit)]
# create term of defence term_of_defence = TermOfDefence(start_date=d, end_date=e, examination_schedule_id=examination_schedule_id)
# check term of defence exist in this date range term_of_defence.members_of_committee = projects_supervisors
td = TermOfDefence.query.filter(or_(and_(TermOfDefence.start_date <= d, TermOfDefence.end_date >= e),
and_(TermOfDefence.start_date > d, TermOfDefence.end_date >= e,
TermOfDefence.start_date < e),
and_(TermOfDefence.start_date <= d, TermOfDefence.end_date > d,
TermOfDefence.end_date < e)
)).first()
if td is None:
term_of_defence = TermOfDefence(start_date=d, end_date=e,
examination_schedule_id=examination_schedule_id)
db.session.add(term_of_defence) db.session.add(term_of_defence)
db.session.commit() db.session.commit()
project_supervisors_ids = []
for i in range(limit):
ta = temporary_availabilities[i]
project_supervisors_ids.append(ta.project_supervisor_id)
project_supervisors = ProjectSupervisor.query.filter(
or_(*[ProjectSupervisor.id == idx for idx in project_supervisors_ids])).all()
for p in project_supervisors:
term_of_defence.members_of_committee.append(p)
db.session.commit()
# print(temporary_availabilities)
return {"message": "Term of defences was generated!"} return {"message": "Term of defences was generated!"}
@bp.post('/<int:examination_schedule_id>/clear-term-of-defences/')
@bp.output(MessageSchema)
def clear_generated_term_of_defences(examination_schedule_id: int) -> dict:
get_examination_schedule_by_id(examination_schedule_id)
# count_defences = db.func.count(ProjectSupervisor.id)
# td = db.session.query(TermOfDefence, count_defences). \
# join(ProjectSupervisor, isouter=True). \
# filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \
# group_by(TermOfDefence.id).having(count_defences > 0).first()
# print(td)
# if td is not None:
# abort(400, "First you remove group assigned to term of defence to clear term of defences!")
td = TermOfDefence.query. \
filter(TermOfDefence.examination_schedule_id == examination_schedule_id).all()
while True:
for t in td[0:10]:
db.session.delete(t)
db.session.commit()
if len(td) == 0:
break
td[0:10] = []
return {"message": "Term of defences was deleted!"}
@bp.post('/<int:examination_schedule_id>/add') @bp.post('/<int:examination_schedule_id>/add')
@bp.input(TermOfDefenceSchema) @bp.input(TermOfDefenceSchema)
@bp.output(MessageSchema) @bp.output(MessageSchema)

View File

@ -2,7 +2,7 @@ from datetime import datetime
from apiflask import APIBlueprint from apiflask import APIBlueprint
from flask import abort from flask import abort
from sqlalchemy import and_, or_
from ..schemas import MessageSchema, TimeAvailabilityCreateSchema, TemporaryProjectSupervisorSchema, \ from ..schemas import MessageSchema, TimeAvailabilityCreateSchema, TemporaryProjectSupervisorSchema, \
ListOfFreeTimesSchema, ListOfTermOfDefenceSchema ListOfFreeTimesSchema, ListOfTermOfDefenceSchema
from ...dependencies import db from ...dependencies import db
@ -17,8 +17,7 @@ bp = APIBlueprint("enrollments", __name__, url_prefix="/")
@bp.output(MessageSchema) @bp.output(MessageSchema)
def set_your_free_time_to_examination_schedule(examination_schedule_id: int, data: dict) -> dict: def set_your_free_time_to_examination_schedule(examination_schedule_id: int, data: dict) -> dict:
# this code will be removed # this code will be removed
project_supervisor = db.session.query(ProjectSupervisor).filter( project_supervisor = ProjectSupervisor.query.filter(ProjectSupervisor.id == data['project_supervisor_id']).first()
ProjectSupervisor.id == data['project_supervisor_id']).first()
if project_supervisor is None: if project_supervisor is None:
abort(404, "ProjectSupervisor doesn't exist!") abort(404, "ProjectSupervisor doesn't exist!")
################ ################
@ -32,22 +31,22 @@ def set_your_free_time_to_examination_schedule(examination_schedule_id: int, dat
if sd > ed: if sd > ed:
abort(400, "Invalid data! End date must be greater than start date!") abort(400, "Invalid data! End date must be greater than start date!")
print(es.start_date.timestamp() >= sd.timestamp())
print(es.end_date.timestamp() <= ed.timestamp())
if not (es.start_date.timestamp() <= sd.timestamp() and es.end_date.timestamp() >= ed.timestamp()): if not (es.start_date.timestamp() <= sd.timestamp() and es.end_date.timestamp() >= ed.timestamp()):
abort(400, "Invalid date ranges!") abort(400, "Date range is not within the examination schedule!")
now = datetime.utcnow() now = datetime.utcnow()
if es.start_date_for_enrollment_students is not None and \ if es.start_date_for_enrollment_students is not None and \
es.start_date_for_enrollment_students.timestamp() < now.timestamp(): es.start_date_for_enrollment_students.timestamp() < now.timestamp():
abort(403, "Enrollment has started! You cannot set your free time!") abort(403, "Enrollment has started! You cannot set your free time!")
ta_query = TemporaryAvailability.query.filter( ta = TemporaryAvailability.query.filter(TemporaryAvailability.examination_schedule_id == examination_schedule_id). \
TemporaryAvailability.examination_schedule_id == examination_schedule_id). \ filter(TemporaryAvailability.project_supervisor_id == project_supervisor.id). \
filter(TemporaryAvailability.project_supervisor_id == project_supervisor.id) filter(or_(and_(TemporaryAvailability.start_date >= sd, TemporaryAvailability.start_date < ed,
if ta_query.first() is not None: TemporaryAvailability.end_date >= ed),
# implement logic and_(TemporaryAvailability.start_date <= sd, TemporaryAvailability.end_date > sd,
pass TemporaryAvailability.end_date <= ed))).first()
if ta is not None:
abort(400, "Invalid date ranges. You set your free time in this date range! Choose another date!")
ta = TemporaryAvailability(**data, examination_schedule_id=examination_schedule_id) ta = TemporaryAvailability(**data, examination_schedule_id=examination_schedule_id)
db.session.add(ta) db.session.add(ta)