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_DATABASE_URI = f'sqlite:///{BASE_DIR / "db.sqlite"}'
LIMIT_STUDENTS_PER_GROUP = 5
LIMIT_PERSONS_PER_COMMITTEE = 4
LIMIT_MEMBERS_PER_COMMITTEE = 3
DESCRIPTION = 'System PRI'
OPENAPI_VERSION = '3.0.2'

View File

@ -1,7 +1,8 @@
import datetime
from itertools import islice
from apiflask import APIBlueprint
from flask import abort
from flask import abort, current_app
from sqlalchemy import or_, and_
from ..schemas import MessageSchema, TermOfDefenceSchema, TermOfDefenceListSchema, \
@ -10,13 +11,64 @@ from ...examination_schedule.models import ExaminationSchedule, TermOfDefence, T
from ...students.models import YearGroup
from ...project_supervisor.models import ProjectSupervisor
from ...dependencies import db
from ..utils import generate_range_dates
bp = APIBlueprint("enrollments", __name__, url_prefix="/enrollments")
@bp.post('/<int:examination_schedule_id>/generate')
@bp.output(MessageSchema)
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')

View File

@ -1,8 +1,9 @@
import datetime
import copy
from datetime import datetime, timedelta
from collections import defaultdict
from io import BytesIO
from itertools import chain
from typing import Generator, Any, List, Tuple
from typing import Generator, Union, Any, List, Tuple
import pandas as pd
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)
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:
pagesize = (297 * mm, 210 * mm)
headers = ["lp.", "Godzina", "Nazwa projektu", "Opiekun", "Zespol", "Komisja"]