from datetime import datetime from apiflask import APIBlueprint from flask import abort from sqlalchemy import and_, or_ from ..schemas import TimeAvailabilityCreateSchema, TemporaryProjectSupervisorSchema, \ ListOfFreeTimesSchema, ListOfTermOfDefenceSchema from ...dependencies import db from ..models import ProjectSupervisor from ...examination_schedule.models import ExaminationSchedule, TemporaryAvailability, TermOfDefence from ...base.schemas import MessageSchema bp = APIBlueprint("enrollments", __name__, url_prefix="/") @bp.post('//enrollments/') @bp.input(TimeAvailabilityCreateSchema) @bp.output(MessageSchema) def set_your_free_time_to_examination_schedule(examination_schedule_id: int, data: dict) -> dict: # this code will be removed project_supervisor = ProjectSupervisor.query.filter(ProjectSupervisor.id == data['project_supervisor_id']).first() if project_supervisor is None: abort(404, "ProjectSupervisor doesn't exist!") ################ es = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first() if es is None: abort(404, "Examination schedule doesn't exist!") sd = data['start_date'] ed = data['end_date'] if sd > ed: abort(400, "Invalid data! End date must be greater than start date!") if not (es.start_date.timestamp() <= sd.timestamp() and es.end_date.timestamp() >= ed.timestamp()): abort(400, "Date range is not within the examination schedule!") now = datetime.utcnow() if es.start_date_for_enrollment_students is not None and \ es.start_date_for_enrollment_students.timestamp() < now.timestamp(): abort(403, "Enrollment has started! You cannot set your free time!") ta = TemporaryAvailability.query.filter(TemporaryAvailability.examination_schedule_id == examination_schedule_id). \ filter(TemporaryAvailability.project_supervisor_id == project_supervisor.id). \ filter(or_(and_(TemporaryAvailability.start_date >= sd, TemporaryAvailability.start_date < ed, TemporaryAvailability.end_date >= ed), and_(TemporaryAvailability.start_date <= sd, TemporaryAvailability.end_date > sd, 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) db.session.add(ta) db.session.commit() return {"message": "You have just assigned your free time!"} @bp.delete('//enrollments//') @bp.input(TemporaryProjectSupervisorSchema) @bp.output(MessageSchema) def delete_your_free_time_from_examination_schedule(examination_schedule_id: int, temporary_availability_id: int, data: dict) -> dict: # this code will be removed project_supervisor = db.session.query(ProjectSupervisor).filter(ProjectSupervisor.id == data['id']).first() if project_supervisor is None: abort(404, "ProjectSupervisor doesn't exist!") ################ ta = TemporaryAvailability.query.filter(TemporaryAvailability.examination_schedule_id == examination_schedule_id, TemporaryAvailability.project_supervisor_id == project_supervisor.id, TemporaryAvailability.id == temporary_availability_id).first() if ta is None: abort(404, "Your free time doesn't exist!") db.session.delete(ta) db.session.commit() return {"message": "You have just removed your free time!"} @bp.get('//temporary-availabilities/') @bp.input(TemporaryProjectSupervisorSchema, location='query') @bp.output(ListOfFreeTimesSchema) def list_enrollments_for_project_supervisor(examination_schedule_id: int, data: dict) -> dict: # this code will be removed project_supervisor = db.session.query(ProjectSupervisor).filter(ProjectSupervisor.id == data['id']).first() if project_supervisor is None: abort(404, "ProjectSupervisor doesn't exist!") ################ es = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id, ExaminationSchedule.year_group_id).first() if es is None: abort(404, "Examination schedule doesn't exist!") now = datetime.utcnow() start_date = es.start_date_for_enrollment_students if start_date is not None and start_date.timestamp() < now.timestamp(): abort(403, "Forbidden! Enrollment has just started! You cannot assign to the exam committees!") # list of your term of defences first enrollment ta = TemporaryAvailability.query.filter(TemporaryAvailability.examination_schedule_id == examination_schedule_id, TemporaryAvailability.project_supervisor_id == project_supervisor.id).all() return {"free_times": ta} @bp.get('//term-of-defences/') @bp.input(TemporaryProjectSupervisorSchema, location='query') @bp.output(ListOfTermOfDefenceSchema) def list_created_term_of_defences_by_coordinator_for_project_supervisor(examination_schedule_id: int, data: dict) -> dict: # this code will be removed project_supervisor = db.session.query(ProjectSupervisor).filter(ProjectSupervisor.id == data['id']).first() if project_supervisor is None: abort(404, "ProjectSupervisor doesn't exist!") ################ es = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id, ExaminationSchedule.year_group_id).first() if es is None: abort(404, "Examination schedule doesn't exist!") # list of your free times first enrollment td = TermOfDefence.query.join(TermOfDefence.members_of_committee). \ filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \ filter_by(id=project_supervisor.id).all() return {"term_of_defences": td}