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:
189
documentation/PRINTING_MODULE_REFERENCE.md
Normal file
189
documentation/PRINTING_MODULE_REFERENCE.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Old Quality App - Printing Module Summary
|
||||
|
||||
## Key Files
|
||||
|
||||
### 1. `/srv/quality_app/py_app/app/pdf_generator.py`
|
||||
**Main PDF Generation Engine**
|
||||
|
||||
The `LabelPDFGenerator` class handles all label PDF generation:
|
||||
- **Dimensions**: 80mm x 105mm thermal printer labels
|
||||
- **Optimized for**: Epson TM-T20, Citizen CTS-310 thermal printers
|
||||
|
||||
#### Key Methods:
|
||||
|
||||
##### `generate_labels_pdf(order_data, quantity, printer_optimized=True)`
|
||||
- Generates PDF with multiple labels based on quantity
|
||||
- Creates sequential labels: CP00000711-001, CP00000711-002, etc.
|
||||
- Returns BytesIO buffer with complete PDF
|
||||
|
||||
##### `generate_single_label_pdf(order_data, piece_number, total_pieces, printer_optimized=True)`
|
||||
- Generates single label PDF for specific piece number
|
||||
- Used by QZ Tray for direct thermal printing
|
||||
- Returns BytesIO buffer with one label
|
||||
|
||||
##### `_draw_label(canvas, order_data, sequential_number, current_num, total_qty)`
|
||||
**Label Layout:**
|
||||
- **Row 1**: Company header (empty)
|
||||
- **Row 2**: Customer name
|
||||
- **Row 3**: Quantity ordered (left) | Right column split 40/60
|
||||
- **Row 4**: Customer order (com_achiz_client - nr_linie_com_client)
|
||||
- **Row 5**: Delivery date (data_livrare)
|
||||
- **Row 6**: Product description (double height)
|
||||
- **Row 7**: Size (dimensiune)
|
||||
- **Row 8**: Article code (customer_article_number)
|
||||
- **Row 9**: Production order (comanda_productie - sequential_number)
|
||||
|
||||
**Barcodes:**
|
||||
- **Bottom**: CODE128 barcode with sequential number (CP00000711/001)
|
||||
- **Right side**: CODE128 vertical barcode with customer order format
|
||||
|
||||
##### `_optimize_for_label_printer(canvas)`
|
||||
- Sets 300 DPI resolution
|
||||
- Enables compression
|
||||
- Sets print scaling to 100% (no scaling)
|
||||
- Adds PDF metadata for printer optimization
|
||||
|
||||
---
|
||||
|
||||
### 2. `/srv/quality_app/py_app/app/print_module.py`
|
||||
**Database Data Retrieval**
|
||||
|
||||
#### Key Functions:
|
||||
|
||||
##### `get_unprinted_orders_data(limit=100)`
|
||||
- Returns orders where `printed_labels != 1`
|
||||
- Retrieves all fields needed for label generation
|
||||
- Returns list of order dictionaries
|
||||
|
||||
##### `get_printed_orders_data(limit=100)`
|
||||
- Returns orders where `printed_labels = 1`
|
||||
- Used for "print lost labels" page
|
||||
- Returns list of order dictionaries
|
||||
|
||||
##### `update_order_printed_status(order_id)`
|
||||
- Updates `printed_labels = 1` for order
|
||||
- Called after successful printing
|
||||
|
||||
---
|
||||
|
||||
### 3. API Routes in `/srv/quality_app/py_app/app/routes.py`
|
||||
|
||||
#### `/generate_label_pdf` (POST)
|
||||
**Single Label Generation for QZ Tray**
|
||||
```python
|
||||
Accepts JSON:
|
||||
{
|
||||
"comanda_productie": "CP00000711",
|
||||
"cantitate": 5,
|
||||
"piece_number": 1,
|
||||
"total_pieces": 5,
|
||||
... (other order fields)
|
||||
}
|
||||
|
||||
Returns: PDF binary data
|
||||
Purpose: Generate single label for thermal printer via QZ Tray
|
||||
```
|
||||
|
||||
#### `/generate_labels_pdf/<order_id>/true` (POST)
|
||||
**Batch Label Generation for PDF Download**
|
||||
```
|
||||
Returns: Multi-page PDF with all labels for order
|
||||
Purpose: Generate all labels for download/preview
|
||||
Also marks order as printed (printed_labels = 1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. `/srv/quality_app/py_app/app/print_config.py`
|
||||
**Print Service Configuration**
|
||||
|
||||
```python
|
||||
WINDOWS_PRINT_SERVICE_URL = "http://192.168.1.XXX:8765"
|
||||
PRINT_SERVICE_TIMEOUT = 30
|
||||
PRINT_SERVICE_ENABLED = True
|
||||
```
|
||||
|
||||
Note: Windows print service is configured but QZ Tray is the primary method.
|
||||
|
||||
---
|
||||
|
||||
## Label Printing Flow
|
||||
|
||||
### For Direct Printing (QZ Tray):
|
||||
1. User selects order from table
|
||||
2. Clicks "Print Labels" button
|
||||
3. Frontend calls `/labels/api/generate-pdf` with order data and piece_number
|
||||
4. Backend's `LabelPDFGenerator.generate_single_label_pdf()` creates PDF
|
||||
5. Returns PDF binary to frontend
|
||||
6. QZ Tray prints directly to thermal printer
|
||||
7. After successful print, calls `/labels/api/update-printed-status/{id}`
|
||||
|
||||
### For PDF Download:
|
||||
1. User selects order
|
||||
2. Clicks "Generate PDF" button
|
||||
3. Frontend calls `/labels/api/generate-pdf/{orderId}/true`
|
||||
4. Backend's `LabelPDFGenerator.generate_labels_pdf()` creates multi-page PDF
|
||||
5. Returns PDF for browser download/print
|
||||
6. Order marked as printed
|
||||
|
||||
---
|
||||
|
||||
## Key Configuration Classes
|
||||
|
||||
### `LabelPDFGenerator` Parameters:
|
||||
```python
|
||||
# Label dimensions
|
||||
label_width = 80mm
|
||||
label_height = 105mm
|
||||
|
||||
# Content area
|
||||
content_width = 60mm
|
||||
content_height = 68mm
|
||||
content_x = 4mm from left
|
||||
content_y = 22mm from bottom
|
||||
|
||||
# Layout
|
||||
row_height = 6.8mm (content_height / 10)
|
||||
left_column_width = 40% (24mm)
|
||||
right_column_width = 60% (36mm)
|
||||
|
||||
# Barcode areas
|
||||
bottom_barcode: 80mm width x 12mm height
|
||||
vertical_barcode: 12mm width x 68mm height (rotated 90°)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Order Data Fields Used
|
||||
|
||||
```python
|
||||
Required fields for label generation:
|
||||
- comanda_productie: Production order number
|
||||
- cod_articol: Article code
|
||||
- descr_com_prod: Product description
|
||||
- cantitate: Quantity
|
||||
- com_achiz_client: Customer purchase order
|
||||
- nr_linie_com_client: Customer order line
|
||||
- customer_name: Customer name
|
||||
- customer_article_number: Customer article number
|
||||
- data_livrare: Delivery date
|
||||
- dimensiune: Product size
|
||||
- printed_labels: Status (0 = unprinted, 1 = printed)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Thermal Printer Optimization
|
||||
|
||||
The PDF generator is specifically optimized for thermal label printers:
|
||||
|
||||
1. **No margins**: Fills entire label area
|
||||
2. **High resolution**: 300 DPI quality
|
||||
3. **Monochrome**: Black/white only (no colors)
|
||||
4. **Compression**: Reduces file size
|
||||
5. **Scaling**: 100% (no scaling in printer)
|
||||
6. **Bar width**: Optimized for thermal resolution
|
||||
|
||||
Tested with:
|
||||
- Epson TM-T20 (80mm thermal printer)
|
||||
- Citizen CTS-310 (80mm thermal printer)
|
||||
Reference in New Issue
Block a user