feat: get deal barcodes pdf

This commit is contained in:
2025-11-01 14:25:22 +04:00
parent ef657c4939
commit 80a74ac8e6
5 changed files with 82 additions and 9 deletions

View File

@ -13,7 +13,7 @@ def create_app() -> FastAPI:
separate_input_output_schemas=True, separate_input_output_schemas=True,
default_response_class=settings.DEFAULT_RESPONSE_CLASS, default_response_class=settings.DEFAULT_RESPONSE_CLASS,
root_path=settings.ROOT_PATH, root_path=settings.ROOT_PATH,
lifespan=lifespan, # lifespan=lifespan,
) )
register_middlewares(app) register_middlewares(app)

View File

@ -26,6 +26,7 @@ class DealProductRepository(
return ( return (
stmt.options( stmt.options(
joinedload(DealProduct.product).selectinload(Product.barcodes), joinedload(DealProduct.product).selectinload(Product.barcodes),
joinedload(DealProduct.product).joinedload(Product.client),
selectinload(DealProduct.product_services).joinedload( selectinload(DealProduct.product_services).joinedload(
DealProductService.service DealProductService.service
), ),

View File

@ -97,6 +97,10 @@ class GetProductBarcodePdfRequest(BaseSchema):
barcode: str barcode: str
class GetDealBarcodesPdfRequest(BaseSchema):
deal_id: int
# endregion # endregion
# region Response # region Response
@ -127,6 +131,10 @@ class GetProductBarcodePdfResponse(BasePdfResponse):
pass pass
class GetDealBarcodesPdfResponse(BasePdfResponse):
pass
class BarcodeUploadImageResponse(BaseResponse): class BarcodeUploadImageResponse(BaseResponse):
image_url: Optional[str] = None image_url: Optional[str] = None

View File

@ -5,9 +5,15 @@ from sqlalchemy.ext.asyncio import AsyncSession
from modules.fulfillment_base.barcodes_pdf_gen import BarcodePdfGenerator, BarcodeData from modules.fulfillment_base.barcodes_pdf_gen import BarcodePdfGenerator, BarcodeData
from modules.fulfillment_base.barcodes_pdf_gen.types import PdfBarcodeImageGenData from modules.fulfillment_base.barcodes_pdf_gen.types import PdfBarcodeImageGenData
from modules.fulfillment_base.models import Product from modules.fulfillment_base.models import Product, DealProduct
from modules.fulfillment_base.repositories import ProductRepository from modules.fulfillment_base.repositories import (
from modules.fulfillment_base.schemas.product import GetProductBarcodePdfRequest ProductRepository,
DealProductRepository,
)
from modules.fulfillment_base.schemas.product import (
GetProductBarcodePdfRequest,
GetDealBarcodesPdfRequest,
)
class BarcodePrinterService: class BarcodePrinterService:
@ -16,7 +22,7 @@ class BarcodePrinterService:
def __init__(self, session: AsyncSession): def __init__(self, session: AsyncSession):
self.session = session self.session = session
async def generate_pdf( async def generate_product_pdf(
self, request: GetProductBarcodePdfRequest self, request: GetProductBarcodePdfRequest
) -> tuple[str, BytesIO]: ) -> tuple[str, BytesIO]:
product: Product = await ProductRepository(self.session).get_by_id( product: Product = await ProductRepository(self.session).get_by_id(
@ -41,9 +47,50 @@ class BarcodePrinterService:
generator = BarcodePdfGenerator(size.width, size.height) generator = BarcodePdfGenerator(size.width, size.height)
return filename, await generator.generate([barcode_data]) return filename, await generator.generate([barcode_data])
async def generate_base64( async def generate_product_base64(
self, request: GetProductBarcodePdfRequest self, request: GetProductBarcodePdfRequest
) -> tuple[str, str]: ) -> tuple[str, str]:
filename, pdf_buffer = await self.generate_pdf(request) 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") base64_string = base64.b64encode(pdf_buffer.read()).decode("utf-8")
return filename, base64_string return filename, base64_string

View File

@ -79,10 +79,27 @@ async def delete_product(
response_model=GetProductBarcodePdfResponse, response_model=GetProductBarcodePdfResponse,
) )
async def get_product_barcode_pdf( async def get_product_barcode_pdf(
request: GetProductBarcodePdfRequest, session: SessionDependency session: SessionDependency,
request: GetProductBarcodePdfRequest,
): ):
service = BarcodePrinterService(session) service = BarcodePrinterService(session)
filename, base64_string = await service.generate_base64(request) filename, base64_string = await service.generate_product_base64(request)
return GetProductBarcodePdfResponse(
base64_string=base64_string, filename=filename, mime_type="application/pdf"
)
@router.post(
"/barcode/for-deal/get-pdf",
operation_id="get_deal_barcodes_pdf",
response_model=GetDealBarcodesPdfResponse,
)
async def get_deal_barcodes_pdf(
session: SessionDependency,
request: GetDealBarcodesPdfRequest,
):
service = BarcodePrinterService(session)
filename, base64_string = await service.generate_deal_base64(request)
return GetProductBarcodePdfResponse( return GetProductBarcodePdfResponse(
base64_string=base64_string, filename=filename, mime_type="application/pdf" base64_string=base64_string, filename=filename, mime_type="application/pdf"
) )