feat: total services amount and recalculating
This commit is contained in:
@@ -3,7 +3,10 @@ from sqlalchemy.orm import declarative_base, DeclarativeBase
|
||||
|
||||
|
||||
class BaseModel(DeclarativeBase, AsyncAttrs):
|
||||
pass
|
||||
def __repr__(self):
|
||||
if hasattr(self, 'id'):
|
||||
return f'<{self.__class__.__name__} id={self.id}>'
|
||||
return super().__repr__()
|
||||
|
||||
|
||||
metadata = BaseModel.metadata
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey, ForeignKeyConstraint, UniqueConstraint
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import relationship, mapped_column, Mapped
|
||||
|
||||
from models.base import BaseModel
|
||||
|
||||
@@ -41,6 +41,7 @@ class DealService(BaseModel):
|
||||
|
||||
quantity = Column(Integer, nullable=False, comment='Кол-во услуги')
|
||||
price = Column(Integer, nullable=False, server_default='0', comment='Цена услуги')
|
||||
is_fixed_price: Mapped[bool] = mapped_column(default=False, server_default='0', comment='Фиксированная цена')
|
||||
|
||||
employees = relationship('User', secondary=deal_service_employees)
|
||||
|
||||
@@ -59,6 +60,8 @@ class DealProductService(BaseModel):
|
||||
|
||||
price = Column(Integer, nullable=False, comment='Цена услуги')
|
||||
|
||||
is_fixed_price: Mapped[bool] = mapped_column(default=False, server_default='0', comment='Фиксированная цена')
|
||||
|
||||
deal_product = relationship('DealProduct',
|
||||
back_populates='services',
|
||||
primaryjoin="and_(DealProductService.deal_id == DealProduct.deal_id, "
|
||||
@@ -114,4 +117,3 @@ barcode_template_attribute_link = Table(
|
||||
Column('barcode_template_id', ForeignKey('barcode_templates.id')),
|
||||
Column('attribute_id', ForeignKey('barcode_template_attributes.id'))
|
||||
)
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ async def complete(
|
||||
):
|
||||
return await DealService(session).complete(user, request)
|
||||
|
||||
|
||||
@deal_router.post(
|
||||
'/quickCreate',
|
||||
response_model=DealQuickCreateResponse,
|
||||
@@ -221,6 +222,18 @@ async def post_prefill_deal(
|
||||
return await DealService(session).prefill_deal(user, request)
|
||||
|
||||
|
||||
@deal_router.post(
|
||||
'/recalculate-price',
|
||||
response_model=DealRecalculatePriceResponse,
|
||||
operation_id='recalculate_deal_price',
|
||||
)
|
||||
async def recalculate_deal_price(
|
||||
session: SessionDependency,
|
||||
request: DealRecalculatePriceRequest,
|
||||
):
|
||||
return await DealService(session).recalculate_price(request)
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region Deal services
|
||||
|
||||
@@ -56,12 +56,13 @@ class DealServiceSchema(BaseSchema):
|
||||
quantity: int
|
||||
price: int
|
||||
employees: List[UserSchema]
|
||||
|
||||
is_fixed_price: bool
|
||||
|
||||
class DealProductServiceSchema(BaseSchema):
|
||||
service: ServiceSchema
|
||||
price: int
|
||||
employees: List[UserSchema]
|
||||
is_fixed_price: bool
|
||||
|
||||
|
||||
class DealProductSchema(BaseSchema):
|
||||
@@ -243,6 +244,10 @@ class DealPrefillRequest(BaseSchema):
|
||||
new_deal_id: int
|
||||
|
||||
|
||||
class DealRecalculatePriceRequest(BaseSchema):
|
||||
deal_id: int
|
||||
|
||||
|
||||
# endregion Requests
|
||||
|
||||
# region Responses
|
||||
@@ -347,4 +352,7 @@ class DealCompleteResponse(OkMessageSchema):
|
||||
class DealPrefillResponse(OkMessageSchema):
|
||||
pass
|
||||
|
||||
|
||||
class DealRecalculatePriceResponse(OkMessageSchema):
|
||||
pass
|
||||
# endregion Responses
|
||||
|
||||
@@ -6,7 +6,7 @@ from starlette import status
|
||||
|
||||
import models.deal
|
||||
import models.secondary
|
||||
from models import User, Service, Client
|
||||
from models import User, Service, Client, DealProductService
|
||||
from models.deal import *
|
||||
from schemas.client import ClientDetailsSchema
|
||||
from schemas.deal import *
|
||||
@@ -732,7 +732,8 @@ class DealService(BaseService):
|
||||
'deal_id': request.deal_id,
|
||||
'product_id': deal_product.product_id,
|
||||
'service_id': service.service.id,
|
||||
'price': service.price
|
||||
'price': service.price,
|
||||
'is_fixed_price': service.is_fixed_price
|
||||
})
|
||||
if not insert_data:
|
||||
return DealServicesCopyResponse(ok=True, message='Услуги успешно перенесены')
|
||||
@@ -916,6 +917,7 @@ class DealService(BaseService):
|
||||
continue
|
||||
request_service = services_dict[service.service_id]
|
||||
service.price = request_service.price
|
||||
service.is_fixed_price = request_service.is_fixed_price
|
||||
await self.session.flush()
|
||||
|
||||
# Creating services
|
||||
@@ -1001,7 +1003,7 @@ class DealService(BaseService):
|
||||
'deal_id': request.deal_id,
|
||||
'product_id': deal_product.product_id,
|
||||
'service_id': service.id,
|
||||
'price': service_price
|
||||
'price': service_price,
|
||||
})
|
||||
if not insert_data:
|
||||
return DealProductAddKitResponse(ok=True, message='Набор услуг успешно добавлен к товару')
|
||||
@@ -1029,6 +1031,7 @@ class DealService(BaseService):
|
||||
return DealProductAddKitResponse(ok=False, message=str(e))
|
||||
|
||||
# endregion
|
||||
|
||||
async def complete(self, user: User, request: DealCompleteRequest) -> DealCompleteResponse:
|
||||
try:
|
||||
# check for admin
|
||||
@@ -1044,3 +1047,59 @@ class DealService(BaseService):
|
||||
except Exception as e:
|
||||
await self.session.rollback()
|
||||
return DealCompleteResponse(ok=False, message=str(e))
|
||||
|
||||
async def recalculate_price(self, request: DealRecalculatePriceRequest) -> DealRecalculatePriceResponse:
|
||||
try:
|
||||
deal_stmt = (
|
||||
select(
|
||||
Deal
|
||||
)
|
||||
.options(
|
||||
selectinload(Deal.services)
|
||||
.joinedload(models.DealService.service),
|
||||
selectinload(Deal.products)
|
||||
.selectinload(DealProduct.services)
|
||||
.joinedload(DealProductService.service),
|
||||
)
|
||||
.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
|
||||
await self.session.commit()
|
||||
return DealRecalculatePriceResponse(ok=True, message="Цены успешно пересчитаны")
|
||||
except Exception as e:
|
||||
return DealRecalculatePriceResponse(ok=False, message=str(e))
|
||||
|
||||
Reference in New Issue
Block a user