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: try: product: Product = await self.repository.get_by_id(product_id) s3_uploader = S3Uploader() 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( ok=True, message="Изображение успешно загружено", image_url=image_url ) except Exception as e: return ProductUploadImageResponse(ok=False, message=str(e))