othr
This commit is contained in:
@@ -132,3 +132,4 @@ async def get_deal_by_id(
|
|||||||
session: Annotated[AsyncSession, Depends(get_session)]
|
session: Annotated[AsyncSession, Depends(get_session)]
|
||||||
):
|
):
|
||||||
return await DealService(session).get_by_id(deal_id)
|
return await DealService(session).get_by_id(deal_id)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import Annotated
|
from typing import Annotated, Union
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
@@ -38,6 +38,7 @@ async def delete_product(
|
|||||||
):
|
):
|
||||||
return await ProductService(session).delete(request)
|
return await ProductService(session).delete(request)
|
||||||
|
|
||||||
|
|
||||||
@product_router.post(
|
@product_router.post(
|
||||||
'/update',
|
'/update',
|
||||||
response_model=ProductUpdateResponse,
|
response_model=ProductUpdateResponse,
|
||||||
@@ -49,6 +50,7 @@ async def delete_product(
|
|||||||
):
|
):
|
||||||
return await ProductService(session).update(request)
|
return await ProductService(session).update(request)
|
||||||
|
|
||||||
|
|
||||||
@product_router.get(
|
@product_router.get(
|
||||||
'/get',
|
'/get',
|
||||||
response_model=ProductGetResponse,
|
response_model=ProductGetResponse,
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class OkMessageSchema(CustomModelCamel):
|
|||||||
|
|
||||||
|
|
||||||
class PaginationSchema(CustomModelCamel):
|
class PaginationSchema(CustomModelCamel):
|
||||||
page: int
|
page: int | None = None
|
||||||
items_per_page: int
|
items_per_page: int | None = None
|
||||||
|
|
||||||
|
|
||||||
class PaginationInfoSchema(CustomModelCamel):
|
class PaginationInfoSchema(CustomModelCamel):
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from typing import List
|
|||||||
|
|
||||||
from schemas.base import CustomModelCamel, OkMessageSchema
|
from schemas.base import CustomModelCamel, OkMessageSchema
|
||||||
from schemas.client import ClientSchema
|
from schemas.client import ClientSchema
|
||||||
|
from schemas.product import ProductSchema
|
||||||
from schemas.service import ServiceSchema
|
from schemas.service import ServiceSchema
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +29,11 @@ class DealServiceSchema(CustomModelCamel):
|
|||||||
quantity: int
|
quantity: int
|
||||||
|
|
||||||
|
|
||||||
|
class DealProductSchema(CustomModelCamel):
|
||||||
|
product: ProductSchema
|
||||||
|
quantity: int
|
||||||
|
|
||||||
|
|
||||||
class DealSchema(CustomModelCamel):
|
class DealSchema(CustomModelCamel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
@@ -35,6 +41,7 @@ class DealSchema(CustomModelCamel):
|
|||||||
created_at: datetime.datetime
|
created_at: datetime.datetime
|
||||||
current_status: int
|
current_status: int
|
||||||
services: List[DealServiceSchema]
|
services: List[DealServiceSchema]
|
||||||
|
products: List[DealProductSchema]
|
||||||
# total_price: int
|
# total_price: int
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ from schemas.base import CustomModelCamel, PaginationInfoSchema, OkMessageSchema
|
|||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
|
class ProductBarcodeSchema(CustomModelCamel):
|
||||||
|
barcode: str
|
||||||
|
|
||||||
|
|
||||||
class ProductSchema(CustomModelCamel):
|
class ProductSchema(CustomModelCamel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
article: str
|
article: str
|
||||||
client_id: int
|
client_id: int
|
||||||
barcodes: list[str]
|
barcodes: list[ProductBarcodeSchema]
|
||||||
|
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|||||||
@@ -172,7 +172,12 @@ class DealService(BaseService):
|
|||||||
joinedload(Deal.client),
|
joinedload(Deal.client),
|
||||||
selectinload(Deal.services)
|
selectinload(Deal.services)
|
||||||
.joinedload(models.secondary.DealService.service)
|
.joinedload(models.secondary.DealService.service)
|
||||||
.joinedload(Service.category))
|
.joinedload(Service.category),
|
||||||
|
selectinload(Deal.products)
|
||||||
|
.joinedload(models.secondary.DealProduct.product)
|
||||||
|
.joinedload(models.Product.client)
|
||||||
|
.selectinload(models.Product.barcodes)
|
||||||
|
)
|
||||||
.where(Deal.id == deal_id)
|
.where(Deal.id == deal_id)
|
||||||
)
|
)
|
||||||
if not deal:
|
if not deal:
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ from models.product import Product, ProductBarcode
|
|||||||
from schemas.base import PaginationSchema
|
from schemas.base import PaginationSchema
|
||||||
from services.base import BaseService
|
from services.base import BaseService
|
||||||
from schemas.product import *
|
from schemas.product import *
|
||||||
|
from utils.dependecies import is_valid_pagination
|
||||||
|
|
||||||
|
|
||||||
class ProductService(BaseService):
|
class ProductService(BaseService):
|
||||||
|
|
||||||
async def create(self, request: ProductCreateRequest) -> ProductCreateResponse:
|
async def create(self, request: ProductCreateRequest) -> ProductCreateResponse:
|
||||||
# Unique article validation
|
# Unique article validation
|
||||||
existing_product_query = await self.session.execute(
|
existing_product_query = await self.session.execute(
|
||||||
@@ -85,23 +87,39 @@ class ProductService(BaseService):
|
|||||||
async def get_by_client_id(self, client_id: int, pagination: PaginationSchema) -> ProductGetResponse:
|
async def get_by_client_id(self, client_id: int, pagination: PaginationSchema) -> ProductGetResponse:
|
||||||
stmt = (
|
stmt = (
|
||||||
select(Product)
|
select(Product)
|
||||||
.options(selectinload(Product.barcodes))
|
.options(selectinload(Product.barcodes)
|
||||||
|
.noload(ProductBarcode.product))
|
||||||
.where(Product.client_id == client_id)
|
.where(Product.client_id == client_id)
|
||||||
.order_by(Product.id)
|
.order_by(Product.id)
|
||||||
)
|
)
|
||||||
total_products_query = await self.session.execute(
|
if is_valid_pagination(pagination):
|
||||||
select(
|
total_products_query = await self.session.execute(
|
||||||
func.cast(func.ceil(func.count() / pagination.items_per_page), Integer),
|
select(
|
||||||
func.count()
|
func.cast(func.ceil(func.count() / pagination.items_per_page), Integer),
|
||||||
|
func.count()
|
||||||
|
)
|
||||||
|
.select_from(stmt.subquery())
|
||||||
)
|
)
|
||||||
.select_from(stmt.subquery())
|
total_pages, total_items = total_products_query.first()
|
||||||
)
|
else:
|
||||||
total_pages, total_items = total_products_query.first()
|
total_items_query = await self.session.execute(
|
||||||
|
select(func.count())
|
||||||
|
.select_from(stmt.subquery())
|
||||||
|
)
|
||||||
|
total_items = total_items_query.scalar()
|
||||||
|
total_pages = 1
|
||||||
pagination_info = PaginationInfoSchema(total_pages=total_pages, total_items=total_items)
|
pagination_info = PaginationInfoSchema(total_pages=total_pages, total_items=total_items)
|
||||||
|
|
||||||
|
if is_valid_pagination(pagination):
|
||||||
|
stmt = (
|
||||||
|
stmt
|
||||||
|
.offset(pagination.page * pagination.items_per_page)
|
||||||
|
.limit(pagination.items_per_page)
|
||||||
|
)
|
||||||
|
|
||||||
query = await self.session.execute(
|
query = await self.session.execute(
|
||||||
stmt
|
stmt
|
||||||
.offset(pagination.page * pagination.items_per_page)
|
.order_by(Product.id)
|
||||||
.limit(pagination.items_per_page)
|
|
||||||
)
|
)
|
||||||
products: list[ProductSchema] = []
|
products: list[ProductSchema] = []
|
||||||
for product in query.scalars().all():
|
for product in query.scalars().all():
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from models import Product, ProductBarcode
|
|||||||
|
|
||||||
|
|
||||||
async def main(session: AsyncSession):
|
async def main(session: AsyncSession):
|
||||||
client_ids = [2, 4]
|
client_ids = [8, 18]
|
||||||
for client_id in client_ids:
|
for client_id in client_ids:
|
||||||
for i in range(1, 500 + 1):
|
for i in range(1, 500 + 1):
|
||||||
product = Product(
|
product = Product(
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
from schemas.base import PaginationSchema
|
from schemas.base import PaginationSchema
|
||||||
|
|
||||||
|
|
||||||
async def pagination_parameters(page: int, items_per_page: int) -> PaginationSchema:
|
async def pagination_parameters(page: int | None = None, items_per_page: int | None = None) -> PaginationSchema:
|
||||||
return PaginationSchema(page=page, items_per_page=items_per_page)
|
return PaginationSchema(page=page, items_per_page=items_per_page)
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_pagination(pagination: PaginationSchema | None) -> bool:
|
||||||
|
if not pagination:
|
||||||
|
return False
|
||||||
|
return all([
|
||||||
|
isinstance(pagination.items_per_page, int),
|
||||||
|
isinstance(pagination.page, int)
|
||||||
|
])
|
||||||
|
|||||||
Reference in New Issue
Block a user