feat: deal group
This commit is contained in:
240
services/deal.py
240
services/deal.py
@@ -1,4 +1,5 @@
|
||||
import lexorank
|
||||
from attr import dataclass
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy import select, func, update, delete, insert
|
||||
from sqlalchemy.orm import joinedload, selectinload
|
||||
@@ -6,7 +7,7 @@ from starlette import status
|
||||
|
||||
import models.deal
|
||||
import models.secondary
|
||||
from models import User, Service, Client, DealProductService
|
||||
from models import User, Service, Client, DealProductService, deal_relations
|
||||
from models.deal import *
|
||||
from schemas.client import ClientDetailsSchema
|
||||
from schemas.deal import *
|
||||
@@ -248,7 +249,7 @@ class DealService(BaseService):
|
||||
delivery_date=deal.delivery_date,
|
||||
receiving_slot_date=deal.receiving_slot_date,
|
||||
bill_request=deal.bill_request,
|
||||
# group=deal.group
|
||||
group=deal.group
|
||||
)
|
||||
)
|
||||
return DealSummaryResponse(summaries=summaries)
|
||||
@@ -1048,6 +1049,66 @@ class DealService(BaseService):
|
||||
await self.session.rollback()
|
||||
return DealCompleteResponse(ok=False, message=str(e))
|
||||
|
||||
async def get_quantity_dict(self, deals: List[models.Deal]):
|
||||
services_quantity = defaultdict(lambda: 0)
|
||||
for deal in deals:
|
||||
for product in deal.products:
|
||||
product: DealProduct
|
||||
for service in product.services:
|
||||
service: DealProductService
|
||||
services_quantity[service.service_id] += product.quantity
|
||||
for service in deal.services:
|
||||
service: models.DealService
|
||||
services_quantity[service.service_id] += service.quantity
|
||||
return services_quantity
|
||||
|
||||
async def _recalculate_price_single(self, deal: models.Deal, quantity_dict: dict):
|
||||
services_quantity = quantity_dict
|
||||
services_prices = {}
|
||||
for product in deal.products:
|
||||
for service in product.services:
|
||||
if service.is_fixed_price:
|
||||
continue
|
||||
quantity = services_quantity[service.service_id]
|
||||
if service.service_id in services_prices:
|
||||
service.price = services_prices[service.service_id]
|
||||
continue
|
||||
price = self.get_service_price(
|
||||
service=service.service,
|
||||
quantity=quantity
|
||||
)
|
||||
service.price = price
|
||||
services_prices[service.service_id] = price
|
||||
for service in deal.services:
|
||||
service: models.DealService
|
||||
if service.is_fixed_price:
|
||||
continue
|
||||
quantity = services_quantity[service.service_id]
|
||||
price = self.get_service_price(
|
||||
service=service.service,
|
||||
quantity=quantity
|
||||
)
|
||||
print(service.service_id, price)
|
||||
service.price = price
|
||||
|
||||
async def _recalculate_price_group(self, group: models.DealGroup):
|
||||
deals = await self.session.scalars(
|
||||
select(Deal)
|
||||
.options(
|
||||
selectinload(Deal.services)
|
||||
.joinedload(models.DealService.service),
|
||||
selectinload(Deal.products)
|
||||
.selectinload(DealProduct.services)
|
||||
.joinedload(DealProductService.service),
|
||||
)
|
||||
.where(Deal.group == group)
|
||||
)
|
||||
deals = list(deals.all())
|
||||
services_quantity = await self.get_quantity_dict(deals)
|
||||
for deal in deals:
|
||||
await self._recalculate_price_single(deal, services_quantity)
|
||||
|
||||
|
||||
async def recalculate_price(self, request: DealRecalculatePriceRequest) -> DealRecalculatePriceResponse:
|
||||
try:
|
||||
deal_stmt = (
|
||||
@@ -1060,46 +1121,151 @@ class DealService(BaseService):
|
||||
selectinload(Deal.products)
|
||||
.selectinload(DealProduct.services)
|
||||
.joinedload(DealProductService.service),
|
||||
joinedload(Deal.group)
|
||||
)
|
||||
.where(Deal.id == request.deal_id)
|
||||
)
|
||||
deal: Deal = await self.session.scalar(deal_stmt)
|
||||
services_quantity = defaultdict(lambda: 0)
|
||||
for product in deal.products:
|
||||
product: DealProduct
|
||||
for service in product.services:
|
||||
service: DealProductService
|
||||
if service.is_fixed_price:
|
||||
continue
|
||||
services_quantity[service.service_id] += product.quantity
|
||||
|
||||
services_prices = {}
|
||||
for product in deal.products:
|
||||
for service in product.services:
|
||||
if service.is_fixed_price:
|
||||
continue
|
||||
quantity = services_quantity[service.service_id]
|
||||
print(service.service_id, quantity)
|
||||
if service.service_id in services_prices:
|
||||
service.price = services_prices[service.service_id]
|
||||
continue
|
||||
price = self.get_service_price(
|
||||
service=service.service,
|
||||
quantity=quantity
|
||||
)
|
||||
print(service.service_id, price)
|
||||
service.price = price
|
||||
services_prices[service.service_id] = price
|
||||
for service in deal.services:
|
||||
service: models.DealService
|
||||
if service.is_fixed_price:
|
||||
continue
|
||||
price = self.get_service_price(
|
||||
service=service.service,
|
||||
quantity=service.quantity
|
||||
)
|
||||
service.price = price
|
||||
if not deal.group:
|
||||
quantity_dict = await self.get_quantity_dict([deal])
|
||||
await self._recalculate_price_single(deal, quantity_dict)
|
||||
else:
|
||||
await self._recalculate_price_group(deal.group)
|
||||
await self.session.commit()
|
||||
return DealRecalculatePriceResponse(ok=True, message="Цены успешно пересчитаны")
|
||||
except Exception as e:
|
||||
return DealRecalculatePriceResponse(ok=False, message=str(e))
|
||||
|
||||
async def add_to_group(self, user: User, request: DealAddToGroupRequest) -> DealAddToGroupResponse:
|
||||
try:
|
||||
# changing status if needed
|
||||
deal_id = await self.session.scalar(
|
||||
select(deal_relations.c.deal_id)
|
||||
.where(deal_relations.c.group_id == request.group_id)
|
||||
)
|
||||
group_deal_status = await self.session.scalar(
|
||||
select(Deal.current_status)
|
||||
.where(Deal.id == deal_id)
|
||||
)
|
||||
request_deal = await self.session.scalar(
|
||||
select(Deal).where(Deal.id == request.deal_id)
|
||||
)
|
||||
if group_deal_status != request_deal.current_status:
|
||||
await self.change_status(request_deal, group_deal_status, user)
|
||||
insert_stmt = insert(deal_relations).values({
|
||||
'deal_id': request.deal_id,
|
||||
'group_id': request.group_id
|
||||
})
|
||||
await self.session.execute(insert_stmt)
|
||||
await self.session.commit()
|
||||
|
||||
return DealAddToGroupResponse(ok=True, message="Сделка успешно добавлена в группу")
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealAddToGroupResponse(ok=False, message=str(e))
|
||||
|
||||
async def create_group(self, user: User, request: DealCreateGroupRequest) -> DealCreateGroupResponse:
|
||||
try:
|
||||
# getting lexorank for grop
|
||||
|
||||
group = models.DealGroup(
|
||||
name='',
|
||||
lexorank=lexorank.middle(lexorank.Bucket.BUCEKT_0).__str__(),
|
||||
|
||||
)
|
||||
|
||||
self.session.add(group)
|
||||
await self.session.flush()
|
||||
for deal_id in [request.dragging_deal_id, request.hovered_deal_id]:
|
||||
insert_stmt = insert(deal_relations).values({
|
||||
'deal_id': deal_id,
|
||||
'group_id': group.id
|
||||
})
|
||||
await self.session.execute(insert_stmt)
|
||||
# changing status if needed on draggable deal
|
||||
dragging_deal = await self.session.scalar(
|
||||
select(Deal).where(Deal.id == request.dragging_deal_id)
|
||||
)
|
||||
dropped_deal = await self.session.scalar(
|
||||
select(Deal).where(Deal.id == request.hovered_deal_id)
|
||||
)
|
||||
if dragging_deal.current_status != dropped_deal.current_status:
|
||||
await self.change_status(dragging_deal, DealStatus(dropped_deal.current_status), user)
|
||||
await self.session.commit()
|
||||
return DealCreateGroupResponse(ok=True, message="Группа успешно создана")
|
||||
except Exception as e:
|
||||
return DealCreateGroupResponse(ok=False, message=str(e))
|
||||
|
||||
async def remove_from_group(self, request: DealRemoveFromGroupRequest) -> DealRemoveFromGroupResponse:
|
||||
try:
|
||||
delete_stmt = (
|
||||
delete(deal_relations)
|
||||
.where(
|
||||
deal_relations.c.deal_id == request.deal_id,
|
||||
)
|
||||
)
|
||||
await self.session.execute(delete_stmt)
|
||||
await self.session.commit()
|
||||
return DealRemoveFromGroupResponse(ok=True, message="Сделка успешно удалена из группы")
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealRemoveFromGroupResponse(ok=False, message=str(e))
|
||||
|
||||
async def update_group(self, request: DealGroupUpdateRequest) -> DealGroupUpdateResponse:
|
||||
try:
|
||||
group = await self.session.scalar(
|
||||
select(models.DealGroup).where(models.DealGroup.id == request.data.id)
|
||||
)
|
||||
if not group:
|
||||
return DealGroupUpdateResponse(ok=False, message="Группа не найдена")
|
||||
# update by dictionary
|
||||
request_dict = request.data.dict()
|
||||
update_stmt = (
|
||||
update(
|
||||
models.DealGroup
|
||||
)
|
||||
.where(models.DealGroup.id == request.data.id)
|
||||
.values(**request_dict)
|
||||
)
|
||||
await self.session.execute(update_stmt)
|
||||
await self.session.commit()
|
||||
return DealGroupUpdateResponse(ok=True, message="Группа успешно обновлена")
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealGroupUpdateResponse(ok=False, message=str(e))
|
||||
|
||||
async def change_group_status(self, user: User,
|
||||
request: DealGroupChangeStatusRequest) -> DealGroupChangeStatusResponse:
|
||||
try:
|
||||
# getting all deals in group
|
||||
deals = await self.session.scalars(
|
||||
select(deal_relations.c.deal_id)
|
||||
.where(deal_relations.c.group_id == request.group_id)
|
||||
)
|
||||
for deal_id in deals:
|
||||
deal = await self.session.scalar(
|
||||
select(Deal).where(Deal.id == deal_id)
|
||||
)
|
||||
await self.change_status(deal, DealStatus(request.new_status), user)
|
||||
await self.session.commit()
|
||||
return DealGroupChangeStatusResponse(ok=True, message="Статус группы успешно изменен")
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealGroupChangeStatusResponse(ok=False, message=str(e))
|
||||
|
||||
async def get_deals_grouped(self, deal:models.Deal)->List[models.Deal]:
|
||||
if not deal.group:
|
||||
return [deal]
|
||||
deals = await self.session.scalars(
|
||||
select(Deal)
|
||||
.options(
|
||||
selectinload(Deal.services)
|
||||
.joinedload(models.DealService.service),
|
||||
selectinload(Deal.products)
|
||||
.selectinload(DealProduct.services)
|
||||
.joinedload(DealProductService.service),
|
||||
)
|
||||
.where(Deal.group == deal.group)
|
||||
)
|
||||
deals = list(deals.all())
|
||||
return deals
|
||||
Reference in New Issue
Block a user