fix: card creation fix

This commit is contained in:
2025-05-12 17:56:25 +04:00
parent 4f08019d85
commit 329616bcd3
6 changed files with 62 additions and 18 deletions

Binary file not shown.

View File

@@ -17,6 +17,8 @@ API_ROOT = "/api"
APP_PATH = os.path.dirname(sys.executable) if getattr(sys, 'frozen', False) else os.path.dirname(__file__) APP_PATH = os.path.dirname(sys.executable) if getattr(sys, 'frozen', False) else os.path.dirname(__file__)
STATIC_PATH = os.path.join(APP_PATH, "static")
KAFKA_CERTS_PATH = os.path.join(APP_PATH, "certs") KAFKA_CERTS_PATH = os.path.join(APP_PATH, "certs")
allowed_telegram_ids = [ allowed_telegram_ids = [

View File

@@ -15,10 +15,15 @@ class BasePdfCardGenerator:
self._session = session self._session = session
assets_folder = os.path.join(APP_PATH, 'assets') assets_folder = os.path.join(APP_PATH, 'assets')
fonts_folder = os.path.join(assets_folder, 'fonts') fonts_folder = os.path.join(assets_folder, 'fonts')
font_file_path = os.path.join(fonts_folder, 'DejaVuSans.ttf')
dejavu_font_file_path = os.path.join(fonts_folder, 'DejaVuSans.ttf')
pdfmetrics.registerFont(TTFont('DejaVuSans', dejavu_font_file_path))
arial_font_file_path = os.path.join(fonts_folder, 'Arial Nova Cond.ttf')
pdfmetrics.registerFont(TTFont('Arial Nova Cond', arial_font_file_path))
self.page_width = 58 * mm self.page_width = 58 * mm
self.page_height = 40 * mm self.page_height = 40 * mm
pdfmetrics.registerFont(TTFont('DejaVuSans', font_file_path))
self.styles = getSampleStyleSheet() self.styles = getSampleStyleSheet()
self._set_small_paragraph_styles() self._set_small_paragraph_styles()
@@ -64,11 +69,9 @@ class BasePdfCardGenerator:
bottomMargin=1 bottomMargin=1
) )
def _get_paragraph_style(self, font_size: int): def _get_paragraph_style(self, font_size: int, font_name: str = "Arial Nova Cond"):
common_paragraph_style = { common_paragraph_style = {
"parent": self.styles['Normal'], "fontName": font_name,
"fontName": "DejaVuSans",
"spaceAfter": 4,
"fontSize": font_size, "fontSize": font_size,
} }
return ParagraphStyle( return ParagraphStyle(

View File

@@ -1,16 +1,50 @@
import os
from io import BytesIO from io import BytesIO
from reportlab.graphics import renderPDF
from reportlab.lib.units import mm from reportlab.lib.units import mm
from reportlab.pdfgen.canvas import Canvas from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import Paragraph, SimpleDocTemplate, Frame from reportlab.platypus import Paragraph, SimpleDocTemplate, Frame
from reportlab_qrcode import QRCodeImage from reportlab_qrcode import QRCodeImage
from svglib.svglib import svg2rlg
from constants import STATIC_PATH
from generators.base_pdf_card_generator.base_pdf_card_generator import BasePdfCardGenerator from generators.base_pdf_card_generator.base_pdf_card_generator import BasePdfCardGenerator
from services.warehouse_management import WmsService from services.warehouse_management import WmsService
class WarehousePlaceQRCodeGenerator(BasePdfCardGenerator): class WarehousePlaceQRCodeGenerator(BasePdfCardGenerator):
@staticmethod
def _get_big_font_size_from_str(value: str | int) -> int:
value = str(value)
dots = value.count(".")
string = value.replace(".", "")
length = len(string) + dots / 3
if length > 8:
return 30
elif length > 5:
return 37
return 48
@staticmethod
def _get_mid_font_size_from_str(value: str | int) -> int:
value = str(value)
dots = value.count(".")
string = value.replace(".", "")
length = len(string) + dots / 3
if length > 8:
return 22
elif length > 6:
return 26
elif length > 4:
return 30
return 34
async def generate(self, place_id: int, is_short: bool) -> BytesIO: async def generate(self, place_id: int, is_short: bool) -> BytesIO:
icon_path = os.path.join(STATIC_PATH, "icons", "denco.svg")
service = WmsService(self._session) service = WmsService(self._session)
place_code = await service.get_code_of_place(place_id) place_code = await service.get_code_of_place(place_id)
@@ -18,25 +52,28 @@ class WarehousePlaceQRCodeGenerator(BasePdfCardGenerator):
doc: SimpleDocTemplate = self._create_doc(buffer) doc: SimpleDocTemplate = self._create_doc(buffer)
def on_first_page(canvas: Canvas, doc): def on_first_page(canvas: Canvas, doc):
denco_paragraph = Paragraph('DENCO', self.small_centered_style) svg_icon_scale = 0.04
drawing = svg2rlg(icon_path)
drawing.scale(svg_icon_scale, svg_icon_scale)
if is_short: if is_short:
qr = QRCodeImage(place_code, size=20 * mm) qr = QRCodeImage(place_code, size=17 * mm)
qr.drawOn(canvas, 39 * mm, -4) qr.drawOn(canvas, 42 * mm, -4)
number_paragraph = Paragraph(str(place_code), self._get_paragraph_style(26)) font_size = self._get_mid_font_size_from_str(place_code)
number_frame = Frame(x1=0 * mm, y1=-15 * mm, width=42 * mm, height=30 * mm) number_paragraph = Paragraph(str(place_code), self._get_paragraph_style(font_size))
denco_frame = Frame(x1=0 * mm, y1=-2 * mm, width=42 * mm, height=20 * mm) number_frame = Frame(x1=0 * mm, y1=-15 * mm, width=45 * mm, height=30 * mm)
renderPDF.draw(drawing, canvas, 3, 35)
else: else:
qr = QRCodeImage(place_code, size=25 * mm) qr = QRCodeImage(place_code, size=20 * mm)
qr.drawOn(canvas, 34 * mm, -4) qr.drawOn(canvas, 39 * mm, -2 * mm)
number_paragraph = Paragraph(str(place_code), self._get_paragraph_style(34)) font_size = self._get_big_font_size_from_str(place_code)
number_paragraph = Paragraph(str(place_code), self._get_paragraph_style(font_size))
number_frame = Frame(x1=0 * mm, y1=9 * mm, width=60 * mm, height=30 * mm) number_frame = Frame(x1=0 * mm, y1=9 * mm, width=60 * mm, height=30 * mm)
denco_frame = Frame(x1=0 * mm, y1=-13 * mm, width=58 * mm, height=20 * mm) renderPDF.draw(drawing, canvas, 67, 3)
number_frame.addFromList([number_paragraph], canvas) number_frame.addFromList([number_paragraph], canvas)
denco_frame.addFromList([denco_paragraph], canvas)
empty_paragraph = Paragraph("", self.small_centered_style) empty_paragraph = Paragraph("", self.small_centered_style)
elements = [empty_paragraph] elements = [empty_paragraph]

View File

@@ -38,4 +38,5 @@ weasyprint
number_to_string number_to_string
pdfrw pdfrw
fpdf fpdf
PyMuPDF PyMuPDF
svglib

1
static/icons/denco.svg Normal file
View File

@@ -0,0 +1 @@
<svg id="Слой_1" data-name="Слой 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 791.06 146.29"><path d="M153.64,36a65.78,65.78,0,0,0-27.48-24.75Q108.48,2.43,85.45,2.43H21.19v36.2H53.93V29.3h29.9q21.21,0,33.84,11.82t12.63,32q0,20.2-12.63,32T83.83,117H53.93V105.13H21.19v38.74H85.45q23,0,40.71-8.79a65.78,65.78,0,0,0,27.48-24.75q9.8-16,9.8-37.18T153.64,36Z"/><path d="M220.62,117.6V84.87h65.67V59.41H220.62V28.7H295V2.43H188.09V143.87H297.6V117.6Z"/><path d="M421.06,2.43V88.3L350.74,2.43H323.67V143.87H356V58l70.51,85.88h26.88V2.43Z"/><path d="M556.44,118.41A47.21,47.21,0,0,1,533,112.65a40.87,40.87,0,0,1-16.06-16.06,47.21,47.21,0,0,1-5.76-23.44,47.21,47.21,0,0,1,5.76-23.44A40.87,40.87,0,0,1,533,33.65a47.21,47.21,0,0,1,23.44-5.76q21.21,0,35.56,16.57l21-19.4a66.55,66.55,0,0,0-25-18.59A82.44,82.44,0,0,0,554.82,0Q533,0,515.52,9.4A70.08,70.08,0,0,0,488,35.47q-10,16.67-10,37.68t10,37.68a70.15,70.15,0,0,0,27.48,26.07q17.47,9.39,39.1,9.39A83.2,83.2,0,0,0,588,139.83,65.49,65.49,0,0,0,613,121l-21-19.4Q577.65,118.41,556.44,118.41Z"/><path d="M732.75,105.13a41.07,41.07,0,0,1-9.62,7.52,47.33,47.33,0,0,1-45.26,0A41.29,41.29,0,0,1,662,96.59a47.21,47.21,0,0,1-5.76-23.44A47.21,47.21,0,0,1,662,49.71a41.29,41.29,0,0,1,15.86-16.06,47.33,47.33,0,0,1,45.26,0,40.89,40.89,0,0,1,7,5h39.35c-.53-1-1.09-2-1.68-3A71.4,71.4,0,0,0,740.1,9.5Q722.54,0,700.5,0T660.8,9.5a70.36,70.36,0,0,0-27.68,26.17,71.42,71.42,0,0,0-10,37.48,71.42,71.42,0,0,0,10,37.48A70.43,70.43,0,0,0,660.8,136.8q17.67,9.49,39.7,9.49t39.6-9.49a71.47,71.47,0,0,0,27.69-26.17c1.09-1.8,2.08-3.63,3-5.5Z"/><rect x="715.07" y="45.63" width="75.99" height="52.5"/><rect y="45.63" width="75.98" height="52.5"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB