From fbadddeadaf29357a7120058e2daaef1797bcf7a Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Sat, 27 Sep 2025 18:21:20 +0400 Subject: [PATCH] feat: service categories endpoints and service creation endpoint --- modules/fulfillment_base/models/__init__.py | 2 +- modules/fulfillment_base/models/service.py | 6 +- .../fulfillment_base/repositories/__init__.py | 1 + .../fulfillment_base/repositories/service.py | 24 +++++++- .../repositories/service_category.py | 23 ++++++++ .../routers/service_category.py | 55 +++++++++++++++++++ modules/fulfillment_base/schemas/service.py | 19 ++----- .../schemas/service_category.py | 55 +++++++++++++++++++ modules/fulfillment_base/services/__init__.py | 1 + .../services/service_category.py | 28 ++++++++++ 10 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 modules/fulfillment_base/repositories/service_category.py create mode 100644 modules/fulfillment_base/routers/service_category.py create mode 100644 modules/fulfillment_base/schemas/service_category.py create mode 100644 modules/fulfillment_base/services/service_category.py diff --git a/modules/fulfillment_base/models/__init__.py b/modules/fulfillment_base/models/__init__.py index 5aa7c97..bb29616 100644 --- a/modules/fulfillment_base/models/__init__.py +++ b/modules/fulfillment_base/models/__init__.py @@ -3,4 +3,4 @@ from .deal_service import ( DealService as DealService, ) from .product import Product as Product -from .service import Service as Service +from .service import Service as Service, ServiceCategory as ServiceCategory diff --git a/modules/fulfillment_base/models/service.py b/modules/fulfillment_base/models/service.py index 7f27b93..604fec3 100644 --- a/modules/fulfillment_base/models/service.py +++ b/modules/fulfillment_base/models/service.py @@ -38,14 +38,10 @@ class Service(BaseModel, IdMixin, SoftDeleteMixin, PriceMixin, CostMixin): lexorank: Mapped[str] = mapped_column(comment="Ранг услуги") -class ServiceCategory(BaseModel, IdMixin): +class ServiceCategory(BaseModel, IdMixin, SoftDeleteMixin): __tablename__ = "fulfillment_base_service_categories" name: Mapped[str] = mapped_column() - is_deleted: Mapped[bool] = mapped_column( - default=False, comment="Удалена ли категория" - ) - deal_service_rank: Mapped[str] = mapped_column(comment="Ранг услуги для сделки") product_service_rank: Mapped[str] = mapped_column(comment="Ранг услуги для товара") diff --git a/modules/fulfillment_base/repositories/__init__.py b/modules/fulfillment_base/repositories/__init__.py index a3beb73..ad1eb04 100644 --- a/modules/fulfillment_base/repositories/__init__.py +++ b/modules/fulfillment_base/repositories/__init__.py @@ -4,3 +4,4 @@ from .deal_service import DealServiceRepository as DealServiceRepository from .product import ProductRepository as ProductRepository from .service import ServiceRepository as ServiceRepository from .services_kit import ServicesKitRepository as ServicesKitRepository +from .service_category import ServiceCategoryRepository as ServiceCategoryRepository diff --git a/modules/fulfillment_base/repositories/service.py b/modules/fulfillment_base/repositories/service.py index b64dd95..6f38af3 100644 --- a/modules/fulfillment_base/repositories/service.py +++ b/modules/fulfillment_base/repositories/service.py @@ -1,4 +1,5 @@ from modules.fulfillment_base.models import Service +from modules.fulfillment_base.models.service import ServicePriceRange from modules.fulfillment_base.schemas.service import ( CreateServiceSchema, UpdateServiceSchema, @@ -10,13 +11,34 @@ class ServiceRepository( BaseRepository, RepGetAllMixin[Service], RepDeleteMixin[Service], - RepCreateMixin[Service, CreateServiceSchema], RepUpdateMixin[Service, UpdateServiceSchema], RepGetByIdMixin[Service], ): entity_class = Service entity_not_found_msg = "Услуга не найдена" + async def create(self, data: CreateServiceSchema) -> int: + price_ranges = [] + for range in data.price_ranges: + price_ranges.append( + ServicePriceRange( + from_quantity=range.from_quantity, + to_quantity=range.to_quantity, + price=range.price, + ) + ) + + data_dict = data.model_dump() + data_dict["price_ranges"] = price_ranges + data_dict["category_id"] = data.category.id + del data_dict["category"] + + service = Service(**data_dict) + self.session.add(service) + await self.session.commit() + await self.session.refresh(service) + return service.id + async def update(self, service: Service, data: UpdateServiceSchema) -> Service: return await self._apply_update_data_to_model(service, data, True) diff --git a/modules/fulfillment_base/repositories/service_category.py b/modules/fulfillment_base/repositories/service_category.py new file mode 100644 index 0000000..c8eccfa --- /dev/null +++ b/modules/fulfillment_base/repositories/service_category.py @@ -0,0 +1,23 @@ +from modules.fulfillment_base.models import ServiceCategory +from modules.fulfillment_base.schemas.service_category import ( + CreateServiceCategorySchema, + UpdateServiceCategorySchema, +) +from repositories.mixins import * + + +class ServiceCategoryRepository( + BaseRepository, + RepGetAllMixin[ServiceCategory], + RepDeleteMixin[ServiceCategory], + RepCreateMixin[ServiceCategory, CreateServiceCategorySchema], + RepUpdateMixin[ServiceCategory, UpdateServiceCategorySchema], + RepGetByIdMixin[ServiceCategory], +): + entity_class = ServiceCategory + entity_not_found_msg = "Категория услуги не найдена" + + async def update( + self, service: ServiceCategory, data: UpdateServiceCategorySchema + ) -> ServiceCategory: + return await self._apply_update_data_to_model(service, data, True) diff --git a/modules/fulfillment_base/routers/service_category.py b/modules/fulfillment_base/routers/service_category.py new file mode 100644 index 0000000..307fba9 --- /dev/null +++ b/modules/fulfillment_base/routers/service_category.py @@ -0,0 +1,55 @@ +from fastapi import APIRouter, Path + +from backend.dependecies import SessionDependency +from modules.fulfillment_base.schemas.service_category import * +from modules.fulfillment_base.services import ServiceCategoryService + +router = APIRouter(tags=["service-category"]) + + +@router.get( + "/", + response_model=GetServiceCategoriesResponse, + operation_id="get_service_categories", +) +async def get_services_categories( + session: SessionDependency, +): + return await ServiceCategoryService(session).get_all() + + +@router.post( + "/", + response_model=CreateServiceCategoryResponse, + operation_id="create_service_category", +) +async def create_service_category( + session: SessionDependency, + request: CreateServiceCategoryRequest, +): + return await ServiceCategoryService(session).create(request) + + +@router.patch( + "/{pk}", + response_model=UpdateServiceCategoryResponse, + operation_id="update_service_category", +) +async def update_service_category( + session: SessionDependency, + request: UpdateServiceCategoryRequest, + pk: int = Path(), +): + return await ServiceCategoryService(session).update(pk, request) + + +@router.delete( + "/{pk}", + response_model=DeleteServiceCategoryResponse, + operation_id="delete_service_category", +) +async def delete_service_category( + session: SessionDependency, + pk: int = Path(), +): + return await ServiceCategoryService(session).delete(pk) diff --git a/modules/fulfillment_base/schemas/service.py b/modules/fulfillment_base/schemas/service.py index ad64700..7c67094 100644 --- a/modules/fulfillment_base/schemas/service.py +++ b/modules/fulfillment_base/schemas/service.py @@ -1,5 +1,6 @@ from typing import Optional +from modules.fulfillment_base.schemas.service_category import ServiceCategorySchema from schemas.base import BaseSchema, BaseResponse @@ -13,15 +14,7 @@ class ServicePriceRangeSchema(BaseSchema): price: float -class ServiceCategorySchema(BaseSchema): - id: int - name: str - deal_service_rank: str - product_service_rank: str - - -class ServiceSchema(BaseSchema): - id: int +class CreateServiceSchema(BaseSchema): name: str category: ServiceCategorySchema price: float @@ -31,14 +24,14 @@ class ServiceSchema(BaseSchema): lexorank: str +class ServiceSchema(CreateServiceSchema): + id: int + + class UpdateServiceSchema(ServiceSchema): pass -class CreateServiceSchema(ServiceSchema): - pass - - # endregion # region Request diff --git a/modules/fulfillment_base/schemas/service_category.py b/modules/fulfillment_base/schemas/service_category.py new file mode 100644 index 0000000..0c4ad2a --- /dev/null +++ b/modules/fulfillment_base/schemas/service_category.py @@ -0,0 +1,55 @@ +from schemas.base import BaseSchema, BaseResponse + + +# region Entity + + +class CreateServiceCategorySchema(BaseSchema): + name: str + deal_service_rank: str + product_service_rank: str + + +class ServiceCategorySchema(CreateServiceCategorySchema): + id: int + + +class UpdateServiceCategorySchema(ServiceCategorySchema): + pass + + +# endregion + +# region Request + + +class CreateServiceCategoryRequest(BaseSchema): + entity: CreateServiceCategorySchema + + +class UpdateServiceCategoryRequest(BaseSchema): + entity: UpdateServiceCategorySchema + + +# endregion + +# region Response + + +class GetServiceCategoriesResponse(BaseSchema): + items: list[ServiceCategorySchema] + + +class CreateServiceCategoryResponse(BaseResponse): + entity: ServiceCategorySchema + + +class UpdateServiceCategoryResponse(BaseResponse): + pass + + +class DeleteServiceCategoryResponse(BaseResponse): + pass + + +# endregion diff --git a/modules/fulfillment_base/services/__init__.py b/modules/fulfillment_base/services/__init__.py index d9f56e1..dc0664c 100644 --- a/modules/fulfillment_base/services/__init__.py +++ b/modules/fulfillment_base/services/__init__.py @@ -4,3 +4,4 @@ from .product import ProductService as ProductService from .product_service import ProductServiceService as ProductServiceService from .service import ServiceModelService as ServiceModelService from .services_kit import ServicesKitService as ServicesKitService +from .service_category import ServiceCategoryService as ServiceCategoryService diff --git a/modules/fulfillment_base/services/service_category.py b/modules/fulfillment_base/services/service_category.py new file mode 100644 index 0000000..5c6b00e --- /dev/null +++ b/modules/fulfillment_base/services/service_category.py @@ -0,0 +1,28 @@ +from modules.fulfillment_base.models import ServiceCategory +from modules.fulfillment_base.repositories import ServiceCategoryRepository +from modules.fulfillment_base.schemas.service_category import ( + ServiceCategorySchema, + CreateServiceCategoryRequest, + UpdateServiceCategoryRequest, +) +from services.mixins import * + + +class ServiceCategoryService( + ServiceGetAllMixin[ServiceCategory, ServiceCategorySchema], + ServiceCreateMixin[ + ServiceCategory, CreateServiceCategoryRequest, ServiceCategorySchema + ], + ServiceUpdateMixin[ServiceCategory, UpdateServiceCategoryRequest], + ServiceDeleteMixin[ServiceCategory], +): + schema_class = ServiceCategorySchema + entity_deleted_msg = "Категория услуг успешно удалена" + entity_updated_msg = "Категория услуг успешно обновлена" + entity_created_msg = "Категория услуг успешно создана" + + def __init__(self, session: AsyncSession): + self.repository = ServiceCategoryRepository(session) + + async def is_soft_delete(self, service: ServiceCategorySchema) -> bool: + return True