feat: service deleting and rest categories placeholders
This commit is contained in:
		@@ -20,6 +20,11 @@ class Service(BaseModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    category_id = Column(Integer, ForeignKey('service_categories.id'), nullable=False, comment='ID категории услуги')
 | 
					    category_id = Column(Integer, ForeignKey('service_categories.id'), nullable=False, comment='ID категории услуги')
 | 
				
			||||||
    category = relationship('ServiceCategory', lazy='joined')
 | 
					    category = relationship('ServiceCategory', lazy='joined')
 | 
				
			||||||
 | 
					    is_deleted: Mapped[bool] = mapped_column(
 | 
				
			||||||
 | 
					        nullable=False,
 | 
				
			||||||
 | 
					        server_default='0',
 | 
				
			||||||
 | 
					        comment='Удалена ли услуга'
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    price = Column(
 | 
					    price = Column(
 | 
				
			||||||
        Double,
 | 
					        Double,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,9 +26,10 @@ service_router = APIRouter(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
async def get_all(
 | 
					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(
 | 
					@service_router.post(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@ class ServiceSchema(BaseSchema):
 | 
				
			|||||||
    category_prices: List[ServiceCategoryPriceSchema]
 | 
					    category_prices: List[ServiceCategoryPriceSchema]
 | 
				
			||||||
    cost: Optional[int]
 | 
					    cost: Optional[int]
 | 
				
			||||||
    rank: str
 | 
					    rank: str
 | 
				
			||||||
 | 
					    is_placeholder: bool = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# endregion
 | 
					# endregion
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
import lexorank
 | 
					import lexorank
 | 
				
			||||||
from lexorank import Bucket, middle
 | 
					from lexorank import Bucket, middle
 | 
				
			||||||
from sqlalchemy import select, update, insert, delete, desc
 | 
					from sqlalchemy import select, update, insert, delete, desc
 | 
				
			||||||
 | 
					from sqlalchemy.exc import IntegrityError
 | 
				
			||||||
from sqlalchemy.orm import joinedload
 | 
					from sqlalchemy.orm import joinedload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from enums.service import ServiceType
 | 
					from enums.service import ServiceType
 | 
				
			||||||
@@ -12,17 +13,47 @@ from utils.list_utils import previous_current_next
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ServiceService(BaseService):
 | 
					class ServiceService(BaseService):
 | 
				
			||||||
    async def get_all(self) -> ServiceGetAllResponse:
 | 
					    async def get_all(self, with_placeholders: bool) -> ServiceGetAllResponse:
 | 
				
			||||||
        query = await (
 | 
					        query = await (
 | 
				
			||||||
            self.session
 | 
					            self.session
 | 
				
			||||||
            .scalars(select(Service)
 | 
					            .scalars(
 | 
				
			||||||
                     .options(joinedload(Service.category))
 | 
					                select(Service)
 | 
				
			||||||
                     .order_by(Service.rank)
 | 
					                .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 category in rest_categories:
 | 
				
			||||||
        for service in query.all():
 | 
					            for service_type in [ServiceType.DEAL_SERVICE, ServiceType.PRODUCT_SERVICE]:
 | 
				
			||||||
            services.append(ServiceSchema.model_validate(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)
 | 
					        return ServiceGetAllResponse(services=services)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def get_latest_rank_in_category(self, category_id: int, service_type: ServiceType) -> str:
 | 
					    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.delete(service)
 | 
				
			||||||
            await self.session.commit()
 | 
					            await self.session.commit()
 | 
				
			||||||
            return ServiceDeleteResponse(ok=True, message="Услуга успешно удалена")
 | 
					            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:
 | 
					        except Exception as e:
 | 
				
			||||||
            return ServiceDeleteResponse(ok=False, message=f"Неудалось удалить услугу, ошибка: {e}")
 | 
					            return ServiceDeleteResponse(ok=False, message=f"Неудалось удалить услугу, ошибка: {e}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user