system-pri/backend/app/coordinator/routes/enrollments.py

175 lines
6.9 KiB
Python

import datetime
from apiflask import APIBlueprint
from flask import abort
from sqlalchemy import or_, and_
from ..schemas import MessageSchema, TermOfDefenceSchema, TermOfDefenceListSchema, \
TemporaryAvailabilityListSchema
from ...examination_schedule.models import ExaminationSchedule, TermOfDefence, TemporaryAvailability
from ...students.models import YearGroup
from ...project_supervisor.models import ProjectSupervisor
from ...dependencies import db
bp = APIBlueprint("enrollments", __name__, url_prefix="/enrollments")
@bp.post('/<int:examination_schedule_id>/generate')
def generate_term_of_defence_for_this_examination_schedule(examination_schedule_id: int) -> dict:
pass
@bp.post('/<int:examination_schedule_id>/add')
@bp.input(TermOfDefenceSchema)
@bp.output(MessageSchema)
def create_term_of_defence(examination_schedule_id: int, data: dict) -> dict:
if not data:
abort(400, "You have passed empty data!")
ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
if ex is None:
abort(404, "Not found examination schedule!")
yg_id = ex.year_group_id
project_supervisors_ids = data.pop('project_supervisors')
project_supervisors = ProjectSupervisor.query.filter(
or_(*[ProjectSupervisor.id == i for i in project_supervisors_ids])).filter(YearGroup.id == yg_id).all()
if len(project_supervisors) != len(project_supervisors_ids):
abort(404, "Project Supervisors didn't exist!")
start_date = data['start_date']
end_date = data['end_date']
if not (ex.start_date.timestamp() < start_date.timestamp() and ex.end_date.timestamp() > end_date.timestamp()):
abort(400, "Invalid date range!")
if end_date <= start_date:
abort(400, "End date must be greater than start date!")
delta_time = end_date - start_date
delta_time_in_minutes = delta_time.total_seconds() / 60
if delta_time_in_minutes != ex.duration_time:
abort(400, "Invalid duration time!")
td = TermOfDefence.query.filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \
filter(
or_(and_(TermOfDefence.start_date >= start_date,
TermOfDefence.start_date < end_date,
TermOfDefence.end_date >= end_date),
and_(TermOfDefence.start_date <= start_date,
TermOfDefence.end_date > start_date,
TermOfDefence.end_date <= end_date))).first()
if td is not None:
abort(400, "This term of defence is taken! You choose other date!")
td = TermOfDefence(**data, examination_schedule_id=examination_schedule_id)
db.session.add(td)
db.session.commit()
for p in project_supervisors:
td.members_of_committee.append(p)
db.session.commit()
return {"message": "Term of defence was created!"}
@bp.put('/<int:examination_schedule_id>/update/<int:term_of_defence_id>/')
@bp.input(TermOfDefenceSchema)
@bp.output(MessageSchema)
def update_term_of_defence(examination_schedule_id: int, term_of_defence_id: int, data: dict) -> dict:
if not data:
abort(400, "You have passed empty data!")
td_query = TermOfDefence.query.filter(TermOfDefence.id == term_of_defence_id,
TermOfDefence.examination_schedule_id == examination_schedule_id)
td = td_query.first()
if td is None:
abort(404, "Not found term of defence!")
ex = td.examination_schedule
yg_id = ex.year_group_id
project_supervisors_ids = data.pop('project_supervisors')
project_supervisors = ProjectSupervisor.query.filter(
or_(*[ProjectSupervisor.id == i for i in project_supervisors_ids])).filter(YearGroup.id == yg_id).all()
if len(project_supervisors) != len(project_supervisors_ids):
abort(404, "Project Supervisors didn't exist!")
start_date = data['start_date']
end_date = data['end_date']
if not (ex.start_date.timestamp() < start_date.timestamp() and ex.end_date.timestamp() > end_date.timestamp()):
abort(400, "Invalid date range!")
if end_date <= start_date:
abort(400, "End date must be greater than start date!")
delta_time = end_date - start_date
delta_time_in_minutes = delta_time.total_seconds() / 60
if delta_time_in_minutes != ex.duration_time:
abort(400, "Invalid duration time!")
term_of_defence = TermOfDefence.query.filter(TermOfDefence.id != term_of_defence_id,
TermOfDefence.examination_schedule_id == examination_schedule_id). \
filter(
or_(and_(TermOfDefence.start_date >= start_date,
TermOfDefence.start_date < end_date,
TermOfDefence.end_date >= end_date),
and_(TermOfDefence.start_date <= start_date,
TermOfDefence.end_date > start_date,
TermOfDefence.end_date <= end_date))).first()
if term_of_defence is not None:
abort(400, "This term of defence is taken! You choose other date!")
td_query.update(data)
td.members_of_committee = []
db.session.commit()
for p in project_supervisors:
td.members_of_committee.append(p)
db.session.commit()
return {"message": "Term of defence was updated!"}
@bp.delete('/<int:examination_schedule_id>/delete/<int:term_of_defence_id>/')
@bp.output(MessageSchema)
def delete_term_of_defence(examination_schedule_id: int, term_of_defence_id: int) -> dict:
td = TermOfDefence.query.filter(TermOfDefence.id == term_of_defence_id,
ExaminationSchedule.id == examination_schedule_id).first()
if td is None:
abort(404, "Not found term of defence!")
db.session.delete(td)
db.session.commit()
return {"message": "Term of defence was deleted!"}
@bp.get('/<int:examination_schedule_id>/term-of-defences/')
@bp.output(TermOfDefenceListSchema)
def list_of_term_of_defences(examination_schedule_id: int) -> dict:
ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
if ex is None:
abort(400, "Examination Schedule didn't exist")
td = TermOfDefence.query. \
filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \
join(TermOfDefence.members_of_committee, isouter=True). \
all()
return {"term_of_defences": td}
@bp.get('/<int:examination_schedule_id>/temporary-availabilities/')
@bp.output(TemporaryAvailabilityListSchema)
def list_of_temporary_availability(examination_schedule_id: int) -> dict:
ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
if ex is None:
abort(400, "Examination Schedule didn't exist")
td = TemporaryAvailability.query. \
filter(TemporaryAvailability.examination_schedule_id == examination_schedule_id). \
join(TemporaryAvailability.project_supervisor). \
all()
return {"temporary_availabilities": td}