Files
Fulfillment-Backend/services/board.py
2025-02-07 20:08:14 +04:00

120 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import datetime
from typing import Optional
from sqlalchemy import select, and_, func
from models import Board, Deal
from schemas.board import *
from services.base import BaseService
class BoardService(BaseService):
async def _get_boards_for_project(self, project_id: int) -> list[Board]:
stmt = (
select(Board)
.where(
and_(
Board.is_deleted == False,
Board.project_id == project_id,
)
)
.order_by(Board.ordinal_number)
)
boards = (await self.session.scalars(stmt)).all()
return list(boards)
async def get_boards(self, project_id: int) -> GetBoardsResponse:
boards = await self._get_boards_for_project(project_id)
return GetBoardsResponse(boards=boards)
async def create_board(self, request: CreateBoardRequest) -> CreateBoardResponse:
boards = await self._get_boards_for_project(request.board.project_id)
if len(boards) == 0:
ordinal_number = 1
else:
ordinal_number = boards[-1].ordinal_number + 1
board = Board(
**request.board.model_dump(),
created_at=datetime.now(),
ordinal_number=ordinal_number,
)
self.session.add(board)
await self.session.commit()
return CreateBoardResponse(ok=True, message="Доска успешно создана")
async def _get_board_by_id(self, board_id: int) -> Optional[Board]:
return await self.session.get(Board, board_id)
async def update_board(self, request: UpdateBoardRequest) -> UpdateBoardResponse:
board = await self._get_board_by_id(request.board.id)
if not board:
return UpdateBoardResponse(ok=False, message=f"Доска с ID {request.board.id} не найдена")
board.name = request.board.name
await self.session.commit()
return UpdateBoardResponse(ok=True, message="Доска успешно обновлена")
async def update_board_order(self, request: UpdateBoardOrderRequest) -> UpdateBoardOrderResponse:
boards = await self._get_boards_for_project(request.project_id)
board_idx = 0
while board_idx < len(boards) and boards[board_idx].id != request.board_id:
board_idx += 1
if board_idx == len(boards):
return UpdateBoardOrderResponse(ok=False, message=f"Доска с ID {request.board_id} не найдена в проекте")
board = boards.pop(board_idx)
boards.insert(request.new_ordinal_number - 1, board)
new_ordinal_number = 1
for board in boards:
board.ordinal_number = new_ordinal_number
new_ordinal_number += 1
await self.session.commit()
return UpdateBoardOrderResponse(ok=True, message="Порядок досок изменен")
async def _count_deals_in_progress(self, board_id: int) -> int:
stmt = (
select(func.count(Deal.id))
.where(
and_(
Deal.board_id == board_id,
Deal.is_deleted == False,
Deal.is_completed == False,
)
)
)
return (await self.session.scalars(stmt)).first()
async def _count_deals(self, board_id: int) -> int:
stmt = (
select(func.count(Deal.id))
.where(Deal.board_id == board_id)
)
return (await self.session.scalars(stmt)).first()
async def delete_board(self, board_id: int) -> DeleteBoardResponse:
board = await self._get_board_by_id(board_id)
if not board:
return DeleteBoardResponse(ok=False, message=f"Доска с ID {board_id} не найдена")
count_deals_in_progress = await self._count_deals_in_progress(board_id)
if count_deals_in_progress != 0:
return DeleteBoardResponse(
ok=False,
message=f"Нельзя удалить доску с активными сделками",
)
count_deals = await self._count_deals(board_id)
if count_deals == 0:
await self.session.delete(board)
else:
board.is_deleted = True
for status in board.deal_statuses:
status.is_deleted = True
await self.session.commit()
return DeleteBoardResponse(ok=True, message="Доска успешно удалена")