feat: total services amount and recalculating

This commit is contained in:
2024-10-22 19:32:27 +03:00
parent 4fa5c0d05b
commit 9a12ddb6af
5 changed files with 93 additions and 8 deletions

View File

@@ -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

View File

@@ -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'))
)

View File

@@ -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

View File

@@ -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

View File

@@ -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))