From 307e6573e3c1122c310d32eee9e2c029f3eea7bf Mon Sep 17 00:00:00 2001 From: AlexSserb Date: Thu, 30 Oct 2025 15:41:32 +0400 Subject: [PATCH] feat: printing uploaded product barcode images --- .../barcodes_pdf_gen/barcode_pdf_generator.py | 25 +++++++++++++------ .../services/barcode_printer_service.py | 22 ++++++++++------ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/modules/fulfillment_base/barcodes_pdf_gen/barcode_pdf_generator.py b/modules/fulfillment_base/barcodes_pdf_gen/barcode_pdf_generator.py index e56a150..daaa3eb 100644 --- a/modules/fulfillment_base/barcodes_pdf_gen/barcode_pdf_generator.py +++ b/modules/fulfillment_base/barcodes_pdf_gen/barcode_pdf_generator.py @@ -1,6 +1,7 @@ from io import BytesIO from typing import Any, Optional +import aiohttp from reportlab.graphics.barcode import code128 from reportlab.lib.units import mm from reportlab.platypus import Spacer, PageBreak, Paragraph @@ -24,7 +25,7 @@ class BarcodePdfGenerator(PDFGenerator): return None return value - def generate( + async def generate( self, barcodes_data: list[BarcodeData | PdfBarcodeImageGenData] ) -> BytesIO: pdf_barcodes_gen_data: list[PdfBarcodeGenData | PdfBarcodeImageGenData] = [] @@ -52,9 +53,9 @@ class BarcodePdfGenerator(PDFGenerator): } ) - return self._generate(pdf_barcodes_gen_data) + return await self._generate(pdf_barcodes_gen_data) - def _generate( + async def _generate( self, barcodes_data: list[PdfBarcodeGenData | PdfBarcodeImageGenData] ) -> BytesIO: pdf_maker = PdfMaker((self.page_width, self.page_height)) @@ -63,9 +64,10 @@ class BarcodePdfGenerator(PDFGenerator): for barcode_data in barcodes_data: if "barcode_value" in barcode_data: - pdf_files.append(self._generate_for_one_product(barcode_data)) + result = self._generate_for_one_product(barcode_data) else: - pdf_files.append(self._generate_for_one_product_using_img(barcode_data)) + result = await self._generate_for_one_product_using_img(barcode_data) + pdf_files.append(result) pdf_files.append(self._generate_spacers()) for file in pdf_files[:-1]: @@ -138,11 +140,18 @@ class BarcodePdfGenerator(PDFGenerator): buffer.seek(0) return buffer - def _generate_for_one_product_using_img( + async def _generate_for_one_product_using_img( self, barcode_data: PdfBarcodeImageGenData ) -> BytesIO: - with open(barcode_data["barcode_image_url"], "rb") as pdf_file: - pdf_bytes = pdf_file.read() + pdf_url = barcode_data["barcode_image_url"] + + async with aiohttp.ClientSession() as session: + async with session.get(pdf_url) as response: + if response.status != 200: + raise ValueError( + f"Failed to download PDF from {pdf_url} (status {response.status})" + ) + pdf_bytes = await response.read() pdf_maker = PdfMaker((self.page_width, self.page_height)) for _ in range(barcode_data["num_duplicates"]): diff --git a/modules/fulfillment_base/services/barcode_printer_service.py b/modules/fulfillment_base/services/barcode_printer_service.py index 5568cf3..89ca1b2 100644 --- a/modules/fulfillment_base/services/barcode_printer_service.py +++ b/modules/fulfillment_base/services/barcode_printer_service.py @@ -4,6 +4,7 @@ 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 from modules.fulfillment_base.repositories import ProductRepository from modules.fulfillment_base.schemas.product import GetProductBarcodePdfRequest @@ -21,17 +22,24 @@ class BarcodePrinterService: product: Product = await ProductRepository(self.session).get_by_id( request.product_id ) - barcode_data: BarcodeData = { - "barcode": request.barcode, - "template": product.barcode_template, - "product": product, - "num_duplicates": request.quantity, - } + 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, generator.generate([barcode_data]) + return filename, await generator.generate([barcode_data]) async def generate_base64( self, request: GetProductBarcodePdfRequest