diff --git a/backend/app/__init__.py b/backend/app/__init__.py index 0dfe872..c66c151 100644 --- a/backend/app/__init__.py +++ b/backend/app/__init__.py @@ -8,6 +8,7 @@ from .config import config from .dependencies import db, ma from .commands.startapp import startapp from .commands.init_db import init_db +from .commands.clear_db import clear_db from .utils import import_models from .api import api_bp from .errors import request_entity_too_large, register_error_handlers @@ -37,6 +38,7 @@ def create_app(config_name: str = '') -> APIFlask: # register commands app.cli.add_command(startapp) app.cli.add_command(init_db) + app.cli.add_command(clear_db) # register errors register_error_handlers(app) diff --git a/backend/app/commands/clear_db.py b/backend/app/commands/clear_db.py new file mode 100644 index 0000000..66cbd15 --- /dev/null +++ b/backend/app/commands/clear_db.py @@ -0,0 +1,12 @@ +from flask.cli import with_appcontext +from click import command + +from ..dependencies import db + + +@command('clear_db') +@with_appcontext +def clear_db() -> None: + """Clear database""" + db.drop_all() + db.create_all() diff --git a/backend/app/coordinator/routes/__init__.py b/backend/app/coordinator/routes/__init__.py index 7372046..9e2e32f 100644 --- a/backend/app/coordinator/routes/__init__.py +++ b/backend/app/coordinator/routes/__init__.py @@ -1,10 +1,11 @@ from flask import Blueprint -from .students import bp as students_bp -from .project_supervisor import bp as project_supervisor_bp -from .groups import bp as groups_bp from .examination_schedule import bp as examination_schedule_bp from .enrollments import bp as enrollments_bp +from .groups import bp as groups_bp +from .project_supervisor import bp as project_supervisor_bp +from .students import bp as students_bp +from .workloads import bp as workloads_bp bp = Blueprint("coordinator", __name__, url_prefix="/coordinator") @@ -13,3 +14,4 @@ bp.register_blueprint(project_supervisor_bp) bp.register_blueprint(groups_bp) bp.register_blueprint(examination_schedule_bp) bp.register_blueprint(enrollments_bp) +bp.register_blueprint(workloads_bp) diff --git a/backend/app/coordinator/routes/groups.py b/backend/app/coordinator/routes/groups.py index 72b4035..94e3424 100644 --- a/backend/app/coordinator/routes/groups.py +++ b/backend/app/coordinator/routes/groups.py @@ -71,7 +71,7 @@ def create_group(data: dict) -> dict: db.session.commit() - return {"message": "Project Supervisor was created!"} + return {"message": "Group was created!"} @bp.route("//", methods=["GET"]) diff --git a/backend/app/coordinator/routes/workloads.py b/backend/app/coordinator/routes/workloads.py new file mode 100644 index 0000000..34beea8 --- /dev/null +++ b/backend/app/coordinator/routes/workloads.py @@ -0,0 +1,33 @@ +from apiflask import APIBlueprint +from flask import abort +from flask_sqlalchemy import get_debug_queries + +from ...dependencies import db +from ...examination_schedule.models import ExaminationSchedule, Enrollment, Committee +from ...project_supervisor.models import ProjectSupervisor +from ..schemas import WorkloadSchema + +bp = APIBlueprint("workloads", __name__, url_prefix="/") + + +@bp.get('/examination_schedule//workloads/') +@bp.output(WorkloadSchema) +def workloads_statistics(examination_schedule_id: int) -> dict: + es = ExaminationSchedule.query.filter_by(id=examination_schedule_id).first() + if es is None: + abort(404, "Not found examination schedule!") + + statistics = db.session.query( + ProjectSupervisor.first_name + " " + ProjectSupervisor.last_name, + db.func.count(Enrollment.group_id), + db.func.count(Committee.id), + ).join(Committee.members). \ + join(Enrollment, isouter=True). \ + group_by(ProjectSupervisor.id).all() + + # print(statistics) + # print(len(statistics)) + # print(get_debug_queries()) + workloads = ({"full_name": s[0], "groups_assigned_to_his_committee": s[1], "assigned_to_committee": s[2]} for s in + statistics) + return {'workloads': workloads} diff --git a/backend/app/coordinator/schemas/__init__.py b/backend/app/coordinator/schemas/__init__.py index 3ff75e7..6599de1 100644 --- a/backend/app/coordinator/schemas/__init__.py +++ b/backend/app/coordinator/schemas/__init__.py @@ -1,6 +1,6 @@ from .enrollments import EnrollmentCreateSchema from .examination_schedule import ExaminationScheduleSchema, ExaminationScheduleUpdateSchema, \ - ExaminationSchedulesPaginationSchema, ExaminationSchedulesQuerySchema + ExaminationSchedulesPaginationSchema, ExaminationSchedulesQuerySchema, WorkloadSchema from .groups import GroupQuerySchema, GroupsPaginationSchema, GroupCreateSchema, GroupEditSchema from .project_supervisor import ProjectSupervisorQuerySchema, ProjectSupervisorsPaginationSchema, \ ProjectSupervisorCreateSchema, ProjectSupervisorEditSchema diff --git a/backend/app/coordinator/schemas/examination_schedule.py b/backend/app/coordinator/schemas/examination_schedule.py index c66073b..a6c2925 100644 --- a/backend/app/coordinator/schemas/examination_schedule.py +++ b/backend/app/coordinator/schemas/examination_schedule.py @@ -29,3 +29,13 @@ class ExaminationSchedulesPaginationSchema(Schema): class ExaminationSchedulesQuerySchema(Schema): page = fields.Integer() per_page = fields.Integer() + + +class ProjectSupervisorStatisticsSchema(Schema): + full_name = fields.Str() + assigned_to_committee = fields.Integer() + groups_assigned_to_his_committee = fields.Integer() + + +class WorkloadSchema(Schema): + workloads = fields.List(fields.Nested(ProjectSupervisorStatisticsSchema)) diff --git a/backend/app/students/routes/enrollments.py b/backend/app/students/routes/enrollments.py index 2b6fe9c..a8ab304 100644 --- a/backend/app/students/routes/enrollments.py +++ b/backend/app/students/routes/enrollments.py @@ -5,6 +5,7 @@ from flask import abort from ..schemas import MessageSchema, TemporaryStudentSchema from ...dependencies import db +from ...examination_schedule.models import Enrollment from ..models import Student, Group from ...project_supervisor.models import ProjectSupervisor from ...project_supervisor.query import get_enrollment_by_enrollment_and_examination_schedule_ids, \ @@ -23,11 +24,15 @@ def assign_group_for_this_exam_date(examination_schedule_id: int, enrollment_id: if student is None: abort(404, "Student doesn't exist!") ################ + st = Student.query.join(Group).join(ProjectSupervisor).filter(Student.index == student.index).first() + + enrollment = db.session.query(Enrollment.id).filter(Enrollment.group_id == st.group.id).first() + if enrollment is not None: + abort(400, "Your group has already assigned to any exam date!") enrollment = get_enrollment_by_enrollment_and_examination_schedule_ids(examination_schedule_id, enrollment_id) check_the_enrollments_has_just_started(enrollment.examination_schedule) - st = Student.query.join(Group).join(ProjectSupervisor).filter(Student.index == student.index).first() if st is None or st.group.project_supervisor is None: abort(400, "You don't have a group or your group doesn't have an assigned project supervisor!")