feat: spacers between barcodes of diff products, avoid product cut in deal document, deal document refactoring
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
from io import BytesIO
|
||||
from typing import List, Dict
|
||||
|
||||
from barcodes.attributes import AttributeWriterFactory
|
||||
@@ -8,7 +9,7 @@ from schemas.barcode import PdfBarcodeGenData
|
||||
|
||||
|
||||
class DefaultBarcodeGenerator(BaseBarcodeGenerator):
|
||||
def generate(self, barcodes_data: List[Dict[str, str | Product | BarcodeTemplate | int]]):
|
||||
def generate(self, barcodes_data: List[Dict[str, str | Product | BarcodeTemplate | int]]) -> BytesIO:
|
||||
pdf_generator = PDFGenerator()
|
||||
|
||||
pdf_barcodes_gen_data: List[PdfBarcodeGenData] = []
|
||||
@@ -35,6 +36,4 @@ class DefaultBarcodeGenerator(BaseBarcodeGenerator):
|
||||
)
|
||||
)
|
||||
|
||||
print(f"value = {barcode_data['barcode']}, text = {barcode_text}, num = {barcode_data['quantity']}")
|
||||
|
||||
return pdf_generator.generate(pdf_barcodes_gen_data)
|
||||
|
||||
@@ -20,6 +20,7 @@ class PDFGenerator:
|
||||
FONT_FILE_PATH = os.path.join(FONTS_FOLDER, 'DejaVuSans.ttf')
|
||||
self.page_width = 58 * mm
|
||||
self.page_height = 40 * mm
|
||||
self.number_of_spacing_pages = 2
|
||||
|
||||
pdfmetrics.registerFont(TTFont('DejaVuSans', FONT_FILE_PATH))
|
||||
|
||||
@@ -40,12 +41,14 @@ class PDFGenerator:
|
||||
buffer = BytesIO()
|
||||
|
||||
# Create document with specified page size
|
||||
doc = SimpleDocTemplate(buffer,
|
||||
pagesize=(self.page_width, self.page_height),
|
||||
rightMargin=1 * mm,
|
||||
leftMargin=1 * mm,
|
||||
topMargin=1 * mm,
|
||||
bottomMargin=1 * mm)
|
||||
doc = SimpleDocTemplate(
|
||||
buffer,
|
||||
pagesize=(self.page_width, self.page_height),
|
||||
rightMargin=1 * mm,
|
||||
leftMargin=1 * mm,
|
||||
topMargin=1 * mm,
|
||||
bottomMargin=1 * mm
|
||||
)
|
||||
|
||||
# Create paragraph with new style
|
||||
paragraph = Paragraph(text, self.small_style)
|
||||
@@ -61,10 +64,12 @@ class PDFGenerator:
|
||||
|
||||
# Calculate barWidth
|
||||
bar_width = available_width / num_elements
|
||||
barcode = code128.Code128(barcode_value,
|
||||
barWidth=bar_width,
|
||||
barHeight=barcode_height,
|
||||
humanReadable=True)
|
||||
barcode = code128.Code128(
|
||||
barcode_value,
|
||||
barWidth=bar_width,
|
||||
barHeight=barcode_height,
|
||||
humanReadable=True
|
||||
)
|
||||
|
||||
# Function to draw barcode on canvas
|
||||
def add_barcode(canvas, doc):
|
||||
@@ -85,22 +90,26 @@ class PDFGenerator:
|
||||
buffer.seek(0)
|
||||
return buffer
|
||||
|
||||
def generate(self, barcodes_data: List[PdfBarcodeGenData]):
|
||||
# Создание документа с указанным размером страницы
|
||||
def _create_doc(self, buffer):
|
||||
return SimpleDocTemplate(
|
||||
buffer,
|
||||
pagesize=(self.page_width, self.page_height),
|
||||
rightMargin=1 * mm,
|
||||
leftMargin=1 * mm,
|
||||
topMargin=1 * mm,
|
||||
bottomMargin=1 * mm
|
||||
)
|
||||
|
||||
def generate(self, barcodes_data: List[PdfBarcodeGenData]) -> BytesIO:
|
||||
buffer = BytesIO()
|
||||
|
||||
# Создаем документ с указанным размером страницы
|
||||
doc = SimpleDocTemplate(buffer,
|
||||
pagesize=(self.page_width, self.page_height),
|
||||
rightMargin=1 * mm,
|
||||
leftMargin=1 * mm,
|
||||
topMargin=1 * mm,
|
||||
bottomMargin=1 * mm)
|
||||
doc = self._create_doc(buffer)
|
||||
|
||||
# Список элементов для добавления в документ
|
||||
elements = []
|
||||
product_barcode_canvases = []
|
||||
product_counter = 0
|
||||
product_barcodes_counter = 0
|
||||
|
||||
for barcode_data in barcodes_data:
|
||||
# Создаем абзац с новым стилем
|
||||
@@ -122,10 +131,12 @@ class PDFGenerator:
|
||||
|
||||
# Рассчитываем ширину штриха
|
||||
bar_width = available_width / num_elements
|
||||
barcode = code128.Code128(barcode_data.barcode_value,
|
||||
barWidth=bar_width,
|
||||
barHeight=barcode_height,
|
||||
humanReadable=True)
|
||||
barcode = code128.Code128(
|
||||
barcode_data.barcode_value,
|
||||
barWidth=bar_width,
|
||||
barHeight=barcode_height,
|
||||
humanReadable=True
|
||||
)
|
||||
product_barcode_canvases.append(barcode)
|
||||
|
||||
# Добавление штрихкодов в список элементов документа
|
||||
@@ -134,24 +145,39 @@ class PDFGenerator:
|
||||
elements.append(Spacer(1, space_between_text_and_barcode)) # Отступ между текстом и штрихкодом
|
||||
elements.append(PageBreak())
|
||||
|
||||
# Добавление спейсеров
|
||||
for _ in range(self.number_of_spacing_pages):
|
||||
elements.append(PageBreak())
|
||||
|
||||
# Удалить последние спейсеры
|
||||
elements = elements[:-2]
|
||||
|
||||
product_counter, product_barcodes_counter = 0, 0
|
||||
|
||||
# Функция для отрисовки штрихкода на canvas
|
||||
def add_barcode(canvas, doc):
|
||||
nonlocal product_barcodes_counter, product_counter
|
||||
|
||||
barcode_canvas = product_barcode_canvases[product_counter]
|
||||
|
||||
product_barcodes_counter += 1
|
||||
|
||||
# Если данная страница это спейсер, то оставить пустой
|
||||
num_duplicates = barcodes_data[product_counter].num_duplicates
|
||||
if product_barcodes_counter > num_duplicates:
|
||||
if product_barcodes_counter >= num_duplicates + self.number_of_spacing_pages:
|
||||
product_barcodes_counter = 0
|
||||
product_counter += 1
|
||||
return
|
||||
|
||||
# Отрисовка штрихкода
|
||||
barcode_width = barcode_canvas.width
|
||||
barcode_x = (self.page_width - barcode_width) / 2 # Центрируем штрихкод
|
||||
barcode_y = human_readable_height + 2 * mm # Размещаем штрихкод снизу с учетом отступа
|
||||
barcode_canvas.drawOn(canvas, barcode_x, barcode_y)
|
||||
|
||||
product_barcodes_counter += 1
|
||||
if product_barcodes_counter >= barcodes_data[product_counter].num_duplicates:
|
||||
product_barcodes_counter = 0
|
||||
product_counter += 1
|
||||
|
||||
# Создаем документ
|
||||
doc.build(elements[:-1], onFirstPage=add_barcode, onLaterPages=add_barcode) # Убираем последний PageBreak
|
||||
|
||||
buffer.seek(0)
|
||||
return buffer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user