refactor: entity not found exceptions handler

This commit is contained in:
2025-09-16 16:56:10 +04:00
parent 276626d6f7
commit 98d3026e0d
24 changed files with 56 additions and 49 deletions

View File

@ -12,6 +12,7 @@ from modules.fulfillment_base.schemas.deal_product import (
)
from repositories.base import BaseRepository
from repositories.mixins import RepGetAllMixin, RepUpdateMixin
from utils.exceptions import ObjectNotFoundException
class DealProductRepository(
@ -34,7 +35,9 @@ class DealProductRepository(
.order_by(DealProduct.product_id)
)
async def get_by_id(self, deal_id: int, product_id: int) -> Optional[DealProduct]:
async def get_by_id(
self, deal_id: int, product_id: int, raise_if_not_found: Optional[bool] = True
) -> Optional[DealProduct]:
stmt = (
select(DealProduct)
.options(
@ -45,8 +48,10 @@ class DealProductRepository(
)
.where(DealProduct.deal_id == deal_id, DealProduct.product_id == product_id)
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
result = (await self.session.execute(stmt)).scalar_one_or_none()
if result is None and raise_if_not_found:
raise ObjectNotFoundException("Связь сделки с товаром не найдена")
return result
async def create(self, data: CreateDealProductSchema):
deal_product = DealProduct(**data.model_dump())

View File

@ -10,6 +10,7 @@ from modules.fulfillment_base.schemas.deal_service import (
)
from repositories.base import BaseRepository
from repositories.mixins import RepGetAllMixin, RepUpdateMixin
from utils.exceptions import ObjectNotFoundException
class DealServiceRepository(
@ -29,14 +30,18 @@ class DealServiceRepository(
.order_by(DealService.service_id)
)
async def get_by_id(self, deal_id: int, service_id: int) -> Optional[DealService]:
async def get_by_id(
self, deal_id: int, service_id: int, raise_if_not_found: Optional[bool] = True
) -> Optional[DealService]:
stmt = (
select(DealService)
.options(joinedload(DealService.service))
.where(DealService.deal_id == deal_id, DealService.service_id == service_id)
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
result = (await self.session.execute(stmt)).scalar_one_or_none()
if result is None and raise_if_not_found:
raise ObjectNotFoundException("Связь сделки с услугой не найдена")
return result
async def create(self, data: CreateDealServiceSchema):
deal_service = DealService(**data.model_dump())

View File

@ -16,6 +16,7 @@ class ProductRepository(
RepGetByIdMixin[Product],
):
entity_class = Product
entity_not_found_msg = "Товар не найден"
def _process_get_all_stmt_with_args(self, stmt: Select, *args) -> Select:
search_input = args[0]

View File

@ -8,6 +8,7 @@ from modules.fulfillment_base.models import DealProductService
from modules.fulfillment_base.schemas.product_service import *
from repositories.base import BaseRepository
from repositories.mixins import RepUpdateMixin
from utils.exceptions import ObjectNotFoundException
class ProductServiceRepository(
@ -15,10 +16,15 @@ class ProductServiceRepository(
RepUpdateMixin[DealProductService, UpdateProductServiceSchema],
):
entity_class = DealProductService
entity_not_found_msg = "Связь услуги с товаром не найдена"
session: AsyncSession
async def get_by_id(
self, deal_id: int, product_id: int, service_id: int
self,
deal_id: int,
product_id: int,
service_id: int,
raise_if_not_found: Optional[bool] = True,
) -> Optional[DealProductService]:
stmt = (
select(DealProductService)
@ -31,8 +37,10 @@ class ProductServiceRepository(
DealProductService.service_id == service_id,
)
)
result = await self.session.execute(stmt)
return result.scalar_one_or_none()
result = (await self.session.execute(stmt)).scalar_one_or_none()
if result is None and raise_if_not_found:
raise ObjectNotFoundException("Связь услуги с товаром не найдена")
return result
async def create(self, data: CreateProductServiceSchema):
deal_product_service = DealProductService(**data.model_dump())

View File

@ -15,6 +15,7 @@ class ServiceRepository(
RepGetByIdMixin[Service],
):
entity_class = Service
entity_not_found_msg = "Услуга не найдена"
async def update(self, service: Service, data: UpdateServiceSchema) -> Service:
return await self._apply_update_data_to_model(service, data, True)

View File

@ -12,6 +12,7 @@ class ServicesKitRepository(
RepCrudMixin[ServicesKit, CreateServicesKitSchema, UpdateServicesKitSchema],
):
entity_class = ServicesKit
entity_not_found_msg = "Набор услуг не найден"
def _process_get_by_id_stmt(self, stmt: Select) -> Select:
return stmt.options(selectinload(ServicesKit.services))

View File

@ -53,14 +53,8 @@ class DealProductService(ServiceGetAllMixin[DealProduct, DealProductSchema]):
) -> DealProductAddKitResponse:
services_kit_repo = ServicesKitRepository(self.repository.session)
services_kit = await services_kit_repo.get_by_id(request.kit_id)
if not services_kit:
raise HTTPException(status_code=404, detail="Набор услуг не найден")
deal_product = await self.repository.get_by_id(
request.deal_id, request.product_id
)
if not deal_product:
raise HTTPException(status_code=404, detail=self.entity_not_found_msg)
deal_product = await self.repository.get_by_id(request.deal_id, request.product_id)
product_service_repo = ProductServiceRepository(self.repository.session)
await product_service_repo.delete_product_services(

View File

@ -1,4 +1,3 @@
from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from modules.fulfillment_base.models import DealService
@ -9,7 +8,6 @@ from services.mixins import ServiceGetAllMixin
class DealServiceService(ServiceGetAllMixin[DealService, DealServiceSchema]):
schema_class = DealServiceSchema
entity_not_found_msg = "Связь услуги со сделкой не найдена"
def __init__(self, session: AsyncSession):
self.repository = DealServiceRepository(session)
@ -30,16 +28,10 @@ class DealServiceService(ServiceGetAllMixin[DealService, DealServiceSchema]):
self, deal_id: int, service_id: int, data: UpdateDealServiceRequest
) -> UpdateDealServiceResponse:
entity = await self.repository.get_by_id(deal_id, service_id)
if not entity:
raise HTTPException(status_code=404, detail=self.entity_not_found_msg)
await self.repository.update(entity, data.entity)
return UpdateDealServiceResponse(message="Услуга сделки обновлена")
async def delete(self, deal_id: int, service_id: int) -> DeleteDealServiceResponse:
entity = await self.repository.get_by_id(deal_id, service_id)
if not entity:
raise HTTPException(status_code=404, detail=self.entity_not_found_msg)
await self.repository.delete(entity)
return DeleteDealServiceResponse(message="Услуга удалена из сделки")

View File

@ -15,7 +15,6 @@ class ProductService(
ServiceDeleteMixin[Product],
):
schema_class = ProductSchema
entity_not_found_msg = "Товар не найден"
entity_deleted_msg = "Товар успешно удален"
entity_updated_msg = "Товар успешно обновлен"
entity_created_msg = "Товар успешно создан"

View File

@ -8,7 +8,6 @@ from modules.fulfillment_base.schemas.product_service import *
class ProductServiceService:
schema_class = ProductServiceSchema
entity_not_found_msg = "Связь услуги с товаром не найдена"
def __init__(self, session: AsyncSession):
self.repository = ProductServiceRepository(session)

View File

@ -15,7 +15,6 @@ class ServiceModelService(
ServiceDeleteMixin[Service],
):
schema_class = ServiceSchema
entity_not_found_msg = "Услуга не найдена"
entity_deleted_msg = "Услуга успешно удалена"
entity_updated_msg = "Услуга успешно обновлена"
entity_created_msg = "Услуга успешно создана"

View File

@ -12,7 +12,6 @@ class ServicesKitService(
ServiceCrudMixin[ServicesKit, ServicesKitSchema, CreateServicesKitRequest, UpdateServicesKitRequest]
):
schema_class = ServicesKitSchema
entity_not_found_msg = "Набор услуг не найден"
entity_deleted_msg = "Набор услуг успешно удален"
entity_updated_msg = "Набор услуг успешно обновлен"
entity_created_msg = "Набор услуг успешно создан"