add endpoint for generate term of defence for coordinator view

This commit is contained in:
dominik24c 2022-11-17 18:39:45 +01:00
parent 0722eb9648
commit 2e3a7b24f0
3 changed files with 70 additions and 5 deletions

View File

@ -18,7 +18,7 @@ class Config:
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_DATABASE_URI = f'sqlite:///{BASE_DIR / "db.sqlite"}' SQLALCHEMY_DATABASE_URI = f'sqlite:///{BASE_DIR / "db.sqlite"}'
LIMIT_STUDENTS_PER_GROUP = 5 LIMIT_STUDENTS_PER_GROUP = 5
LIMIT_PERSONS_PER_COMMITTEE = 4 LIMIT_MEMBERS_PER_COMMITTEE = 3
DESCRIPTION = 'System PRI' DESCRIPTION = 'System PRI'
OPENAPI_VERSION = '3.0.2' OPENAPI_VERSION = '3.0.2'

View File

@ -1,7 +1,8 @@
import datetime import datetime
from itertools import islice
from apiflask import APIBlueprint from apiflask import APIBlueprint
from flask import abort from flask import abort, current_app
from sqlalchemy import or_, and_ from sqlalchemy import or_, and_
from ..schemas import MessageSchema, TermOfDefenceSchema, TermOfDefenceListSchema, \ from ..schemas import MessageSchema, TermOfDefenceSchema, TermOfDefenceListSchema, \
@ -10,13 +11,64 @@ from ...examination_schedule.models import ExaminationSchedule, TermOfDefence, T
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
from ..utils import generate_range_dates
bp = APIBlueprint("enrollments", __name__, url_prefix="/enrollments") bp = APIBlueprint("enrollments", __name__, url_prefix="/enrollments")
@bp.post('/<int:examination_schedule_id>/generate') @bp.post('/<int:examination_schedule_id>/generate')
@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:
pass ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
if ex is None:
abort(404, "Not found examination schedule!")
# 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)
# in future optimize sql query
# project_supervisor cache in memory (flyweight)
# while True:
# sliced_dates = islice(dates, 1)
# list_of_dates = list(sliced_dates)
#
# if len(list_of_dates) == 0:
# break
for d in dates:
e = d + datetime.timedelta(minutes=ex.duration_time)
# print(f"{d} - {e}")
temporary_availabilities = TemporaryAvailability.query.filter(
TemporaryAvailability.examination_schedule_id == examination_schedule_id). \
filter(TemporaryAvailability.start_date <= d,
TemporaryAvailability.end_date >= e).all()
if len(temporary_availabilities) >= limit:
# create term of defence
# check term of defence exist in this date range
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.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!"}
@bp.post('/<int:examination_schedule_id>/add') @bp.post('/<int:examination_schedule_id>/add')

View File

@ -1,8 +1,9 @@
import datetime import copy
from datetime import datetime, timedelta
from collections import defaultdict from collections import defaultdict
from io import BytesIO from io import BytesIO
from itertools import chain from itertools import chain
from typing import Generator, Any, List, Tuple from typing import Generator, Union, Any, List, Tuple
import pandas as pd import pandas as pd
from reportlab.lib import colors from reportlab.lib import colors
@ -65,6 +66,18 @@ def generate_csv(students_and_groups: List[Tuple[Student, Group]]) -> str:
return df.to_csv(index=False) return df.to_csv(index=False)
def generate_range_dates(start_date: datetime, end_date: datetime, step_in_minutes: int) -> \
Generator[Union[datetime, timedelta], Any, None]:
current_date = copy.copy(start_date)
while True:
next_date = current_date + timedelta(minutes=step_in_minutes)
if next_date > end_date:
break
yield current_date
current_date = copy.copy(next_date)
def generate_examination_schedule_pdf_file(title: str, nested_enrollments: List[List[object]]) -> bytes: def generate_examination_schedule_pdf_file(title: str, nested_enrollments: List[List[object]]) -> bytes:
pagesize = (297 * mm, 210 * mm) pagesize = (297 * mm, 210 * mm)
headers = ["lp.", "Godzina", "Nazwa projektu", "Opiekun", "Zespol", "Komisja"] headers = ["lp.", "Godzina", "Nazwa projektu", "Opiekun", "Zespol", "Komisja"]