122 lines
4.6 KiB
Python
122 lines
4.6 KiB
Python
from datetime import datetime
|
||
|
||
from sqlalchemy import select, update, func, delete
|
||
from sqlalchemy.orm import selectinload
|
||
|
||
from card_attributes import CardAttributesCommandHandler
|
||
from models import Project, Board, Module
|
||
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),
|
||
)
|
||
.where(Project.is_deleted == False)
|
||
.order_by(Project.id)
|
||
)
|
||
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,
|
||
tags=project.tags,
|
||
)
|
||
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="Проект успешно удален")
|
||
|
||
async def get_all_modules(self) -> GetAllModulesResponse:
|
||
stmt = (
|
||
select(Module)
|
||
.where(Module.is_deleted == False)
|
||
)
|
||
modules = await self.session.scalars(stmt)
|
||
return GetAllModulesResponse(modules=modules.all())
|
||
|
||
async def update_project_modules(self, request: UpdateModulesRequest) -> UpdateModulesResponse:
|
||
project: Optional[Project] = await self.session.get(Project, request.project_id)
|
||
if not project:
|
||
return UpdateModulesResponse(ok=False, message=f"Проект с ID {request.project_id} не найден")
|
||
|
||
modules_stmt = (
|
||
select(Module)
|
||
.where(Module.id.in_(request.module_ids))
|
||
)
|
||
modules = (await self.session.scalars(modules_stmt)).all()
|
||
|
||
project.modules = modules
|
||
await self.session.commit()
|
||
|
||
return UpdateModulesResponse(ok=True, message="Модули успешно обновлены")
|
||
|
||
async def update_project_attributes(self, request: UpdateAttributesRequest) -> UpdateAttributesResponse:
|
||
project: Optional[Project] = await self.session.get(Project, request.project_id)
|
||
if not project:
|
||
return UpdateAttributesResponse(ok=False, message=f"Проект с ID {request.project_id} не найден")
|
||
|
||
card_attrs_handler = CardAttributesCommandHandler(self.session)
|
||
await card_attrs_handler.set_project_attributes(project, request.attribute_ids)
|
||
|
||
return UpdateAttributesResponse(ok=True, message="Атрибуты успешно обновлены")
|