import base64 from io import BytesIO from sqlalchemy.ext.asyncio import AsyncSession from modules.fulfillment_base.barcodes_pdf_gen import BarcodePdfGenerator, BarcodeData from modules.fulfillment_base.barcodes_pdf_gen.types import PdfBarcodeImageGenData from modules.fulfillment_base.models import Product, DealProduct from modules.fulfillment_base.repositories import ( ProductRepository, DealProductRepository, ) from modules.fulfillment_base.schemas.product import ( GetProductBarcodePdfRequest, GetDealBarcodesPdfRequest, ) class BarcodePrinterService: session: AsyncSession def __init__(self, session: AsyncSession): self.session = session async def generate_product_pdf( self, request: GetProductBarcodePdfRequest ) -> tuple[str, BytesIO]: product: Product = await ProductRepository(self.session).get_by_id( request.product_id ) if product.barcode_image: barcode_data: PdfBarcodeImageGenData = { "barcode_image_url": product.barcode_image.image_url, "num_duplicates": request.quantity, } else: barcode_data: BarcodeData = { "barcode": request.barcode, "template": product.barcode_template, "product": product, "num_duplicates": request.quantity, } filename = f"{product.id}_barcode.pdf" size = product.barcode_template.size generator = BarcodePdfGenerator(size.width, size.height) return filename, await generator.generate([barcode_data]) async def generate_product_base64( self, request: GetProductBarcodePdfRequest ) -> tuple[str, str]: filename, pdf_buffer = await self.generate_product_pdf(request) base64_string = base64.b64encode(pdf_buffer.read()).decode("utf-8") return filename, base64_string async def generate_deal_pdf( self, request: GetDealBarcodesPdfRequest ) -> tuple[str, BytesIO]: deal_product_repo = DealProductRepository(self.session) deal_products: list[DealProduct] = await deal_product_repo.get_all( request.deal_id ) if len(deal_products) == 0: return "no_content.pdf", BytesIO() barcodes_data: list[BarcodeData | PdfBarcodeImageGenData] = [] for deal_product in deal_products: if deal_product.product.barcode_image: barcode_data: PdfBarcodeImageGenData = { "barcode_image_url": deal_product.product.barcode_image.image_url, "num_duplicates": deal_product.quantity, } barcodes_data.append(barcode_data) elif len(deal_product.product.barcodes) > 0: barcode_data: BarcodeData = { "barcode": deal_product.product.barcodes[0].barcode, "template": deal_product.product.barcode_template, "product": deal_product.product, "num_duplicates": deal_product.quantity, } barcodes_data.append(barcode_data) size = deal_products[0].product.barcode_template.size generator = BarcodePdfGenerator(size.width, size.height) filename = "deal_barcodes.pdf" return filename, await generator.generate(barcodes_data) async def generate_deal_base64( self, request: GetDealBarcodesPdfRequest ) -> tuple[str, str]: filename, pdf_buffer = await self.generate_deal_pdf(request) base64_string = base64.b64encode(pdf_buffer.read()).decode("utf-8") return filename, base64_string