Implement professional PDF-based label printing for boxes and locations
- Replace ZPL/image-based printing with ReportLab PDF generation - Box labels: 8cm x 5cm landscape with 'BOX Nr:' header and CODE128 barcode - Location labels: 8cm x 5cm landscape with 'Location nr:' header and CODE128 barcode - Add /generate_box_label_pdf endpoint using same approach as print_module - Update FG scan quick box creation to use PDF printing with default printer - Switch from CDN QZ Tray to local patched version for pairing-key auth - Improve error handling and logging throughout printing workflow - Fix import issues (add mm unit to warehouse.py) - Optimize barcode size and spacing for better readability
This commit is contained in:
@@ -3,7 +3,7 @@ from flask import current_app, request, render_template, session, redirect, url_
|
||||
import csv, os, tempfile
|
||||
from reportlab.lib.pagesizes import letter
|
||||
from reportlab.pdfgen import canvas
|
||||
from reportlab.lib.units import cm
|
||||
from reportlab.lib.units import cm, mm
|
||||
from reportlab.graphics.barcode import code128
|
||||
import io
|
||||
|
||||
@@ -255,7 +255,7 @@ def import_locations_csv_handler():
|
||||
return render_template('import_locations_csv.html', report=report, locations=locations)
|
||||
|
||||
def generate_location_label_pdf():
|
||||
"""Generate PDF for location barcode label (8x4cm)"""
|
||||
"""Generate PDF for location barcode label (8cm x 5cm landscape)"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
location_code = data.get('location_code', '')
|
||||
@@ -263,46 +263,93 @@ def generate_location_label_pdf():
|
||||
if not location_code:
|
||||
return jsonify({'error': 'Location code is required'}), 400
|
||||
|
||||
print(f"DEBUG: Generating location label PDF for: {location_code}")
|
||||
|
||||
# Create PDF in memory
|
||||
buffer = io.BytesIO()
|
||||
|
||||
# Create PDF with 8x4cm page size (width x height)
|
||||
page_width = 8 * cm
|
||||
page_height = 4 * cm
|
||||
# Create PDF with 8cm x 5cm page size in landscape orientation
|
||||
page_width = 80 * mm # 8 cm
|
||||
page_height = 50 * mm # 5 cm
|
||||
|
||||
c = canvas.Canvas(buffer, pagesize=(page_width, page_height))
|
||||
|
||||
# Generate Code128 barcode
|
||||
barcode = code128.Code128(location_code, barWidth=1.0, humanReadable=False)
|
||||
# Optimize for label printer
|
||||
c.setPageCompression(1)
|
||||
c.setCreator("Trasabilitate Location Label System")
|
||||
c.setTitle("Location Label - Optimized for Label Printers")
|
||||
|
||||
# Calculate the desired barcode dimensions (fill most of the label)
|
||||
desired_barcode_width = 7 * cm # Almost full width
|
||||
desired_barcode_height = 2.5 * cm # Most of the height
|
||||
# Define margins and usable area
|
||||
margin = 2 * mm
|
||||
usable_width = page_width - (2 * margin)
|
||||
usable_height = page_height - (2 * margin)
|
||||
|
||||
# Calculate scaling factor to fit the desired width
|
||||
scale = desired_barcode_width / barcode.width
|
||||
# Calculate vertical layout
|
||||
# Top section: "Location nr: XXXX" text
|
||||
# Bottom section: Barcode
|
||||
text_height = 12 * mm # Space for text at top
|
||||
barcode_height = usable_height - text_height - (1 * mm) # Rest for barcode with minimal spacing
|
||||
|
||||
# Calculate actual dimensions after scaling
|
||||
actual_width = barcode.width * scale
|
||||
actual_height = barcode.height * scale
|
||||
# === TOP SECTION: Location Nr Label ===
|
||||
# Position from top of usable area
|
||||
text_y = page_height - margin - text_height
|
||||
|
||||
# Center the barcode on the label
|
||||
barcode_x = (page_width - actual_width) / 2
|
||||
barcode_y = (page_height - actual_height) / 2 + 0.3 * cm # Slightly above center for text space
|
||||
# Draw "Location nr:" label
|
||||
c.setFont("Helvetica-Bold", 14)
|
||||
label_text = "Location nr:"
|
||||
label_width = c.stringWidth(label_text, "Helvetica-Bold", 14)
|
||||
|
||||
# Draw barcode with scaling
|
||||
c.saveState()
|
||||
c.translate(barcode_x, barcode_y)
|
||||
c.scale(scale, scale)
|
||||
barcode.drawOn(c, 0, 0)
|
||||
c.restoreState()
|
||||
# Draw location code
|
||||
c.setFont("Helvetica-Bold", 18)
|
||||
code_text = location_code
|
||||
code_width = c.stringWidth(code_text, "Helvetica-Bold", 18)
|
||||
|
||||
# Add location code text below barcode
|
||||
c.setFont("Helvetica-Bold", 10)
|
||||
text_width = c.stringWidth(location_code, "Helvetica-Bold", 10)
|
||||
text_x = (page_width - text_width) / 2
|
||||
text_y = barcode_y - 0.5 * cm # Below the barcode
|
||||
c.drawString(text_x, text_y, location_code)
|
||||
# Calculate total width and center everything
|
||||
total_text_width = label_width + 3*mm + code_width # 3mm spacing between label and code
|
||||
start_x = margin + (usable_width - total_text_width) / 2
|
||||
|
||||
# Draw label text
|
||||
c.setFont("Helvetica-Bold", 14)
|
||||
c.drawString(start_x, text_y + 5*mm, label_text)
|
||||
|
||||
# Draw location code
|
||||
c.setFont("Helvetica-Bold", 18)
|
||||
c.drawString(start_x + label_width + 3*mm, text_y + 5*mm, code_text)
|
||||
|
||||
# === BOTTOM SECTION: Barcode ===
|
||||
barcode_y = margin
|
||||
|
||||
try:
|
||||
# Create barcode for location code
|
||||
barcode = code128.Code128(
|
||||
location_code,
|
||||
barWidth=0.4*mm, # Thicker bars for better scanning
|
||||
barHeight=barcode_height,
|
||||
humanReadable=True,
|
||||
fontSize=10
|
||||
)
|
||||
|
||||
# Calculate scaling to fit width
|
||||
scale_factor = usable_width / barcode.width
|
||||
|
||||
# Center the barcode horizontally
|
||||
barcode_x = margin + (usable_width - (barcode.width * scale_factor)) / 2
|
||||
|
||||
# Draw the barcode
|
||||
c.saveState()
|
||||
c.translate(barcode_x, barcode_y)
|
||||
c.scale(scale_factor, 1)
|
||||
barcode.drawOn(c, 0, 0)
|
||||
c.restoreState()
|
||||
|
||||
print(f"DEBUG: Barcode generated successfully with scale factor: {scale_factor}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"DEBUG: Error generating barcode: {e}")
|
||||
# Fallback: draw text if barcode fails
|
||||
c.setFont("Helvetica-Bold", 12)
|
||||
text_width = c.stringWidth(location_code, "Helvetica-Bold", 12)
|
||||
c.drawString((page_width - text_width) / 2, barcode_y + barcode_height/2, location_code)
|
||||
|
||||
# Finalize PDF
|
||||
c.save()
|
||||
@@ -313,10 +360,13 @@ def generate_location_label_pdf():
|
||||
response.headers['Content-Type'] = 'application/pdf'
|
||||
response.headers['Content-Disposition'] = f'inline; filename=location_{location_code}_label.pdf'
|
||||
|
||||
print(f"DEBUG: Location label PDF generated successfully")
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error generating location label PDF: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
def update_location(location_id, location_code, size, description):
|
||||
|
||||
Reference in New Issue
Block a user