diff --git a/repositories/status.py b/repositories/status.py index 25f4ec2..cecb220 100644 --- a/repositories/status.py +++ b/repositories/status.py @@ -1,10 +1,11 @@ +from datetime import datetime from typing import Optional -from sqlalchemy import select +from sqlalchemy import select, func -from models import Status +from models import Status, Deal from repositories.base import BaseRepository -from schemas.status import UpdateStatusSchema +from schemas.status import UpdateStatusSchema, CreateStatusSchema class StatusRepository(BaseRepository): @@ -22,6 +23,20 @@ class StatusRepository(BaseRepository): result = await self.session.execute(stmt) return result.scalar_one_or_none() + async def get_deals_count(self, status_id: int) -> int: + stmt = select(func.count(Deal.id)).where(Deal.status_id == status_id) + result = await self.session.execute(stmt) + return result.scalar() + + async def create(self, data: CreateStatusSchema) -> Status: + status_data = data.model_dump() + status_data["created_at"] = datetime.now() + status = Status(**status_data) + self.session.add(status) + await self.session.commit() + await self.session.refresh(status) + return status + async def update(self, status: Status, data: UpdateStatusSchema) -> Status: status.lexorank = data.lexorank if data.lexorank else status.lexorank status.name = data.name if data.name else status.name @@ -30,3 +45,13 @@ class StatusRepository(BaseRepository): await self.session.commit() await self.session.refresh(status) return status + + async def delete(self, status: Status, is_soft: bool): + if not is_soft: + await self.session.delete(status) + await self.session.commit() + return + + status.is_deleted = True + self.session.add(status) + await self.session.commit() diff --git a/routers/status.py b/routers/status.py index 910e13d..7ce49d8 100644 --- a/routers/status.py +++ b/routers/status.py @@ -5,6 +5,9 @@ from schemas.status import ( UpdateStatusRequest, UpdateStatusResponse, GetStatusesResponse, + CreateStatusResponse, + CreateStatusRequest, + DeleteStatusResponse, ) from services import StatusService @@ -25,6 +28,18 @@ async def get_statuses( return await StatusService(session).get_statuses(board_id) +@status_router.post( + "/", + response_model=CreateStatusResponse, + operation_id="create_status", +) +async def create_status( + session: SessionDependency, + request: CreateStatusRequest, +): + return await StatusService(session).create_status(request) + + @status_router.patch( "/{statusId}", response_model=UpdateStatusResponse, @@ -36,3 +51,15 @@ async def update_status( status_id: int = Path(alias="statusId"), ): return await StatusService(session).update_status(status_id, request) + + +@status_router.delete( + "/{statusId}", + response_model=DeleteStatusResponse, + operation_id="delete_status", +) +async def delete_status( + session: SessionDependency, + status_id: int = Path(alias="statusId"), +): + return await StatusService(session).delete_status(status_id) diff --git a/schemas/status.py b/schemas/status.py index ee80a01..ba0e906 100644 --- a/schemas/status.py +++ b/schemas/status.py @@ -6,12 +6,15 @@ from schemas.base import BaseSchema, BaseResponse # region Entities -class BaseStatusSchema(BaseSchema): - name: str - - -class StatusSchema(BaseStatusSchema): +class StatusSchema(BaseSchema): id: int + name: str + lexorank: str + + +class CreateStatusSchema(BaseSchema): + name: str + board_id: int lexorank: str @@ -25,6 +28,10 @@ class UpdateStatusSchema(BaseSchema): # region Requests +class CreateStatusRequest(BaseSchema): + status: CreateStatusSchema + + class UpdateStatusRequest(BaseSchema): status: UpdateStatusSchema @@ -38,8 +45,16 @@ class GetStatusesResponse(BaseSchema): statuses: list[StatusSchema] +class CreateStatusResponse(BaseResponse): + status: StatusSchema + + class UpdateStatusResponse(BaseResponse): pass +class DeleteStatusResponse(BaseResponse): + pass + + # endregion diff --git a/services/status.py b/services/status.py index 7a02df2..81ffe90 100644 --- a/services/status.py +++ b/services/status.py @@ -3,7 +3,14 @@ from sqlalchemy.ext.asyncio import AsyncSession from repositories import StatusRepository from schemas.board import UpdateBoardResponse -from schemas.status import UpdateStatusRequest, GetStatusesResponse, StatusSchema +from schemas.status import ( + UpdateStatusRequest, + GetStatusesResponse, + StatusSchema, + CreateStatusRequest, + CreateStatusResponse, + DeleteStatusResponse, +) class StatusService: @@ -16,6 +23,13 @@ class StatusService: statuses=[StatusSchema.model_validate(status) for status in statuses] ) + async def create_status(self, request: CreateStatusRequest) -> CreateStatusResponse: + status = await self.repository.create(request.status) + return CreateStatusResponse( + board=StatusSchema.model_validate(status), + message="Статус успешно создан", + ) + async def update_status(self, status_id: int, request: UpdateStatusRequest): status = await self.repository.get_by_id(status_id) if not status: @@ -23,3 +37,13 @@ class StatusService: await self.repository.update(status, request.status) return UpdateBoardResponse(message="Статус успешно обновлен") + + async def delete_status(self, status_id: int) -> DeleteStatusResponse: + board = await self.repository.get_by_id(status_id) + if not board: + raise HTTPException(status_code=404, detail="Статус не найден") + + deals_count = await self.repository.get_deals_count(status_id) + is_soft_needed: bool = deals_count > 0 + await self.repository.delete(board, is_soft_needed) + return DeleteStatusResponse(message="Статус успешно удален")