This commit is contained in:
2024-04-12 07:34:21 +03:00
parent 5c81af05d5
commit be623a3555
12 changed files with 513 additions and 93 deletions

View File

@@ -5,7 +5,7 @@ from fastapi import HTTPException
from sqlalchemy import select, func
from sqlalchemy.orm import joinedload, selectinload
from models import User, Service
from models import User, Service, Client
from models.deal import *
from schemas.client import ClientDetailsSchema
from schemas.deal import *
@@ -15,6 +15,7 @@ from services.client import ClientService
class DealService(BaseService):
# region Deal
async def _get_deal_by_id(self, deal_id) -> Union[Deal, None]:
return await self.session.get(Deal, deal_id)
@@ -116,6 +117,56 @@ class DealService(BaseService):
)
return DealSummaryResponse(summaries=summaries)
async def get_all(self) -> DealGetAllResponse:
deals_query = await self.session.scalars(select(Deal).options(joinedload(Deal.client)))
deals = deals_query.all()
result = []
for deal in deals:
result.append(DealSchema.model_validate(deal))
return DealGetAllResponse(deals=result)
async def get_by_id(self, deal_id: int) -> DealSchema:
deal = await self.session.scalar(
select(Deal)
.options(
joinedload(Deal.client).joinedload(Client.details),
selectinload(Deal.services)
.joinedload(models.secondary.DealService.service)
.joinedload(Service.category),
selectinload(Deal.products)
.joinedload(models.secondary.DealProduct.product)
.joinedload(models.Product.client),
selectinload(Deal.products)
.joinedload(models.secondary.DealProduct.product)
.joinedload(models.Product.barcodes),
selectinload(Deal.status_history)
.joinedload(DealStatusHistory.user),
selectinload(Deal.status_history)
.noload(DealStatusHistory.deal)
)
.where(Deal.id == deal_id)
)
if not deal:
raise HTTPException(status_code=404, detail="Сделка не найдена")
return DealSchema.model_validate(deal)
async def update_general_info(self, request: DealUpdateGeneralInfoRequest) -> DealUpdateGeneralInfoResponse:
try:
deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
if not deal:
raise HTTPException(status_code=404, detail="Сделка не найдена")
deal.name = request.data.name
deal.is_deleted = request.data.is_deleted
deal.is_completed = request.data.is_completed
await self.session.commit()
return DealUpdateGeneralInfoResponse(ok=True, message='Данные о сделке успешно обновлены')
except Exception as e:
await self.session.rollback()
return DealUpdateGeneralInfoResponse(ok=False, message=str(e))
# endregion
# region Deal services
async def add_services(self, request: DealAddServicesRequest):
# TODO refactor
deal: Deal = await self.session.scalar(
@@ -149,41 +200,14 @@ class DealService(BaseService):
quantity = request_services_dict[service.id]
deal.services.append(
models.secondary.DealService(
service=service,
deal=deal,
service_id=service.id,
deal_id=deal.id,
quantity=quantity
)
)
await self.session.commit()
return DealAddServicesResponse(ok=True, message='Услуги успешно добавлены')
async def get_all(self) -> DealGetAllResponse:
deals_query = await self.session.scalars(select(Deal).options(joinedload(Deal.client)))
deals = deals_query.all()
result = []
for deal in deals:
result.append(DealSchema.model_validate(deal))
return DealGetAllResponse(deals=result)
async def get_by_id(self, deal_id: int) -> DealSchema:
deal = await self.session.scalar(
select(Deal)
.options(
joinedload(Deal.client),
selectinload(Deal.services)
.joinedload(models.secondary.DealService.service)
.joinedload(Service.category),
selectinload(Deal.products)
.joinedload(models.secondary.DealProduct.product)
.joinedload(models.Product.client)
.selectinload(models.Product.barcodes)
)
.where(Deal.id == deal_id)
)
if not deal:
raise HTTPException(status_code=404, detail="Сделка не найдена")
return DealSchema.model_validate(deal)
async def update_service_quantity(self,
request: DealUpdateServiceQuantityRequest) -> DealUpdateServiceQuantityResponse:
try:
@@ -259,3 +283,84 @@ class DealService(BaseService):
except Exception as e:
await self.session.rollback()
return DealDeleteServicesResponse(ok=False, message=str(e))
# endregion
# region Deal products
async def update_product_quantity(self,
request: DealUpdateProductQuantityRequest) -> DealUpdateProductQuantityResponse:
try:
# check if there is no deal or no product with different exceptions
deal_product = await self.session.scalar(
select(models.secondary.DealProduct)
.where(models.secondary.DealProduct.deal_id == request.deal_id,
models.secondary.DealProduct.product_id == request.product_id)
)
if not deal_product:
raise HTTPException(status_code=404, detail="Сделка или товар не найдена")
deal_product.quantity = request.quantity
await self.session.commit()
return DealUpdateProductQuantityResponse(ok=True, message='Количество успешно обновлено')
except Exception as e:
await self.session.rollback()
return DealUpdateProductQuantityResponse(ok=False, message=str(e))
async def add_product(self, request: DealAddProductRequest) -> DealAddProductResponse:
try:
deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
if not deal:
raise HTTPException(status_code=404, detail="Сделка не найдена")
product = await self.session.scalar(select(models.Product).where(models.Product.id == request.product_id))
if not product:
raise HTTPException(status_code=404, detail="Товар не найден")
# Preventing duplicates
deal_product = await self.session.scalar(
select(models.secondary.DealProduct)
.where(models.secondary.DealProduct.deal_id == request.deal_id,
models.secondary.DealProduct.product_id == request.product_id)
)
if deal_product:
raise HTTPException(status_code=400, detail="Товар уже добавлен")
deal_product = models.secondary.DealProduct(
deal_id=request.deal_id,
product_id=request.product_id,
quantity=request.quantity
)
self.session.add(deal_product)
await self.session.commit()
return DealAddProductResponse(ok=True, message='Товар успешно добавлен')
except Exception as e:
await self.session.rollback()
return DealAddProductResponse(ok=False, message=str(e))
async def delete_product(self, request: DealDeleteProductRequest) -> DealDeleteProductResponse:
try:
deal_product = await self.session.scalar(
select(models.secondary.DealProduct)
.where(models.secondary.DealProduct.deal_id == request.deal_id,
models.secondary.DealProduct.product_id == request.product_id)
)
if not deal_product:
raise HTTPException(status_code=404, detail="Сделка не найдена")
await self.session.delete(deal_product)
await self.session.commit()
return DealDeleteProductResponse(ok=True, message='Товар успешно удален')
except Exception as e:
await self.session.rollback()
return DealDeleteProductResponse(ok=False, message=str(e))
async def delete_products(self, request: DealDeleteProductsRequest) -> DealDeleteProductsResponse:
try:
deal_products = await self.session.scalars(
select(models.secondary.DealProduct)
.where(models.secondary.DealProduct.deal_id == request.deal_id,
models.secondary.DealProduct.product_id.in_(request.product_ids))
)
for deal_product in deal_products:
await self.session.delete(deal_product)
await self.session.commit()
return DealDeleteProductsResponse(ok=True, message='Товары успешно удалены')
except Exception as e:
await self.session.rollback()
return DealDeleteProductsResponse(ok=False, message=str(e))
# endregion