This commit is contained in:
2024-04-11 07:57:08 +03:00
parent 93eb6ae6b7
commit 7f302acdb5
8 changed files with 267 additions and 26 deletions

View File

@@ -6,7 +6,7 @@ import routers
origins = [
'http://localhost:5173'
]
app = FastAPI()
app = FastAPI(separate_input_output_schemas=False)
app.add_middleware(
CORSMiddleware,

View File

@@ -33,7 +33,7 @@ class Deal(BaseModel):
is_completed = Column(Boolean, nullable=False, server_default='0', default=False, comment='Завершена')
services = relationship('DealService', back_populates='deal')
products = relationship('DealProduct', back_populates='deal')
class DealStatusHistory(BaseModel):
__tablename__ = 'deals_status_history'

View File

@@ -13,3 +13,15 @@ class DealService(BaseModel):
service = relationship('Service')
quantity = Column(Integer, nullable=False, comment='Кол-во услуги')
class DealProduct(BaseModel):
__tablename__ = 'deal_products'
deal_id = Column(Integer, ForeignKey('deals.id'), nullable=False, comment='ID Сделки', primary_key=True)
deal = relationship('Deal', back_populates='products')
product_id = Column(Integer, ForeignKey('products.id'), nullable=False, comment='ID Продукта', primary_key=True)
product = relationship('Product')
quantity = Column(Integer, nullable=False, comment='Кол-во продукта')

View File

@@ -53,11 +53,82 @@ async def get_summary(
@deal_router.post(
'/services/add',
'/services/add/multiple',
response_model=DealAddServicesResponse,
operation_id='addMultipleDealServices'
)
async def services_add(
request: DealAddServicesRequest,
session: Annotated[AsyncSession, Depends(get_session)]
):
return await DealService(session).add_services(request)
@deal_router.post(
'/services/add',
response_model=DealAddServiceResponse,
operation_id='addDealService'
)
async def services_add(
request: DealAddServiceRequest,
session: Annotated[AsyncSession, Depends(get_session)]
):
return await DealService(session).add_service(request)
@deal_router.post(
'/services/update-quantity',
response_model=DealUpdateServiceQuantityResponse,
operation_id='updateDealServiceQuantity'
)
async def services_update(
request: DealUpdateServiceQuantityRequest,
session: Annotated[AsyncSession, Depends(get_session)]
):
return await DealService(session).update_service_quantity(request)
@deal_router.post(
'/services/delete',
response_model=DealDeleteServiceResponse,
operation_id='deleteDealService'
)
async def services_delete(
request: DealDeleteServiceRequest,
session: Annotated[AsyncSession, Depends(get_session)]
):
return await DealService(session).delete_service(request)
@deal_router.post(
'/services/delete/multiple',
response_model=DealDeleteServicesResponse,
operation_id='deleteMultipleDealServices'
)
async def services_delete(
request: DealDeleteServicesRequest,
session: Annotated[AsyncSession, Depends(get_session)]
):
return await DealService(session).delete_services(request)
@deal_router.get(
'/get-all',
response_model=DealGetAllResponse,
operation_id='getAllDeals'
)
async def get_all(
session: Annotated[AsyncSession, Depends(get_session)]
):
return await DealService(session).get_all()
# endpoint to get deal by id
@deal_router.get(
'/get/{deal_id}',
response_model=DealSchema,
operation_id='getDealById'
)
async def get_deal_by_id(
deal_id: int,
session: Annotated[AsyncSession, Depends(get_session)]
):
return await DealService(session).get_by_id(deal_id)

View File

@@ -3,6 +3,7 @@ from typing import List
from schemas.base import CustomModelCamel, OkMessageSchema
# region Entities
class ClientDetailsSchema(CustomModelCamel):
address: str | None = None
phone_number: str | None = None
@@ -16,19 +17,37 @@ class ClientSchema(CustomModelCamel):
details: ClientDetailsSchema | None = None
# endregion
# region Requests
class ClientSearchRequest(CustomModelCamel):
name: str
class ClientSearchResponse(CustomModelCamel):
clients: List[ClientSchema]
class ClientUpdateDetailsRequest(CustomModelCamel):
client_id: int
details: ClientDetailsSchema
class ClientCreateRequest(CustomModelCamel):
data: ClientSchema
class ClientUpdateRequest(CustomModelCamel):
data: ClientSchema
class ClientDeleteRequest(CustomModelCamel):
client_id: int
# endregion
# region Responses
class ClientSearchResponse(CustomModelCamel):
clients: List[ClientSchema]
class ClientUpdateDetailsResponse(CustomModelCamel):
ok: bool
@@ -41,21 +60,10 @@ class ClientCreateResponse(OkMessageSchema):
pass
class ClientCreateRequest(CustomModelCamel):
data: ClientSchema
class ClientUpdateRequest(CustomModelCamel):
data: ClientSchema
class ClientUpdateResponse(OkMessageSchema):
pass
class ClientDeleteRequest(CustomModelCamel):
client_id: int
class ClientDeleteResponse(OkMessageSchema):
pass
# endregion

View File

@@ -1,8 +1,9 @@
import datetime
from typing import List
from schemas.base import CustomModelCamel
from schemas.base import CustomModelCamel, OkMessageSchema
from schemas.client import ClientSchema
from schemas.service import ServiceSchema
# region Entities
@@ -23,10 +24,20 @@ class DealSummary(CustomModelCamel):
class DealServiceSchema(CustomModelCamel):
id: int
service: ServiceSchema
quantity: int
class DealSchema(CustomModelCamel):
id: int
name: str
client_id: int
created_at: datetime.datetime
current_status: int
services: List[DealServiceSchema]
# total_price: int
# endregion Entities
# region Requests
@@ -56,6 +67,36 @@ class DealAddServicesRequest(CustomModelCamel):
services: list[DealServiceSchema]
class DealGetAllResponse(CustomModelCamel):
deals: List[DealSchema]
class DealUpdateServiceQuantityRequest(CustomModelCamel):
deal_id: int
service_id: int
quantity: int
class DealAddServiceRequest(CustomModelCamel):
deal_id: int
service_id: int
quantity: int
class DealDeleteServiceRequest(CustomModelCamel):
deal_id: int
service_id: int
class DealDeleteServicesResponse(OkMessageSchema):
pass
class DealDeleteServicesRequest(CustomModelCamel):
deal_id: int
service_ids: List[int]
# endregion Requests
# region Responses
@@ -79,4 +120,17 @@ class DealSummaryResponse(CustomModelCamel):
class DealAddServicesResponse(CustomModelCamel):
ok: bool
message: str
class DealUpdateServiceQuantityResponse(CustomModelCamel):
ok: bool
message: str
class DealAddServiceResponse(OkMessageSchema):
pass
class DealDeleteServiceResponse(OkMessageSchema):
pass
# endregion Responses

View File

@@ -1,14 +1,12 @@
import datetime
from typing import Union, Annotated
from typing import Union
from fastapi import Depends
from sqlalchemy import select, update
from sqlalchemy.orm import joinedload
from models import Client, ClientDetails, User
from services.auth import get_current_user
from services.base import BaseService
from schemas.client import *
from services.base import BaseService
class ClientService(BaseService):

View File

@@ -1,6 +1,6 @@
import models.secondary
from typing import Union
import models.deal
from fastapi import HTTPException
from sqlalchemy import select, func
from sqlalchemy.orm import joinedload, selectinload
@@ -156,3 +156,101 @@ class DealService(BaseService):
)
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))
.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:
deal_service = await self.session.scalar(
select(models.secondary.DealService)
.where(models.secondary.DealService.deal_id == request.deal_id,
models.secondary.DealService.service_id == request.service_id)
)
if not deal_service:
raise HTTPException(status_code=404, detail="Сделка не найдена")
deal_service.quantity = request.quantity
await self.session.commit()
return DealUpdateServiceQuantityResponse(ok=True, message='Количество успешно обновлено')
except Exception as e:
await self.session.rollback()
return DealUpdateServiceQuantityResponse(ok=False, message=str(e))
async def add_service(self, request: DealAddServiceRequest) -> DealAddServiceResponse:
try:
deal = await self.session.scalar(select(Deal).where(Deal.id == request.deal_id))
if not deal:
raise HTTPException(status_code=404, detail="Сделка не найдена")
service = await self.session.scalar(select(Service).where(Service.id == request.service_id))
if not service:
raise HTTPException(status_code=404, detail="Услуга не найдена")
# Preventing duplicates
deal_service = await self.session.scalar(
select(models.secondary.DealService)
.where(models.secondary.DealService.deal_id == request.deal_id,
models.secondary.DealService.service_id == request.service_id)
)
if deal_service:
raise HTTPException(status_code=400, detail="Услуга уже добавлена")
deal_service = models.secondary.DealService(
deal_id=request.deal_id,
service_id=request.service_id,
quantity=request.quantity
)
self.session.add(deal_service)
await self.session.commit()
return DealAddServiceResponse(ok=True, message='Услуга успешно добавлена')
except Exception as e:
await self.session.rollback()
return DealAddServiceResponse(ok=False, message=str(e))
async def delete_service(self, request: DealDeleteServiceRequest) -> DealDeleteServiceResponse:
try:
deal_service = await self.session.scalar(
select(models.secondary.DealService)
.where(models.secondary.DealService.deal_id == request.deal_id,
models.secondary.DealService.service_id == request.service_id)
)
if not deal_service:
raise HTTPException(status_code=404, detail="Сделка не найдена")
await self.session.delete(deal_service)
await self.session.commit()
return DealDeleteServiceResponse(ok=True, message='Услуга успешно удалена')
except Exception as e:
await self.session.rollback()
return DealDeleteServiceResponse(ok=False, message=str(e))
async def delete_services(self, request: DealDeleteServicesRequest) -> DealDeleteServicesResponse:
try:
deal_services = await self.session.scalars(
select(models.secondary.DealService)
.where(models.secondary.DealService.deal_id == request.deal_id,
models.secondary.DealService.service_id.in_(request.service_ids))
)
for deal_service in deal_services:
await self.session.delete(deal_service)
await self.session.commit()
return DealDeleteServicesResponse(ok=True, message='Услуги успешно удалены')
except Exception as e:
await self.session.rollback()
return DealDeleteServicesResponse(ok=False, message=str(e))