diff --git a/backend/app/coordinator/routes/examination_schedule.py b/backend/app/coordinator/routes/examination_schedule.py index 504cefd..fafbb4b 100644 --- a/backend/app/coordinator/routes/examination_schedule.py +++ b/backend/app/coordinator/routes/examination_schedule.py @@ -1,12 +1,12 @@ import datetime from apiflask import APIBlueprint -from flask import abort, Response, make_response +from flask import abort, Response, make_response, current_app from ...base.utils import paginate_models from ...base.mode import ModeGroups from ...dependencies import db -from ...examination_schedule.models import ExaminationSchedule +from ...examination_schedule.models import ExaminationSchedule, TermOfDefence from ...students.models import Group, YearGroup from ...project_supervisor.models import ProjectSupervisor from ..schemas import ExaminationScheduleSchema, ExaminationScheduleUpdateSchema, MessageSchema, \ @@ -104,19 +104,22 @@ def download_examination_schedule(examination_schedule_id: int) -> Response: if examination_schedule is None: abort(404, "Examination schedule doesn't exist!") - distinct_dates = db.session.query(db.func.Date(Enrollment.start_date)).distinct().all() - # print(distinct_dates) - nested_enrollments = [] + distinct_dates = db.session.query(db.func.Date(TermOfDefence.start_date)).distinct().all() + + nested_term_of_defences = [] for d in distinct_dates: date_tmp = datetime.datetime.strptime(d[0], "%Y-%m-%d").date() - enrollment = db.session.query(Enrollment).join(ExaminationSchedule, isouter=True). \ + term_of_defences = db.session.query(TermOfDefence). \ join(Group, isouter=True).join(ProjectSupervisor, isouter=True). \ - filter(ExaminationSchedule.id == examination_schedule_id).filter( - db.func.Date(Enrollment.start_date) == date_tmp).all() - nested_enrollments.append(enrollment) - - # print(nested_enrollments) - pdf = generate_examination_schedule_pdf_file(examination_schedule.title, nested_enrollments) + filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \ + filter(TermOfDefence.group_id.isnot(None)). \ + filter(db.func.Date(TermOfDefence.start_date) == date_tmp). \ + all() + if len(term_of_defences) > 0: + nested_term_of_defences.append(term_of_defences) + # print(nested_term_of_defences) + base_dir = current_app.config.get('BASE_DIR') + pdf = generate_examination_schedule_pdf_file(examination_schedule.title, nested_term_of_defences, base_dir) title = examination_schedule.title.replace("-", "_").split() filename = "_".join(title) diff --git a/backend/app/coordinator/utils.py b/backend/app/coordinator/utils.py index 2dde9ec..713fb9a 100644 --- a/backend/app/coordinator/utils.py +++ b/backend/app/coordinator/utils.py @@ -1,9 +1,9 @@ import copy -from datetime import datetime, timedelta from collections import defaultdict +from datetime import datetime, timedelta from io import BytesIO -from itertools import chain from typing import Generator, Union, Any, List, Tuple +from pathlib import Path import pandas as pd from reportlab.lib import colors @@ -11,10 +11,13 @@ from reportlab.lib.enums import TA_CENTER from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.units import mm, inch from reportlab.platypus import SimpleDocTemplate, Paragraph, PageBreak, Table +from reportlab.pdfbase import pdfmetrics +from reportlab.pdfbase.ttfonts import TTFont from werkzeug.datastructures import FileStorage from .exceptions import InvalidNameOrTypeHeaderException from ..students.models import Student, Group +from ..examination_schedule.models import TermOfDefence def check_columns(df: pd.DataFrame) -> bool: @@ -78,7 +81,8 @@ def generate_range_dates(start_date: datetime, end_date: datetime, step_in_minut 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_term_of_defences: List[List[TermOfDefence]], + base_dir: Path) -> bytes: pagesize = (297 * mm, 210 * mm) headers = ["lp.", "Godzina", "Nazwa projektu", "Opiekun", "Zespol", "Komisja"] pdf_buffer = BytesIO() @@ -92,44 +96,42 @@ def generate_examination_schedule_pdf_file(title: str, nested_enrollments: List[ title=title ) + pdfmetrics.registerFont(TTFont('Lato', base_dir / 'fonts' / 'Lato.ttf')) style = getSampleStyleSheet() bodyText = style['BodyText'] - bodyText.fontName = 'Helvetica' + bodyText.fontName = 'Lato' normal = style["Heading1"] normal.alignment = TA_CENTER flowables = [] # print(nested_enrollments) - for enrollments in nested_enrollments: - if len(enrollments) == 0: + for term_of_defences in nested_term_of_defences: + if len(term_of_defences) == 0: continue - date = datetime.datetime.strftime(enrollments[0].start_date, '%d/%m/%Y') + date = datetime.strftime(term_of_defences[0].start_date.date(), '%d.%m.%Y') paragraph_1 = Paragraph(f"{title} ~ {date}", normal) flowables.append(paragraph_1) data = [headers] - for idx, e in enumerate(enrollments, start=1): - new_date = e.start_date + datetime.timedelta(hours=2) - group_name = e.group.name if e.group is not None else "" + for idx, td in enumerate(term_of_defences, start=1): + new_date = td.start_date + timedelta(hours=2) + group_name = td.group.name if td.group is not None else "" if group_name != '': - ps = e.group.project_supervisor + ps = td.group.project_supervisor project_supervisor_fullname = f"{ps.first_name[0]}. {ps.last_name}" - students = e.group.students + students = td.group.students # print(students) team = ", ".join([f"{s.first_name} {s.last_name}" for s in students]) else: project_supervisor_fullname = "" team = "" - members = e.committee.members + members = td.members_of_committee # print(members) if len(members) == 0: committee = '' else: members_iter = (f"{m.first_name[0]} {m.last_name}" for m in members) - if project_supervisor_fullname != '': - members_iter = chain(members_iter, [project_supervisor_fullname]) - committee = ", ".join(members_iter) data.append([str(idx), new_date.strftime("%H:%M"), diff --git a/backend/fonts/Lato.ttf b/backend/fonts/Lato.ttf new file mode 100644 index 0000000..dfa72ce Binary files /dev/null and b/backend/fonts/Lato.ttf differ