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="Атрибуты успешно обновлены")
 |