crappy
This commit is contained in:
@@ -12,7 +12,7 @@ class Product(BaseModel):
|
|||||||
|
|
||||||
client_id = Column(Integer, ForeignKey('clients.id'), nullable=False, comment='ID сделки')
|
client_id = Column(Integer, ForeignKey('clients.id'), nullable=False, comment='ID сделки')
|
||||||
client = relationship('Client', back_populates='products')
|
client = relationship('Client', back_populates='products')
|
||||||
barcodes = relationship('ProductBarcode', back_populates='product')
|
barcodes = relationship('ProductBarcode', back_populates='product', cascade="all, delete-orphan")
|
||||||
|
|
||||||
|
|
||||||
class ProductBarcode(BaseModel):
|
class ProductBarcode(BaseModel):
|
||||||
@@ -20,4 +20,4 @@ class ProductBarcode(BaseModel):
|
|||||||
product_id = Column(Integer, ForeignKey('products.id'), nullable=False, comment='ID товара', primary_key=True)
|
product_id = Column(Integer, ForeignKey('products.id'), nullable=False, comment='ID товара', primary_key=True)
|
||||||
product = relationship('Product', back_populates='barcodes')
|
product = relationship('Product', back_populates='barcodes')
|
||||||
|
|
||||||
barcode = Column(String, nullable=False, index=True, comment='ШК товара')
|
barcode = Column(String, nullable=False, index=True, comment='ШК товара', primary_key=True)
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ product_router = APIRouter(
|
|||||||
|
|
||||||
@product_router.post(
|
@product_router.post(
|
||||||
'/create',
|
'/create',
|
||||||
response_model=ProductCreateResponse
|
response_model=ProductCreateResponse,
|
||||||
|
operation_id='create_product'
|
||||||
)
|
)
|
||||||
async def create_product(
|
async def create_product(
|
||||||
request: ProductCreateRequest,
|
request: ProductCreateRequest,
|
||||||
@@ -26,6 +27,28 @@ async def create_product(
|
|||||||
return await ProductService(session).create(request)
|
return await ProductService(session).create(request)
|
||||||
|
|
||||||
|
|
||||||
|
@product_router.post(
|
||||||
|
'/delete',
|
||||||
|
response_model=ProductDeleteResponse,
|
||||||
|
operation_id='delete_product'
|
||||||
|
)
|
||||||
|
async def delete_product(
|
||||||
|
request: ProductDeleteRequest,
|
||||||
|
session: Annotated[AsyncSession, Depends(get_session)]
|
||||||
|
):
|
||||||
|
return await ProductService(session).delete(request)
|
||||||
|
|
||||||
|
@product_router.post(
|
||||||
|
'/update',
|
||||||
|
response_model=ProductUpdateResponse,
|
||||||
|
operation_id='update_product'
|
||||||
|
)
|
||||||
|
async def delete_product(
|
||||||
|
request: ProductUpdateRequest,
|
||||||
|
session: Annotated[AsyncSession, Depends(get_session)]
|
||||||
|
):
|
||||||
|
return await ProductService(session).update(request)
|
||||||
|
|
||||||
@product_router.get(
|
@product_router.get(
|
||||||
'/get',
|
'/get',
|
||||||
response_model=ProductGetResponse,
|
response_model=ProductGetResponse,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from schemas.base import CustomModel
|
from schemas.base import CustomModelCamel, CustomModelSnake
|
||||||
|
|
||||||
|
|
||||||
class AuthLoginRequest(CustomModel):
|
class AuthLoginRequest(CustomModelSnake):
|
||||||
auth_date: int
|
auth_date: int
|
||||||
first_name: str
|
first_name: str
|
||||||
hash: str
|
hash: str
|
||||||
@@ -9,5 +9,5 @@ class AuthLoginRequest(CustomModel):
|
|||||||
photo_url: str
|
photo_url: str
|
||||||
|
|
||||||
|
|
||||||
class AuthLoginResponse(CustomModel):
|
class AuthLoginResponse(CustomModelCamel):
|
||||||
access_token: str
|
access_token: str
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
from pydantic.alias_generators import to_camel
|
||||||
|
|
||||||
|
|
||||||
class CustomConfig:
|
class CustomConfig:
|
||||||
@@ -6,21 +7,34 @@ class CustomConfig:
|
|||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class CustomModel(BaseModel):
|
class CustomModelCamel(BaseModel):
|
||||||
|
class Config:
|
||||||
|
from_attributes = True
|
||||||
|
alias_generator = to_camel
|
||||||
|
populate_by_name = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_sql_model(cls, model, fields: dict):
|
||||||
|
model_dict = {c.name: getattr(model, c.name) for c in model.__table__.columns}
|
||||||
|
model_dict.update(fields)
|
||||||
|
return cls(**model_dict)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomModelSnake(BaseModel):
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class OkMessageSchema(BaseModel):
|
class OkMessageSchema(CustomModelCamel):
|
||||||
ok: bool
|
ok: bool
|
||||||
message: str
|
message: str
|
||||||
|
|
||||||
|
|
||||||
class PaginationSchema(CustomModel):
|
class PaginationSchema(CustomModelCamel):
|
||||||
page: int
|
page: int
|
||||||
items_per_page: int
|
items_per_page: int
|
||||||
|
|
||||||
|
|
||||||
class PaginationInfoSchema(CustomModel):
|
class PaginationInfoSchema(CustomModelCamel):
|
||||||
total_pages: int
|
total_pages: int
|
||||||
total_items: int
|
total_items: int
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from schemas.base import CustomModel
|
from schemas.base import CustomModelCamel
|
||||||
|
|
||||||
|
|
||||||
class ClientDetailsSchema(CustomModel):
|
class ClientDetailsSchema(CustomModelCamel):
|
||||||
address: str | None = None
|
address: str | None = None
|
||||||
phone_number: str | None = None
|
phone_number: str | None = None
|
||||||
inn: int | None = None
|
inn: int | None = None
|
||||||
email: str | None = None
|
email: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class ClientSchema(CustomModel):
|
class ClientSchema(CustomModelCamel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
details: ClientDetailsSchema | None = None
|
details: ClientDetailsSchema | None = None
|
||||||
|
|
||||||
|
|
||||||
class ClientSearchRequest(CustomModel):
|
class ClientSearchRequest(CustomModelCamel):
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class ClientCreateRequest(CustomModel):
|
class ClientCreateRequest(CustomModelCamel):
|
||||||
name: str
|
name: str
|
||||||
address: str
|
address: str
|
||||||
|
|
||||||
|
|
||||||
class ClientSearchResponse(CustomModel):
|
class ClientSearchResponse(CustomModelCamel):
|
||||||
clients: List[ClientSchema]
|
clients: List[ClientSchema]
|
||||||
|
|
||||||
|
|
||||||
class ClientUpdateDetailsRequest(CustomModel):
|
class ClientUpdateDetailsRequest(CustomModelCamel):
|
||||||
client_id: int
|
client_id: int
|
||||||
details: ClientDetailsSchema
|
details: ClientDetailsSchema
|
||||||
|
|
||||||
|
|
||||||
class ClientUpdateDetailsResponse(CustomModel):
|
class ClientUpdateDetailsResponse(CustomModelCamel):
|
||||||
ok: bool
|
ok: bool
|
||||||
|
|
||||||
|
|
||||||
class ClientGetAllResponse(CustomModel):
|
class ClientGetAllResponse(CustomModelCamel):
|
||||||
clients: List[ClientSchema]
|
clients: List[ClientSchema]
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from schemas.base import CustomModel
|
from schemas.base import CustomModelCamel
|
||||||
from schemas.client import ClientSchema
|
from schemas.client import ClientSchema
|
||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
class FastDeal(CustomModel):
|
class FastDeal(CustomModelCamel):
|
||||||
name: str
|
name: str
|
||||||
client: ClientSchema
|
client: ClientSchema
|
||||||
comment: str
|
comment: str
|
||||||
acceptance_date: datetime.datetime
|
acceptance_date: datetime.datetime
|
||||||
|
|
||||||
|
|
||||||
class DealSummary(CustomModel):
|
class DealSummary(CustomModelCamel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
client_name: str
|
client_name: str
|
||||||
@@ -22,7 +22,7 @@ class DealSummary(CustomModel):
|
|||||||
total_price: int
|
total_price: int
|
||||||
|
|
||||||
|
|
||||||
class DealServiceSchema(CustomModel):
|
class DealServiceSchema(CustomModelCamel):
|
||||||
id: int
|
id: int
|
||||||
quantity: int
|
quantity: int
|
||||||
|
|
||||||
@@ -30,16 +30,16 @@ class DealServiceSchema(CustomModel):
|
|||||||
# endregion Entities
|
# endregion Entities
|
||||||
|
|
||||||
# region Requests
|
# region Requests
|
||||||
class DealChangeStatusRequest(CustomModel):
|
class DealChangeStatusRequest(CustomModelCamel):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
new_status: int
|
new_status: int
|
||||||
|
|
||||||
|
|
||||||
class DealCreateRequest(CustomModel):
|
class DealCreateRequest(CustomModelCamel):
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class DealQuickCreateRequest(CustomModel):
|
class DealQuickCreateRequest(CustomModelCamel):
|
||||||
name: str
|
name: str
|
||||||
client_name: str
|
client_name: str
|
||||||
client_address: str
|
client_address: str
|
||||||
@@ -47,11 +47,11 @@ class DealQuickCreateRequest(CustomModel):
|
|||||||
acceptance_date: datetime.datetime
|
acceptance_date: datetime.datetime
|
||||||
|
|
||||||
|
|
||||||
class DealSummaryRequest(CustomModel):
|
class DealSummaryRequest(CustomModelCamel):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DealAddServicesRequest(CustomModel):
|
class DealAddServicesRequest(CustomModelCamel):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
services: list[DealServiceSchema]
|
services: list[DealServiceSchema]
|
||||||
|
|
||||||
@@ -60,23 +60,23 @@ class DealAddServicesRequest(CustomModel):
|
|||||||
|
|
||||||
# region Responses
|
# region Responses
|
||||||
|
|
||||||
class DealChangeStatusResponse(CustomModel):
|
class DealChangeStatusResponse(CustomModelCamel):
|
||||||
ok: bool
|
ok: bool
|
||||||
|
|
||||||
|
|
||||||
class DealCreateResponse(CustomModel):
|
class DealCreateResponse(CustomModelCamel):
|
||||||
ok: bool
|
ok: bool
|
||||||
|
|
||||||
|
|
||||||
class DealQuickCreateResponse(CustomModel):
|
class DealQuickCreateResponse(CustomModelCamel):
|
||||||
deal_id: int
|
deal_id: int
|
||||||
|
|
||||||
|
|
||||||
class DealSummaryResponse(CustomModel):
|
class DealSummaryResponse(CustomModelCamel):
|
||||||
summaries: List[DealSummary]
|
summaries: List[DealSummary]
|
||||||
|
|
||||||
|
|
||||||
class DealAddServicesResponse(CustomModel):
|
class DealAddServicesResponse(CustomModelCamel):
|
||||||
ok: bool
|
ok: bool
|
||||||
message: str
|
message: str
|
||||||
# endregion Responses
|
# endregion Responses
|
||||||
|
|||||||
@@ -1,33 +1,51 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from schemas.base import CustomModel, PaginationInfoSchema
|
from schemas.base import CustomModelCamel, PaginationInfoSchema, OkMessageSchema
|
||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
class ProductSchema(CustomModel):
|
class ProductSchema(CustomModelCamel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
article: str
|
article: str
|
||||||
client_id: int
|
client_id: int
|
||||||
|
barcodes: list[str]
|
||||||
|
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Requests
|
# region Requests
|
||||||
class ProductCreateRequest(CustomModel):
|
class ProductCreateRequest(CustomModelCamel):
|
||||||
name: str
|
name: str
|
||||||
article: str
|
article: str
|
||||||
client_id: int
|
client_id: int
|
||||||
|
barcodes: List[str]
|
||||||
|
|
||||||
|
|
||||||
|
class ProductDeleteRequest(CustomModelCamel):
|
||||||
|
product_id: int
|
||||||
|
|
||||||
|
|
||||||
|
class ProductUpdateRequest(CustomModelCamel):
|
||||||
|
product: ProductSchema
|
||||||
|
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Responses
|
# region Responses
|
||||||
class ProductCreateResponse(CustomModel):
|
class ProductCreateResponse(OkMessageSchema):
|
||||||
product_id: int
|
product_id: int | None = None
|
||||||
|
|
||||||
|
|
||||||
class ProductGetResponse(CustomModel):
|
class ProductGetResponse(CustomModelCamel):
|
||||||
products: List[ProductSchema]
|
products: List[ProductSchema]
|
||||||
pagination_info: PaginationInfoSchema
|
pagination_info: PaginationInfoSchema
|
||||||
|
|
||||||
|
|
||||||
|
class ProductDeleteResponse(OkMessageSchema):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ProductUpdateResponse(OkMessageSchema):
|
||||||
|
pass
|
||||||
# endregion
|
# endregion
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from schemas.base import CustomModel, OkMessageSchema
|
from schemas.base import CustomModelCamel, OkMessageSchema
|
||||||
|
|
||||||
|
|
||||||
# region Entities
|
# region Entities
|
||||||
class ServiceCategorySchema(CustomModel):
|
class ServiceCategorySchema(CustomModelCamel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class ServiceSchema(CustomModel):
|
class ServiceSchema(CustomModelCamel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
category: ServiceCategorySchema
|
category: ServiceCategorySchema
|
||||||
@@ -20,11 +20,11 @@ class ServiceSchema(CustomModel):
|
|||||||
|
|
||||||
|
|
||||||
# region Requests
|
# region Requests
|
||||||
class ServiceCreateRequest(CustomModel):
|
class ServiceCreateRequest(CustomModelCamel):
|
||||||
service: ServiceSchema
|
service: ServiceSchema
|
||||||
|
|
||||||
|
|
||||||
class ServiceCreateCategoryRequest(CustomModel):
|
class ServiceCreateCategoryRequest(CustomModelCamel):
|
||||||
category: ServiceCategorySchema
|
category: ServiceCategorySchema
|
||||||
|
|
||||||
|
|
||||||
@@ -32,11 +32,11 @@ class ServiceCreateCategoryRequest(CustomModel):
|
|||||||
|
|
||||||
|
|
||||||
# region Responses
|
# region Responses
|
||||||
class ServiceGetAllResponse(CustomModel):
|
class ServiceGetAllResponse(CustomModelCamel):
|
||||||
services: List[ServiceSchema]
|
services: List[ServiceSchema]
|
||||||
|
|
||||||
|
|
||||||
class ServiceGetAllCategoriesResponse(CustomModel):
|
class ServiceGetAllCategoriesResponse(CustomModelCamel):
|
||||||
categories: List[ServiceCategorySchema]
|
categories: List[ServiceCategorySchema]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from typing import Union, Annotated
|
from typing import Union, Annotated
|
||||||
|
|
||||||
from fastapi import Depends, HTTPException
|
from fastapi import Depends, HTTPException
|
||||||
from fastapi.security import OAuth2PasswordBearer, HTTPBearer, HTTPAuthorizationCredentials
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||||
from jose import jwt, JWTError
|
from jose import jwt, JWTError
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
@@ -10,8 +10,8 @@ from starlette import status
|
|||||||
import backend.config
|
import backend.config
|
||||||
from backend.session import get_session
|
from backend.session import get_session
|
||||||
from models import User
|
from models import User
|
||||||
from services.base import BaseService
|
|
||||||
from schemas.auth import *
|
from schemas.auth import *
|
||||||
|
from services.base import BaseService
|
||||||
|
|
||||||
oauth2_schema = HTTPBearer()
|
oauth2_schema = HTTPBearer()
|
||||||
algorithm = 'HS256'
|
algorithm = 'HS256'
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select, func, Integer, update
|
||||||
|
from sqlalchemy.orm import selectinload
|
||||||
|
|
||||||
from models.product import Product
|
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 *
|
||||||
@@ -9,6 +10,7 @@ from schemas.product import *
|
|||||||
|
|
||||||
class ProductService(BaseService):
|
class ProductService(BaseService):
|
||||||
async def create(self, request: ProductCreateRequest) -> ProductCreateResponse:
|
async def create(self, request: ProductCreateRequest) -> ProductCreateResponse:
|
||||||
|
# Unique article validation
|
||||||
existing_product_query = await self.session.execute(
|
existing_product_query = await self.session.execute(
|
||||||
select(Product)
|
select(Product)
|
||||||
.where(Product.client_id == request.client_id,
|
.where(Product.client_id == request.client_id,
|
||||||
@@ -16,22 +18,101 @@ class ProductService(BaseService):
|
|||||||
)
|
)
|
||||||
existing_product = existing_product_query.first()
|
existing_product = existing_product_query.first()
|
||||||
if existing_product:
|
if existing_product:
|
||||||
raise HTTPException(status_code=403, detail="Product already exists")
|
return ProductCreateResponse(ok=False, message='Товар с таким артикулом уже существует у клиента')
|
||||||
product = Product(**request.dict())
|
|
||||||
|
# Creating product
|
||||||
|
product_dict = request.dict()
|
||||||
|
del product_dict['barcodes']
|
||||||
|
product = Product(**product_dict)
|
||||||
self.session.add(product)
|
self.session.add(product)
|
||||||
|
|
||||||
|
# Creating barcodes
|
||||||
|
await self.session.flush()
|
||||||
|
for barcode in request.barcodes:
|
||||||
|
product_barcode = ProductBarcode(product_id=product.id,
|
||||||
|
barcode=barcode)
|
||||||
|
self.session.add(product_barcode)
|
||||||
|
await self.session.flush()
|
||||||
await self.session.commit()
|
await self.session.commit()
|
||||||
return ProductCreateResponse(product_id=product.id)
|
return ProductCreateResponse(ok=True, message='Товар успешно создан', product_id=product.id)
|
||||||
|
|
||||||
|
async def delete(self, request: ProductDeleteRequest):
|
||||||
|
product = await self.session.get(Product, request.product_id)
|
||||||
|
if not product:
|
||||||
|
return ProductDeleteResponse(ok=False, message='Указанного товара не существует')
|
||||||
|
await self.session.delete(product)
|
||||||
|
await self.session.commit()
|
||||||
|
return ProductDeleteResponse(ok=True, message="Товар успешно удален!")
|
||||||
|
|
||||||
|
async def update(self, request: ProductUpdateRequest):
|
||||||
|
stmt = (
|
||||||
|
select(Product)
|
||||||
|
.where(Product.id == request.product.id)
|
||||||
|
.options(selectinload(Product.barcodes))
|
||||||
|
)
|
||||||
|
product_query = await self.session.execute(stmt)
|
||||||
|
product = product_query.scalar()
|
||||||
|
if not product:
|
||||||
|
return ProductUpdateResponse(ok=False, message='Указанного товара не существует')
|
||||||
|
product_dict = request.product.dict()
|
||||||
|
del product_dict['id']
|
||||||
|
del product_dict['barcodes']
|
||||||
|
await self.session.execute(
|
||||||
|
update(Product)
|
||||||
|
.where(Product.id == request.product.id)
|
||||||
|
.values(**product_dict)
|
||||||
|
)
|
||||||
|
# Updating barcodes
|
||||||
|
product_barcodes = set([barcode for barcode in product.barcodes])
|
||||||
|
request_barcodes = set(request.product.barcodes)
|
||||||
|
new_barcodes = request_barcodes.difference(product_barcodes)
|
||||||
|
deleted_barcodes = product_barcodes.difference(request_barcodes)
|
||||||
|
for product_barcode in product.barcodes:
|
||||||
|
if product_barcode not in deleted_barcodes:
|
||||||
|
continue
|
||||||
|
await self.session.delete(product_barcode)
|
||||||
|
for new_barcode in new_barcodes:
|
||||||
|
product_barcode = ProductBarcode(
|
||||||
|
product_id=product.id,
|
||||||
|
barcode=new_barcode
|
||||||
|
)
|
||||||
|
self.session.add(product_barcode)
|
||||||
|
await self.session.flush()
|
||||||
|
|
||||||
|
await self.session.commit()
|
||||||
|
return ProductUpdateResponse(ok=True, message='Товар успешно обновлен')
|
||||||
|
|
||||||
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:
|
||||||
query = await self.session.execute(
|
stmt = (
|
||||||
select(Product)
|
select(Product)
|
||||||
|
.options(selectinload(Product.barcodes))
|
||||||
.where(Product.client_id == client_id)
|
.where(Product.client_id == client_id)
|
||||||
|
.order_by(Product.id)
|
||||||
|
)
|
||||||
|
total_products_query = await self.session.execute(
|
||||||
|
select(
|
||||||
|
func.cast(func.ceil(func.count() / pagination.items_per_page), Integer),
|
||||||
|
func.count()
|
||||||
|
)
|
||||||
|
.select_from(stmt.subquery())
|
||||||
|
)
|
||||||
|
total_pages, total_items = total_products_query.first()
|
||||||
|
pagination_info = PaginationInfoSchema(total_pages=total_pages, total_items=total_items)
|
||||||
|
query = await self.session.execute(
|
||||||
|
stmt
|
||||||
.offset(pagination.page * pagination.items_per_page)
|
.offset(pagination.page * pagination.items_per_page)
|
||||||
.limit(pagination.items_per_page)
|
.limit(pagination.items_per_page)
|
||||||
)
|
)
|
||||||
products: list[ProductSchema] = []
|
products: list[ProductSchema] = []
|
||||||
for product in query.scalars().all():
|
for product in query.scalars().all():
|
||||||
|
product: Product
|
||||||
|
|
||||||
|
barcodes = []
|
||||||
|
for barcode_obj in product.barcodes:
|
||||||
|
barcode_obj: ProductBarcode
|
||||||
|
barcodes.append(barcode_obj.barcode)
|
||||||
|
|
||||||
products.append(
|
products.append(
|
||||||
ProductSchema.model_validate(product)
|
ProductSchema.from_sql_model(product, {'barcodes': barcodes})
|
||||||
)
|
)
|
||||||
return ProductGetResponse(products=products)
|
return ProductGetResponse(products=products, pagination_info=pagination_info)
|
||||||
|
|||||||
1241
test/test.json
Normal file
1241
test/test.json
Normal file
File diff suppressed because it is too large
Load Diff
36
test/test.py
Normal file
36
test/test.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from backend.session import session_maker
|
||||||
|
from models import Product, ProductBarcode
|
||||||
|
|
||||||
|
|
||||||
|
async def main(session: AsyncSession):
|
||||||
|
client_ids = [2, 4]
|
||||||
|
for client_id in client_ids:
|
||||||
|
for i in range(1, 500 + 1):
|
||||||
|
product = Product(
|
||||||
|
name=f"Товар №{i}",
|
||||||
|
article=f"Ариткул товара №{i}",
|
||||||
|
client_id=client_id
|
||||||
|
)
|
||||||
|
session.add(product)
|
||||||
|
await session.flush()
|
||||||
|
for j in range(1, 5 + 1):
|
||||||
|
barcode = ProductBarcode(
|
||||||
|
barcode=f"Штрихкод №{j} для товара №{i}",
|
||||||
|
product_id=product.id
|
||||||
|
)
|
||||||
|
session.add(barcode)
|
||||||
|
await session.flush()
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def preload():
|
||||||
|
async with session_maker() as session:
|
||||||
|
await main(session)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
asyncio.run(preload())
|
||||||
Reference in New Issue
Block a user