feat: create and delete status endpoints
This commit is contained in:
@ -1,10 +1,11 @@
|
|||||||
|
from datetime import datetime
|
||||||
from typing import Optional
|
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 repositories.base import BaseRepository
|
||||||
from schemas.status import UpdateStatusSchema
|
from schemas.status import UpdateStatusSchema, CreateStatusSchema
|
||||||
|
|
||||||
|
|
||||||
class StatusRepository(BaseRepository):
|
class StatusRepository(BaseRepository):
|
||||||
@ -22,6 +23,20 @@ class StatusRepository(BaseRepository):
|
|||||||
result = await self.session.execute(stmt)
|
result = await self.session.execute(stmt)
|
||||||
return result.scalar_one_or_none()
|
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:
|
async def update(self, status: Status, data: UpdateStatusSchema) -> Status:
|
||||||
status.lexorank = data.lexorank if data.lexorank else status.lexorank
|
status.lexorank = data.lexorank if data.lexorank else status.lexorank
|
||||||
status.name = data.name if data.name else status.name
|
status.name = data.name if data.name else status.name
|
||||||
@ -30,3 +45,13 @@ class StatusRepository(BaseRepository):
|
|||||||
await self.session.commit()
|
await self.session.commit()
|
||||||
await self.session.refresh(status)
|
await self.session.refresh(status)
|
||||||
return 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()
|
||||||
|
|||||||
@ -5,6 +5,9 @@ from schemas.status import (
|
|||||||
UpdateStatusRequest,
|
UpdateStatusRequest,
|
||||||
UpdateStatusResponse,
|
UpdateStatusResponse,
|
||||||
GetStatusesResponse,
|
GetStatusesResponse,
|
||||||
|
CreateStatusResponse,
|
||||||
|
CreateStatusRequest,
|
||||||
|
DeleteStatusResponse,
|
||||||
)
|
)
|
||||||
from services import StatusService
|
from services import StatusService
|
||||||
|
|
||||||
@ -25,6 +28,18 @@ async def get_statuses(
|
|||||||
return await StatusService(session).get_statuses(board_id)
|
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(
|
@status_router.patch(
|
||||||
"/{statusId}",
|
"/{statusId}",
|
||||||
response_model=UpdateStatusResponse,
|
response_model=UpdateStatusResponse,
|
||||||
@ -36,3 +51,15 @@ async def update_status(
|
|||||||
status_id: int = Path(alias="statusId"),
|
status_id: int = Path(alias="statusId"),
|
||||||
):
|
):
|
||||||
return await StatusService(session).update_status(status_id, request)
|
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)
|
||||||
|
|||||||
@ -6,12 +6,15 @@ from schemas.base import BaseSchema, BaseResponse
|
|||||||
# region Entities
|
# region Entities
|
||||||
|
|
||||||
|
|
||||||
class BaseStatusSchema(BaseSchema):
|
class StatusSchema(BaseSchema):
|
||||||
name: str
|
|
||||||
|
|
||||||
|
|
||||||
class StatusSchema(BaseStatusSchema):
|
|
||||||
id: int
|
id: int
|
||||||
|
name: str
|
||||||
|
lexorank: str
|
||||||
|
|
||||||
|
|
||||||
|
class CreateStatusSchema(BaseSchema):
|
||||||
|
name: str
|
||||||
|
board_id: int
|
||||||
lexorank: str
|
lexorank: str
|
||||||
|
|
||||||
|
|
||||||
@ -25,6 +28,10 @@ class UpdateStatusSchema(BaseSchema):
|
|||||||
# region Requests
|
# region Requests
|
||||||
|
|
||||||
|
|
||||||
|
class CreateStatusRequest(BaseSchema):
|
||||||
|
status: CreateStatusSchema
|
||||||
|
|
||||||
|
|
||||||
class UpdateStatusRequest(BaseSchema):
|
class UpdateStatusRequest(BaseSchema):
|
||||||
status: UpdateStatusSchema
|
status: UpdateStatusSchema
|
||||||
|
|
||||||
@ -38,8 +45,16 @@ class GetStatusesResponse(BaseSchema):
|
|||||||
statuses: list[StatusSchema]
|
statuses: list[StatusSchema]
|
||||||
|
|
||||||
|
|
||||||
|
class CreateStatusResponse(BaseResponse):
|
||||||
|
status: StatusSchema
|
||||||
|
|
||||||
|
|
||||||
class UpdateStatusResponse(BaseResponse):
|
class UpdateStatusResponse(BaseResponse):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteStatusResponse(BaseResponse):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|||||||
@ -3,7 +3,14 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||||||
|
|
||||||
from repositories import StatusRepository
|
from repositories import StatusRepository
|
||||||
from schemas.board import UpdateBoardResponse
|
from schemas.board import UpdateBoardResponse
|
||||||
from schemas.status import UpdateStatusRequest, GetStatusesResponse, StatusSchema
|
from schemas.status import (
|
||||||
|
UpdateStatusRequest,
|
||||||
|
GetStatusesResponse,
|
||||||
|
StatusSchema,
|
||||||
|
CreateStatusRequest,
|
||||||
|
CreateStatusResponse,
|
||||||
|
DeleteStatusResponse,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class StatusService:
|
class StatusService:
|
||||||
@ -16,6 +23,13 @@ class StatusService:
|
|||||||
statuses=[StatusSchema.model_validate(status) for status in statuses]
|
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):
|
async def update_status(self, status_id: int, request: UpdateStatusRequest):
|
||||||
status = await self.repository.get_by_id(status_id)
|
status = await self.repository.get_by_id(status_id)
|
||||||
if not status:
|
if not status:
|
||||||
@ -23,3 +37,13 @@ class StatusService:
|
|||||||
|
|
||||||
await self.repository.update(status, request.status)
|
await self.repository.update(status, request.status)
|
||||||
return UpdateBoardResponse(message="Статус успешно обновлен")
|
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="Статус успешно удален")
|
||||||
|
|||||||
Reference in New Issue
Block a user