crappy
This commit is contained in:
2
main.py
2
main.py
@@ -6,7 +6,7 @@ import routers
|
||||
origins = [
|
||||
'http://localhost:5173'
|
||||
]
|
||||
app = FastAPI()
|
||||
app = FastAPI(separate_input_output_schemas=False)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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='Кол-во продукта')
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
100
services/deal.py
100
services/deal.py
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user