99 lines
3.8 KiB
Python
99 lines
3.8 KiB
Python
import math
|
||
|
||
from fastapi import UploadFile
|
||
|
||
from external.s3_uploader import S3Uploader
|
||
from modules.fulfillment_base.models import Product
|
||
from modules.fulfillment_base.repositories import ProductRepository
|
||
from modules.fulfillment_base.schemas.product import *
|
||
from schemas.base import PaginationSchema, PaginationInfoSchema
|
||
from services.mixins import *
|
||
|
||
|
||
class ProductService(
|
||
ServiceCreateMixin[Product, CreateProductRequest, ProductSchema],
|
||
ServiceUpdateMixin[Product, UpdateProductRequest],
|
||
ServiceDeleteMixin[Product],
|
||
):
|
||
schema_class = ProductSchema
|
||
entity_deleted_msg = "Товар успешно удален"
|
||
entity_updated_msg = "Товар успешно обновлен"
|
||
entity_created_msg = "Товар успешно создан"
|
||
|
||
def __init__(self, session: AsyncSession):
|
||
self.repository = ProductRepository(session)
|
||
|
||
async def get_all(
|
||
self,
|
||
pagination: PaginationSchema,
|
||
*filters,
|
||
) -> GetProductsResponse:
|
||
products, total_items = await self.repository.get_all(
|
||
pagination.page,
|
||
pagination.items_per_page,
|
||
*filters,
|
||
)
|
||
|
||
total_pages = 1
|
||
if pagination.items_per_page:
|
||
total_pages = math.ceil(total_items / pagination.items_per_page)
|
||
|
||
return GetProductsResponse(
|
||
items=[ProductSchema.model_validate(product) for product in products],
|
||
pagination_info=PaginationInfoSchema(
|
||
total_pages=total_pages, total_items=total_items
|
||
),
|
||
)
|
||
|
||
async def upload_image(
|
||
self, product_id: int, upload_file: UploadFile
|
||
) -> ProductUploadImageResponse:
|
||
product: Product = await self.repository.get_by_id(product_id)
|
||
s3_uploader = S3Uploader()
|
||
|
||
if len(product.images) > 0:
|
||
for image in product.images:
|
||
s3_key = image.image_url.split("/")[-1]
|
||
await s3_uploader.delete_image(s3_key)
|
||
await self.repository.delete_images(product.images)
|
||
|
||
image_url = await s3_uploader.upload_from_upload_file_obj(upload_file)
|
||
await self.repository.create_image(product_id, image_url)
|
||
return ProductUploadImageResponse(
|
||
message="Изображение успешно загружено", image_url=image_url
|
||
)
|
||
|
||
async def upload_barcode_image(
|
||
self, product_id: int, upload_file: UploadFile
|
||
) -> BarcodeUploadImageResponse:
|
||
product: Product = await self.repository.get_by_id(product_id)
|
||
s3_uploader = S3Uploader()
|
||
|
||
if product.barcode_image:
|
||
s3_key = product.barcode_image.image_url.split("/")[-1]
|
||
await s3_uploader.delete_image(s3_key)
|
||
await self.repository.delete_barcode_image(product.barcode_image)
|
||
|
||
image_url = await s3_uploader.upload_from_upload_file_obj(upload_file)
|
||
await self.repository.create_barcode_image(product_id, image_url)
|
||
return BarcodeUploadImageResponse(
|
||
message="Изображение штрихкода успешно загружено", image_url=image_url
|
||
)
|
||
|
||
async def delete_barcode_image(self, product_id: int) -> DeleteBarcodeImageResponse:
|
||
product: Product = await self.repository.get_by_id(product_id)
|
||
|
||
if not product.barcode_image:
|
||
return DeleteBarcodeImageResponse(
|
||
message="У товара нет изображения штрихкода"
|
||
)
|
||
|
||
s3_uploader = S3Uploader()
|
||
s3_key = product.barcode_image.image_url.split("/")[-1]
|
||
await s3_uploader.delete_image(s3_key)
|
||
await self.repository.delete_barcode_image(product.barcode_image, True)
|
||
|
||
return DeleteBarcodeImageResponse(
|
||
message="Изображение штрихкода успешно удалено"
|
||
)
|