This commit is contained in:
2025-09-26 21:56:06 +03:00
parent c17812a0c1
commit 2216f21c47
17 changed files with 3361 additions and 631 deletions

View File

@@ -23,20 +23,31 @@ def mm_to_points(mm_value):
class LabelPDFGenerator:
def __init__(self):
def __init__(self, paper_saving_mode=True):
# Label dimensions: 80mm x 110mm
self.label_width = mm_to_points(80)
self.label_height = mm_to_points(110)
# Paper-saving mode: positions content at top of label to minimize waste
self.paper_saving_mode = paper_saving_mode
# Match the HTML preview dimensions exactly
# Preview: 227.4px width x 321.3px height
# Convert to proportional dimensions for 80x110mm
self.content_width = mm_to_points(60) # ~227px scaled to 80mm
self.content_height = mm_to_points(85) # ~321px scaled to 110mm
# Position content in label, leaving space for barcodes
self.content_x = mm_to_points(3) # 3mm from left edge
self.content_y = mm_to_points(15) # 15mm from bottom (space for bottom barcode)
# Position content in label - optimized for paper saving
if self.paper_saving_mode:
# Start content from top of label with minimal top margin
self.content_x = mm_to_points(2) # 2mm from left edge (was 3mm)
self.content_y = mm_to_points(20) # 20mm from bottom (more space at top)
self.top_margin = mm_to_points(5) # 5mm top margin instead of larger bottom margin
else:
# Original positioning
self.content_x = mm_to_points(3) # 3mm from left edge
self.content_y = mm_to_points(15) # 15mm from bottom (space for bottom barcode)
self.top_margin = mm_to_points(10)
# Row dimensions (9 rows total, row 6 is double height)
self.row_height = self.content_height / 10 # 8.5mm per standard row
@@ -49,16 +60,21 @@ class LabelPDFGenerator:
# Vertical divider starts from row 3
self.vertical_divider_start_y = self.content_y + self.content_height - (2 * self.row_height)
def generate_labels_pdf(self, order_data, quantity):
def generate_labels_pdf(self, order_data, quantity, printer_optimized=True):
"""
Generate PDF with multiple labels based on quantity
Creates sequential labels: CP00000711-001 to CP00000711-XXX
Optimized for thermal label printers (Epson TM-T20, Citizen CTS-310)
"""
buffer = io.BytesIO()
# Create canvas with label dimensions
c = canvas.Canvas(buffer, pagesize=(self.label_width, self.label_height))
# Optimize PDF for label printers
if printer_optimized:
self._optimize_for_label_printer(c)
# Extract base production order number for sequential numbering
prod_order = order_data.get('comanda_productie', 'CP00000000')
@@ -66,6 +82,8 @@ class LabelPDFGenerator:
for i in range(1, quantity + 1):
if i > 1: # Add new page for each label except first
c.showPage()
if printer_optimized:
self._optimize_for_label_printer(c)
# Create sequential label number: CP00000711-001, CP00000711-002, etc.
sequential_number = f"{prod_order}-{i:03d}"
@@ -77,6 +95,27 @@ class LabelPDFGenerator:
buffer.seek(0)
return buffer
def _optimize_for_label_printer(self, canvas):
"""
Optimize PDF settings for thermal label printers
- Sets high resolution for crisp text
- Minimizes margins to save paper
- Optimizes for monochrome printing
"""
# Set high resolution for thermal printers (300 DPI)
canvas.setPageCompression(1) # Enable compression
# Add PDF metadata for printer optimization
canvas.setCreator("Recticel Label System")
canvas.setTitle("Thermal Label - Optimized for Label Printers")
canvas.setSubject("Production Label")
# Set print scaling to none (100%) to maintain exact dimensions
canvas.setPageRotation(0)
# Add custom PDF properties for label printers
canvas._doc.info.producer = "Optimized for Epson TM-T20 / Citizen CTS-310"
def _draw_label(self, canvas, order_data, sequential_number, current_num, total_qty):
"""Draw a single label matching the HTML preview layout exactly"""
@@ -316,18 +355,24 @@ class LabelPDFGenerator:
canvas.rect(vertical_barcode_x, y_pos, mm_to_points(8), bar_height * 0.8, fill=1)
def generate_order_labels_pdf(order_id, order_data):
def generate_order_labels_pdf(order_id, order_data, paper_saving_mode=True):
"""
Main function to generate PDF for an order with multiple labels
Optimized for thermal label printers (Epson TM-T20, Citizen CTS-310)
Args:
order_id: Order identifier
order_data: Order information dictionary
paper_saving_mode: If True, positions content at top to save paper
"""
try:
generator = LabelPDFGenerator()
generator = LabelPDFGenerator(paper_saving_mode=paper_saving_mode)
# Get quantity from order data
quantity = int(order_data.get('cantitate', 1))
# Generate PDF
pdf_buffer = generator.generate_labels_pdf(order_data, quantity)
# Generate PDF with printer optimization
pdf_buffer = generator.generate_labels_pdf(order_data, quantity, printer_optimized=True)
return pdf_buffer