add endpoint for generate term of defence for coordinator view
This commit is contained in:
parent
0722eb9648
commit
2e3a7b24f0
@ -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'
|
||||||
|
@ -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')
|
||||||
|
@ -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"]
|
||||||
|
Loading…
Reference in New Issue
Block a user