Implement print labels module with PDF generation, QZ Tray integration, and theme support
- Migrate print_labels.html and print_lost_labels.html to standalone pages with header and theme toggle - Implement dark/light theme support using data-theme attribute and CSS variables - Add PDF generation endpoints for single and batch label printing - Copy pdf_generator.py from original app with full label formatting (80mm x 105mm) - Fix data response handling to correctly access data.orders from API endpoints - Synchronize table text sizes across both print pages - Remove help buttons from print pages - Database column rename: data_livrara → data_livrare for consistency - Update routes to use correct database column names - Add 7 test orders to database (4 unprinted, 3 printed) - Implement QZ Tray integration with PDF fallback for label printing - All CSS uses theme variables for dark/light mode synchronization
This commit is contained in:
@@ -5,6 +5,7 @@ Handles label printing pages and API endpoints
|
||||
from flask import Blueprint, render_template, session, redirect, url_for, jsonify, request
|
||||
import logging
|
||||
|
||||
from app.database import get_db
|
||||
from .print_module import (
|
||||
get_unprinted_orders_data,
|
||||
get_printed_orders_data,
|
||||
@@ -35,6 +36,15 @@ def print_module():
|
||||
return render_template('modules/labels/print_module.html')
|
||||
|
||||
|
||||
@labels_bp.route('/print-labels', methods=['GET'])
|
||||
def print_labels():
|
||||
"""Original print labels interface - complete copy from quality app"""
|
||||
if 'user_id' not in session:
|
||||
return redirect(url_for('main.login'))
|
||||
|
||||
return render_template('modules/labels/print_labels.html')
|
||||
|
||||
|
||||
@labels_bp.route('/print-lost-labels', methods=['GET'])
|
||||
def print_lost_labels():
|
||||
"""Print lost/missing labels interface"""
|
||||
@@ -74,6 +84,28 @@ def help(page='index'):
|
||||
</ol>
|
||||
'''
|
||||
},
|
||||
'print_labels': {
|
||||
'title': 'Print Labels Help',
|
||||
'content': '''
|
||||
<h3>Print Labels - Thermal Printer Guide</h3>
|
||||
<p>This module helps you print labels directly to thermal printers.</p>
|
||||
<h4>Features:</h4>
|
||||
<ul>
|
||||
<li>Live label preview in thermal format</li>
|
||||
<li>Real-time printer selection</li>
|
||||
<li>Barcode generation</li>
|
||||
<li>PDF export fallback</li>
|
||||
<li>Batch printing support</li>
|
||||
</ul>
|
||||
<h4>How to use:</h4>
|
||||
<ol>
|
||||
<li>Select orders from the list</li>
|
||||
<li>Preview labels in the preview pane</li>
|
||||
<li>Select your printer</li>
|
||||
<li>Click "Print Labels" to send to printer</li>
|
||||
</ol>
|
||||
'''
|
||||
},
|
||||
'print_lost_labels': {
|
||||
'title': 'Print Lost Labels Help',
|
||||
'content': '''
|
||||
@@ -198,3 +230,110 @@ def api_update_printed_status(order_id):
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating order status: {e}")
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@labels_bp.route('/api/generate-pdf', methods=['POST'], endpoint='api_generate_pdf')
|
||||
def api_generate_pdf():
|
||||
"""Generate single label PDF for thermal printing via QZ Tray"""
|
||||
if 'user_id' not in session:
|
||||
return jsonify({'error': 'Unauthorized'}), 401
|
||||
|
||||
try:
|
||||
from .pdf_generator import LabelPDFGenerator
|
||||
|
||||
# Get order data from request
|
||||
order_data = request.get_json()
|
||||
|
||||
if not order_data:
|
||||
return jsonify({'error': 'No order data provided'}), 400
|
||||
|
||||
# Extract piece number and total pieces for sequential numbering
|
||||
piece_number = order_data.get('piece_number', 1)
|
||||
total_pieces = order_data.get('total_pieces', 1)
|
||||
|
||||
logger.info(f"Generating single label PDF for piece {piece_number} of {total_pieces}")
|
||||
|
||||
# Initialize PDF generator in thermal printer optimized mode
|
||||
pdf_generator = LabelPDFGenerator(paper_saving_mode=True)
|
||||
|
||||
# Generate single label PDF with specific piece number for sequential CP numbering
|
||||
pdf_buffer = pdf_generator.generate_single_label_pdf(order_data, piece_number, total_pieces, printer_optimized=True)
|
||||
|
||||
# Create response with PDF data
|
||||
from flask import make_response
|
||||
response = make_response(pdf_buffer.getvalue())
|
||||
response.headers['Content-Type'] = 'application/pdf'
|
||||
response.headers['Content-Disposition'] = f'inline; filename="label_{piece_number:03d}.pdf"'
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating PDF: {e}")
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@labels_bp.route('/api/generate-pdf/<int:order_id>/true', methods=['POST'], endpoint='api_generate_batch_pdf')
|
||||
def api_generate_batch_pdf(order_id):
|
||||
"""Generate all label PDFs for an order and mark as printed"""
|
||||
if 'user_id' not in session:
|
||||
return jsonify({'error': 'Unauthorized'}), 401
|
||||
|
||||
try:
|
||||
from .pdf_generator import LabelPDFGenerator
|
||||
|
||||
# Get order data from database
|
||||
conn = get_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("""
|
||||
SELECT id, comanda_productie, cod_articol, descr_com_prod, cantitate,
|
||||
com_achiz_client, nr_linie_com_client, customer_name,
|
||||
customer_article_number, open_for_order, line_number,
|
||||
created_at, updated_at, printed_labels, data_livrare, dimensiune
|
||||
FROM order_for_labels
|
||||
WHERE id = %s
|
||||
""", (order_id,))
|
||||
|
||||
row = cursor.fetchone()
|
||||
|
||||
if not row:
|
||||
cursor.close()
|
||||
return jsonify({'error': 'Order not found'}), 404
|
||||
|
||||
# Create order data dictionary
|
||||
columns = [col[0] for col in cursor.description]
|
||||
order_data = {columns[i]: row[i] for i in range(len(columns))}
|
||||
|
||||
# Ensure date fields are strings
|
||||
if order_data.get('data_livrare'):
|
||||
order_data['data_livrare'] = str(order_data['data_livrare'])
|
||||
|
||||
cursor.close()
|
||||
|
||||
logger.info(f"Generating batch PDF for order {order_id} with {order_data.get('cantitate', 0)} labels")
|
||||
|
||||
# Initialize PDF generator
|
||||
pdf_generator = LabelPDFGenerator(paper_saving_mode=True)
|
||||
|
||||
# Get quantity from order data
|
||||
quantity = int(order_data.get('cantitate', 1))
|
||||
|
||||
# Generate PDF with all labels
|
||||
pdf_buffer = pdf_generator.generate_labels_pdf(order_data, quantity, printer_optimized=True)
|
||||
|
||||
# Mark order as printed
|
||||
success = update_order_printed_status(order_id, True)
|
||||
if not success:
|
||||
logger.warning(f"Failed to mark order {order_id} as printed, but PDF was generated")
|
||||
|
||||
# Create response with PDF data
|
||||
from flask import make_response
|
||||
response = make_response(pdf_buffer.getvalue())
|
||||
response.headers['Content-Type'] = 'application/pdf'
|
||||
response.headers['Content-Disposition'] = f'attachment; filename="labels_{order_data.get("comanda_productie", "unknown")}.pdf"'
|
||||
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating batch PDF: {e}")
|
||||
return jsonify({'error': str(e)}), 500
|
||||
Reference in New Issue
Block a user