This commit is contained in:
2024-03-28 08:22:14 +03:00
parent 6ba041a839
commit a72eb31e07
19 changed files with 243 additions and 28 deletions

View File

@@ -1,10 +1,11 @@
import datetime
from typing import Type, Union
import models.secondary
from typing import Union
from sqlalchemy import select
from fastapi import HTTPException
from sqlalchemy import select, func
from sqlalchemy.orm import joinedload, selectinload
from models import User, Deal
from models import User, Service
from models.deal import *
from schemas.client import ClientDetailsSchema
from schemas.deal import *
@@ -80,13 +81,27 @@ class DealService(BaseService):
return DealChangeStatusResponse(ok=True)
async def get_summary(self) -> DealSummaryResponse:
deals_query = await self.session.scalars(select(Deal)
.options(selectinload(Deal.status_history),
joinedload(Deal.client))
.where(Deal.is_deleted == False,
Deal.is_completed == False))
service_subquery = (
select(
models.secondary.DealService.deal_id,
func.sum(models.secondary.DealService.quantity * Service.price).label('total_price')
)
.join(Service)
.group_by(models.secondary.DealService.deal_id)
.subquery()
)
q = (select(
Deal,
func.coalesce(service_subquery.c.total_price, 0)
)
.options(selectinload(Deal.status_history),
joinedload(Deal.client))
.outerjoin(service_subquery, Deal.id == service_subquery.c.deal_id)
.where(Deal.is_deleted == False,
Deal.is_completed == False))
deals_query = await self.session.execute(q)
summaries = []
for deal in deals_query.all():
for deal, total_price in deals_query.all():
deal: Deal
last_status: DealStatusHistory = max(deal.status_history, key=lambda status: status.changed_at)
summaries.append(
@@ -95,7 +110,49 @@ class DealService(BaseService):
client_name=deal.client.name,
name=deal.name,
changed_at=last_status.changed_at,
status=last_status.to_status
status=last_status.to_status,
total_price=total_price
)
)
return DealSummaryResponse(summaries=summaries)
return DealSummaryResponse(summaries=summaries)
async def add_services(self, request: DealAddServicesRequest):
# TODO refactor
deal: Deal = await self.session.scalar(
select(Deal)
.options(selectinload(Deal.services))
.where(Deal.id == request.deal_id)
)
if not deal:
raise HTTPException(status_code=404, detail="Deal is not found")
services_ids = [service.id for service in request.services]
existing_service_ids = {service.service_id for service in deal.services}
request_services_dict = {service.id: service.quantity for service in request.services}
services_query = await self.session.scalars(select(Service).where(Service.id.in_(services_ids)))
services = services_query.all()
if len(services) != len(services_ids):
raise HTTPException(status_code=404, detail="Some of services is not found")
# Adding quantity
for deal_service in deal.services:
deal_service: models.secondary.DealService
if deal_service.service_id not in services_ids:
continue
deal_service.quantity += request_services_dict[deal_service.service_id]
# Adding new services
for service in services:
if service.id in existing_service_ids:
continue
quantity = request_services_dict[service.id]
deal.services.append(
models.secondary.DealService(
service=service,
deal=deal,
quantity=quantity
)
)
await self.session.commit()
return DealAddServicesResponse(ok=True, message='Услуги успешно добавлены')

37
services/product.py Normal file
View File

@@ -0,0 +1,37 @@
from fastapi import HTTPException
from sqlalchemy import select
from models.product import Product
from schemas.base import PaginationSchema
from services.base import BaseService
from schemas.product import *
class ProductService(BaseService):
async def create(self, request: ProductCreateRequest) -> ProductCreateResponse:
existing_product_query = await self.session.execute(
select(Product)
.where(Product.client_id == request.client_id,
Product.article == request.article)
)
existing_product = existing_product_query.first()
if existing_product:
raise HTTPException(status_code=403, detail="Product already exists")
product = Product(**request.dict())
self.session.add(product)
await self.session.commit()
return ProductCreateResponse(product_id=product.id)
async def get_by_client_id(self, client_id: int, pagination: PaginationSchema) -> ProductGetResponse:
query = await self.session.execute(
select(Product)
.where(Product.client_id == client_id)
.offset(pagination.page * pagination.items_per_page)
.limit(pagination.items_per_page)
)
products: list[ProductSchema] = []
for product in query.scalars().all():
products.append(
ProductSchema.model_validate(product)
)
return ProductGetResponse(products=products)

View File

@@ -3,7 +3,7 @@ from sqlalchemy.orm import joinedload
from models import Service, ServiceCategory
from services.base import BaseService
from schemas.services import ServiceGetAllResponse, ServiceSchema, ServiceGetAllCategoriesResponse, \
from schemas.service import ServiceGetAllResponse, ServiceSchema, ServiceGetAllCategoriesResponse, \
ServiceCategorySchema, ServiceCreateRequest, ServiceCreateResponse, ServiceCreateCategoryRequest, \
ServiceCreateCategoryResponse