diff --git a/models/service.py b/models/service.py index 2c20c0e..a989a86 100644 --- a/models/service.py +++ b/models/service.py @@ -20,6 +20,11 @@ class Service(BaseModel): category_id = Column(Integer, ForeignKey('service_categories.id'), nullable=False, comment='ID категории услуги') category = relationship('ServiceCategory', lazy='joined') + is_deleted: Mapped[bool] = mapped_column( + nullable=False, + server_default='0', + comment='Удалена ли услуга' + ) price = Column( Double, diff --git a/routers/service.py b/routers/service.py index de03c92..482ea36 100644 --- a/routers/service.py +++ b/routers/service.py @@ -26,9 +26,10 @@ service_router = APIRouter( ) async def get_all( - session: Annotated[AsyncSession, Depends(get_session)] + session: Annotated[AsyncSession, Depends(get_session)], + with_placeholders: bool = False ): - return await ServiceService(session).get_all() + return await ServiceService(session).get_all(with_placeholders) @service_router.post( diff --git a/schemas/service.py b/schemas/service.py index dbc6c8c..c7ad041 100644 --- a/schemas/service.py +++ b/schemas/service.py @@ -40,6 +40,7 @@ class ServiceSchema(BaseSchema): category_prices: List[ServiceCategoryPriceSchema] cost: Optional[int] rank: str + is_placeholder: bool = False # endregion diff --git a/services/service.py b/services/service.py index f825305..87632a6 100644 --- a/services/service.py +++ b/services/service.py @@ -1,6 +1,7 @@ import lexorank from lexorank import Bucket, middle from sqlalchemy import select, update, insert, delete, desc +from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import joinedload from enums.service import ServiceType @@ -12,17 +13,47 @@ from utils.list_utils import previous_current_next class ServiceService(BaseService): - async def get_all(self) -> ServiceGetAllResponse: + async def get_all(self, with_placeholders: bool) -> ServiceGetAllResponse: query = await ( self.session - .scalars(select(Service) - .options(joinedload(Service.category)) - .order_by(Service.rank) + .scalars( + select(Service) + .options(joinedload(Service.category)) + .order_by(Service.rank) + .filter(Service.is_deleted == False) + ) + ) + services_raw = query.all() + services = [] + + for service in services_raw: + services.append(ServiceSchema.model_validate(service)) + + if not with_placeholders: + return ServiceGetAllResponse(services=services) + + category_ids = list(set([service.category_id for service in services_raw])) + rest_categories = await ( + self.session + .scalars(select(ServiceCategory) + .where(ServiceCategory.id.notin_(category_ids)) ) ) - services = [] - for service in query.all(): - services.append(ServiceSchema.model_validate(service)) + for category in rest_categories: + for service_type in [ServiceType.DEAL_SERVICE, ServiceType.PRODUCT_SERVICE]: + services.append(ServiceSchema( + id=0, + name='Пусто', + category=ServiceCategorySchema.model_validate(category), + price=0, + service_type=service_type, + price_ranges=[], + category_prices=[], + cost=0, + rank='', + is_placeholder=True + )) + return ServiceGetAllResponse(services=services) async def get_latest_rank_in_category(self, category_id: int, service_type: ServiceType) -> str: @@ -152,6 +183,14 @@ class ServiceService(BaseService): await self.session.delete(service) await self.session.commit() return ServiceDeleteResponse(ok=True, message="Услуга успешно удалена") + except IntegrityError: + await self.session.rollback() + service = await (self.session + .scalar(select(Service) + .filter(Service.id == request.service_id))) + service.is_deleted = True + await self.session.commit() + return ServiceDeleteResponse(ok=True, message="Услуга успешно удалена") except Exception as e: return ServiceDeleteResponse(ok=False, message=f"Неудалось удалить услугу, ошибка: {e}")