from datetime import datetime from sqlalchemy import select, update, func, delete from sqlalchemy.orm import selectinload from models import Project, Board from schemas.project import * from services.base import BaseService class ProjectService(BaseService): async def get_projects(self) -> GetProjectsResponse: board_count_sub = ( select( Board.project_id, func.count(Board.id).label('boards_count'), ) .group_by(Board.project_id) .subquery() ) stmt = ( select( Project, func.coalesce(board_count_sub.c.boards_count, 0), ) .outerjoin(board_count_sub, Project.id == board_count_sub.c.project_id) .options( selectinload(Project.attributes), selectinload(Project.modules), ) ) project_data = (await self.session.execute(stmt)).all() projects = [] for project, boards_count in project_data: project_schema = FullProjectSchema( id=project.id, name=project.name, boards_count=boards_count, attributes=project.attributes, modules=project.modules, ) projects.append(project_schema) return GetProjectsResponse(projects=projects) async def create_project(self, request: CreateProjectRequest) -> CreateProjectResponse: project = Project( name=request.project.name, created_at=datetime.now(), ) self.session.add(project) await self.session.commit() return UpdateProjectResponse(ok=True, message="Проект успешно создан") async def update_project(self, request: UpdateProjectRequest) -> UpdateProjectResponse: stmt = ( update(Project) .where(Project.id == request.project.id) .values(name=request.project.name) ) await self.session.execute(stmt) await self.session.commit() return UpdateProjectResponse(ok=True, message="Проект успешно изменен") async def delete_project(self, project_id: int) -> DeleteProjectResponse: stmt_boards = select(Board).where(Board.project_id == project_id) boards = (await self.session.scalars(stmt_boards)).all() if len(boards) == 0: stmt = ( delete(Project) .where(Project.id == project_id) ) else: stmt = ( update(Project) .where(Project.id == project_id) .values(is_deleted=True) ) await self.session.execute(stmt) await self.session.commit() return DeleteProjectResponse(ok=True, message="Проект успешно удален")