from apiflask import APIBlueprint from flask import abort from ...base.schemas import MessageSchema from ...base.utils import paginate_models from ...dependencies import db from ...project_supervisor.models import ProjectSupervisor from ...students.models import Group, ProjectGradeSheet, Student, YearGroup from ..schemas.groups import ( GroupCreateSchema, GroupEditSchema, GroupQuerySchema, GroupSetGradeSchema, GroupsPaginationSchema, ) from ..schemas.students import DetailGroupSchema from ..utils import attach_grade_to_group_models bp = APIBlueprint("groups", __name__, url_prefix="/groups") @bp.get("//") @bp.input(GroupQuerySchema, location="query") @bp.output(GroupsPaginationSchema) def list_groups(year_group_id: int, query: dict) -> dict: search_name = query.get("name") page = query.get("page") per_page = query.get("per_page") groups_query = Group.search_by_name(year_group_id, search_name) data = paginate_models(page, groups_query, per_page) items = data["items"] attach_grade_to_group_models(items) return {"groups": items, "max_pages": data["max_pages"]} @bp.post("//") @bp.input(GroupCreateSchema) @bp.output(MessageSchema, status_code=201) def create_group(year_group_id: int, data: dict) -> dict: name = data["name"] students_ids = data["students"] project_supervisor_id = data["project_supervisor_id"] yg = YearGroup.query.filter(YearGroup.id == year_group_id).first() if yg is None: abort(404, "Not found year group!") project_supervisor = ProjectSupervisor.query.filter_by( id=project_supervisor_id ).first() if project_supervisor is None: abort(404, "Not found project supervisor!") group = Group( name=name, project_supervisor_id=project_supervisor_id, year_group_id=year_group_id, ) students_without_groups = ( db.session.query(Student, Group) .join(Group, Student.groups) .filter(Group.year_group_id == year_group_id) .filter(db.or_(*[Student.id == st_id for st_id in students_ids])) .all() ) if len(students_without_groups) > 0: abort(400, "One or more students have already belonged to group!") students = db.session.query(Student).filter(Student.id.in_(students_ids)).all() if len(students) != len(students_ids): abort(404, "Not found students!") db.session.add(group) db.session.commit() for student in students: group.students.append(student) pgs = ProjectGradeSheet(group_id=group.id) db.session.add(pgs) db.session.commit() return {"message": "Group was created!"} @bp.get("//detail/") @bp.output(DetailGroupSchema) def detail_group(group_id: int) -> Group: group = Group.query.filter_by(id=group_id).first() if group is None: abort(404, "Not found group!") attach_grade_to_group_models([group]) return group @bp.delete("//") @bp.output(MessageSchema, status_code=202) def delete_group(group_id: int) -> dict: group = Group.query.filter_by(id=group_id).first() if group is None: abort(404, "Not found group!") group.students = [] db.session.delete(group) db.session.commit() return {"message": "Group was deleted!"} @bp.put("//") @bp.input(GroupEditSchema) @bp.output(MessageSchema) def edit_group(group_id: int, data: dict) -> dict: if not data: abort(400, "You have passed empty data!") group_query = Group.query.filter_by(id=group_id) group = group_query.first() if group is None: abort(404, "Not found group!") students_ids = data.get("students") name = data.get("name") project_supervisor_id = data.get("project_supervisor_id") if students_ids is not None: students = db.session.query(Student).filter(Student.id.in_(students_ids)).all() if len(students_ids) != len(students): abort(404, "Not found students!") group.students = students if name is not None: group.name = name if project_supervisor_id is not None: ps = ProjectSupervisor.query.filter( ProjectSupervisor.id == project_supervisor_id ).first() if ps is None: abort(404, "Not found project supervisor!") group.project_supervisor_id = project_supervisor_id db.session.commit() return {"message": "Group was updated!"} @bp.put("//set-grades/") @bp.input(GroupSetGradeSchema) @bp.output(MessageSchema) def set_grade_for_group(group_id: int, data: dict) -> dict: if not data: abort(400, "You have passed empty data!") group_query = Group.query.filter_by(id=group_id) group = group_query.first() if group is None: abort(404, "Not found group!") group_query.update(data) db.session.commit() return {"message": "Grade was updated!"}