This commit is contained in:
2024-04-11 14:25:40 +03:00
parent 7f302acdb5
commit 5c81af05d5
9 changed files with 63 additions and 17 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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