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:
182
documentation/PDF_GENERATION_IMPLEMENTATION_PLAN.md
Normal file
182
documentation/PDF_GENERATION_IMPLEMENTATION_PLAN.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Implementation Plan: PDF Generation for Print Functionality
|
||||
|
||||
## Current Status
|
||||
|
||||
The new Quality App v2 has:
|
||||
✅ Labels module with routes and templates
|
||||
✅ print_labels.html and print_lost_labels.html with UI
|
||||
✅ Database schema (order_for_labels table)
|
||||
✅ API endpoints for fetching orders
|
||||
❌ PDF generation functionality (NEEDS IMPLEMENTATION)
|
||||
❌ `/labels/api/generate-pdf` endpoint
|
||||
❌ `/labels/api/generate-pdf/{order_id}/true` endpoint
|
||||
|
||||
## What Needs to Be Done
|
||||
|
||||
### 1. Create PDF Generator Module
|
||||
**File**: `/srv/quality_app-v2/app/modules/labels/pdf_generator.py`
|
||||
|
||||
Copy from old app: `/srv/quality_app/py_app/app/pdf_generator.py`
|
||||
|
||||
Key classes:
|
||||
- `LabelPDFGenerator` - Main PDF generation class
|
||||
- Methods for single label and batch label generation
|
||||
|
||||
### 2. Create/Update Print Module Functions
|
||||
**File**: `/srv/quality_app-v2/app/modules/labels/print_module.py`
|
||||
|
||||
Add to existing functions:
|
||||
- `update_order_printed_status(order_id, status=1)` - Mark order as printed
|
||||
- Import PDF generator functions
|
||||
|
||||
### 3. Add API Endpoints to Routes
|
||||
**File**: `/srv/quality_app-v2/app/modules/labels/routes.py`
|
||||
|
||||
Add two new routes:
|
||||
|
||||
#### Endpoint 1: Single Label PDF (for QZ Tray)
|
||||
```python
|
||||
@labels_bp.route('/api/generate-pdf', methods=['POST'])
|
||||
def api_generate_pdf():
|
||||
"""Generate single label PDF for QZ Tray thermal printing"""
|
||||
# Accept JSON with:
|
||||
# - order_data: Complete order information
|
||||
# - piece_number: Which label number (1, 2, 3, etc.)
|
||||
# - total_pieces: Total quantity
|
||||
# Return: PDF binary data
|
||||
```
|
||||
|
||||
#### Endpoint 2: Batch PDF (for download)
|
||||
```python
|
||||
@labels_bp.route('/api/generate-pdf/<int:order_id>/true', methods=['POST'])
|
||||
def api_generate_batch_pdf(order_id):
|
||||
"""Generate all label PDFs for an order and mark as printed"""
|
||||
# Fetch order from database
|
||||
# Generate all labels in one PDF
|
||||
# Mark order as printed (printed_labels = 1)
|
||||
# Return: PDF binary data
|
||||
```
|
||||
|
||||
### 4. Install Required Dependencies
|
||||
|
||||
The new app needs these Python packages:
|
||||
```
|
||||
reportlab>=3.6.0 (for PDF generation)
|
||||
```
|
||||
|
||||
Check `/srv/quality_app-v2/requirements.txt` and add if needed.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Details from Old App
|
||||
|
||||
### LabelPDFGenerator Class Structure
|
||||
|
||||
```python
|
||||
class LabelPDFGenerator:
|
||||
def __init__(self, paper_saving_mode=True):
|
||||
self.label_width = 80mm
|
||||
self.label_height = 105mm
|
||||
# ... other dimensions
|
||||
|
||||
def generate_labels_pdf(self, order_data, quantity, printer_optimized=True):
|
||||
# Generate multiple labels (one per page)
|
||||
# Return BytesIO buffer
|
||||
|
||||
def generate_single_label_pdf(self, order_data, piece_number, total_pieces):
|
||||
# Generate one label for QZ Tray
|
||||
# Return BytesIO buffer
|
||||
|
||||
def _draw_label(self, canvas, order_data, sequential_number, current_num, total_qty):
|
||||
# Draw all label elements on canvas
|
||||
|
||||
def _optimize_for_label_printer(self, canvas):
|
||||
# Set printer optimization settings
|
||||
```
|
||||
|
||||
### Label Data Structure
|
||||
|
||||
```python
|
||||
order_data = {
|
||||
'id': int,
|
||||
'comanda_productie': str, # Production order (CP00000711)
|
||||
'cod_articol': str, # Article code
|
||||
'descr_com_prod': str, # Product description
|
||||
'cantitate': int, # Quantity (total labels)
|
||||
'com_achiz_client': str, # Customer PO
|
||||
'nr_linie_com_client': str,# Customer PO line
|
||||
'customer_name': str,
|
||||
'customer_article_number': str,
|
||||
'data_livrare': str/date, # Delivery date
|
||||
'dimensiune': str, # Product size
|
||||
'printed_labels': bool # Print status
|
||||
}
|
||||
```
|
||||
|
||||
### API Request/Response Format
|
||||
|
||||
#### Generate Single Label (QZ Tray)
|
||||
```
|
||||
POST /labels/api/generate-pdf
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"comanda_productie": "CP00000711",
|
||||
"cod_articol": "ART001",
|
||||
"descr_com_prod": "Product Description",
|
||||
"cantitate": 5,
|
||||
"com_achiz_client": "PO2026001",
|
||||
"nr_linie_com_client": "001",
|
||||
"customer_name": "ACME Corp",
|
||||
"customer_article_number": "ACME-001",
|
||||
"data_livrare": "2026-02-11",
|
||||
"dimensiune": "Standard",
|
||||
"piece_number": 1,
|
||||
"total_pieces": 5
|
||||
}
|
||||
|
||||
Response: Binary PDF data (Content-Type: application/pdf)
|
||||
```
|
||||
|
||||
#### Generate Batch PDF (Download)
|
||||
```
|
||||
POST /labels/api/generate-pdf/711/true
|
||||
|
||||
Response: Binary PDF data with all 5 labels
|
||||
Side effect: Sets order.printed_labels = 1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Files to Copy from Old App
|
||||
|
||||
1. **pdf_generator.py**
|
||||
- Source: `/srv/quality_app/py_app/app/pdf_generator.py`
|
||||
- Destination: `/srv/quality_app-v2/app/modules/labels/pdf_generator.py`
|
||||
- Status: READY TO COPY
|
||||
|
||||
2. **Requirements Update**
|
||||
- Add `reportlab>=3.6.0` to `/srv/quality_app-v2/requirements.txt`
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Copy pdf_generator.py from old app
|
||||
2. Update requirements.txt with reportlab
|
||||
3. Add two new API routes to routes.py
|
||||
4. Update print_module.py with update_order_printed_status function
|
||||
5. Test the endpoints with test data already inserted
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [ ] Single label generation works
|
||||
- [ ] Batch PDF generation works
|
||||
- [ ] QZ Tray can print generated labels
|
||||
- [ ] Order marked as printed after successful generation
|
||||
- [ ] PDF dimensions correct (80mm x 105mm)
|
||||
- [ ] Barcodes generate correctly
|
||||
- [ ] All order data displays correctly on label
|
||||
- [ ] Thermal printer optimization enabled
|
||||
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)
|
||||
219
documentation/insert_test_data.py
Normal file
219
documentation/insert_test_data.py
Normal file
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Insert test data into the order_for_labels table for testing print functionality
|
||||
"""
|
||||
import pymysql
|
||||
from datetime import datetime, timedelta
|
||||
import sys
|
||||
|
||||
# Database connection parameters
|
||||
DB_HOST = 'mariadb'
|
||||
DB_PORT = 3306
|
||||
DB_USER = 'quality_user'
|
||||
DB_PASSWORD = 'quality_secure_password_2026'
|
||||
DB_NAME = 'quality_db'
|
||||
|
||||
def insert_test_data():
|
||||
"""Insert test orders into the database"""
|
||||
|
||||
try:
|
||||
# Connect to database
|
||||
conn = pymysql.connect(
|
||||
host=DB_HOST,
|
||||
port=DB_PORT,
|
||||
user=DB_USER,
|
||||
password=DB_PASSWORD,
|
||||
database=DB_NAME,
|
||||
charset='utf8mb4'
|
||||
)
|
||||
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Check if table exists
|
||||
cursor.execute("SHOW TABLES LIKE 'order_for_labels'")
|
||||
if not cursor.fetchone():
|
||||
print("Error: order_for_labels table does not exist")
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return False
|
||||
|
||||
# Check if printed_labels column exists
|
||||
cursor.execute("SHOW COLUMNS FROM order_for_labels LIKE 'printed_labels'")
|
||||
if not cursor.fetchone():
|
||||
print("Error: printed_labels column does not exist")
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return False
|
||||
|
||||
# Sample test data
|
||||
today = datetime.now()
|
||||
delivery_date = today + timedelta(days=7)
|
||||
|
||||
test_orders = [
|
||||
{
|
||||
'comanda_productie': 'CP00000711',
|
||||
'cod_articol': 'ART001',
|
||||
'descr_com_prod': 'Memory Foam Pillow - Premium Quality',
|
||||
'cantitate': 5,
|
||||
'com_achiz_client': 'PO2026001',
|
||||
'nr_linie_com_client': '001',
|
||||
'customer_name': 'ACME Corporation',
|
||||
'customer_article_number': 'ACME-MFP-001',
|
||||
'open_for_order': 1,
|
||||
'line_number': 1,
|
||||
'data_livrara': delivery_date.date(),
|
||||
'dimensiune': 'Standard (50x70cm)',
|
||||
'printed_labels': 0
|
||||
},
|
||||
{
|
||||
'comanda_productie': 'CP00000712',
|
||||
'cod_articol': 'ART002',
|
||||
'descr_com_prod': 'Gel Infused Mattress Topper',
|
||||
'cantitate': 10,
|
||||
'com_achiz_client': 'PO2026002',
|
||||
'nr_linie_com_client': '001',
|
||||
'customer_name': 'Sleep Solutions Ltd',
|
||||
'customer_article_number': 'SS-GIM-002',
|
||||
'open_for_order': 1,
|
||||
'line_number': 1,
|
||||
'data_livrara': delivery_date.date(),
|
||||
'dimensiune': 'Double (140x200cm)',
|
||||
'printed_labels': 0
|
||||
},
|
||||
{
|
||||
'comanda_productie': 'CP00000713',
|
||||
'cod_articol': 'ART003',
|
||||
'descr_com_prod': 'Cooling Gel Pillow - Twin Pack',
|
||||
'cantitate': 8,
|
||||
'com_achiz_client': 'PO2026003',
|
||||
'nr_linie_com_client': '002',
|
||||
'customer_name': 'Bedding Warehouse',
|
||||
'customer_article_number': 'BW-CGP-003',
|
||||
'open_for_order': 1,
|
||||
'line_number': 2,
|
||||
'data_livrara': delivery_date.date(),
|
||||
'dimensiune': 'King (200x200cm)',
|
||||
'printed_labels': 1
|
||||
},
|
||||
{
|
||||
'comanda_productie': 'CP00000714',
|
||||
'cod_articol': 'ART004',
|
||||
'descr_com_prod': 'Hypoallergenic Pillow Insert',
|
||||
'cantitate': 15,
|
||||
'com_achiz_client': 'PO2026004',
|
||||
'nr_linie_com_client': '001',
|
||||
'customer_name': 'Health Products Inc',
|
||||
'customer_article_number': 'HPI-HYP-004',
|
||||
'open_for_order': 0,
|
||||
'line_number': 1,
|
||||
'data_livrara': delivery_date.date(),
|
||||
'dimensiune': 'Standard (50x70cm)',
|
||||
'printed_labels': 0
|
||||
},
|
||||
{
|
||||
'comanda_productie': 'CP00000715',
|
||||
'cod_articol': 'ART005',
|
||||
'descr_com_prod': 'Memory Foam Mattress 10CM',
|
||||
'cantitate': 3,
|
||||
'com_achiz_client': 'PO2026005',
|
||||
'nr_linie_com_client': '001',
|
||||
'customer_name': 'Premium Comfort Ltd',
|
||||
'customer_article_number': 'PC-MFM-005',
|
||||
'open_for_order': 1,
|
||||
'line_number': 1,
|
||||
'data_livrara': delivery_date.date(),
|
||||
'dimensiune': 'Queen (160x200cm)',
|
||||
'printed_labels': 1
|
||||
},
|
||||
{
|
||||
'comanda_productie': 'CP00000716',
|
||||
'cod_articol': 'ART006',
|
||||
'descr_com_prod': 'Latex Pillow - Eco Friendly',
|
||||
'cantitate': 12,
|
||||
'com_achiz_client': 'PO2026006',
|
||||
'nr_linie_com_client': '003',
|
||||
'customer_name': 'Sustainable Sleep',
|
||||
'customer_article_number': 'SS-LAT-006',
|
||||
'open_for_order': 1,
|
||||
'line_number': 3,
|
||||
'data_livrara': delivery_date.date(),
|
||||
'dimensiune': 'Standard (50x70cm)',
|
||||
'printed_labels': 0
|
||||
},
|
||||
{
|
||||
'comanda_productie': 'CP00000717',
|
||||
'cod_articol': 'ART007',
|
||||
'descr_com_prod': 'Body Pillow with Cover',
|
||||
'cantitate': 6,
|
||||
'com_achiz_client': 'PO2026007',
|
||||
'nr_linie_com_client': '001',
|
||||
'customer_name': 'Comfort Essentials',
|
||||
'customer_article_number': 'CE-BP-007',
|
||||
'open_for_order': 1,
|
||||
'line_number': 1,
|
||||
'data_livrara': delivery_date.date(),
|
||||
'dimensiune': 'Long (40x150cm)',
|
||||
'printed_labels': 1
|
||||
}
|
||||
]
|
||||
|
||||
# Insert test data
|
||||
insert_query = """
|
||||
INSERT INTO order_for_labels
|
||||
(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, data_livrara, dimensiune, printed_labels,
|
||||
created_at, updated_at)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
|
||||
"""
|
||||
|
||||
inserted = 0
|
||||
for order in test_orders:
|
||||
try:
|
||||
cursor.execute(insert_query, (
|
||||
order['comanda_productie'],
|
||||
order['cod_articol'],
|
||||
order['descr_com_prod'],
|
||||
order['cantitate'],
|
||||
order['com_achiz_client'],
|
||||
order['nr_linie_com_client'],
|
||||
order['customer_name'],
|
||||
order['customer_article_number'],
|
||||
order['open_for_order'],
|
||||
order['line_number'],
|
||||
order['data_livrara'],
|
||||
order['dimensiune'],
|
||||
order['printed_labels']
|
||||
))
|
||||
inserted += 1
|
||||
print(f"✓ Inserted: {order['comanda_productie']} - {order['descr_com_prod'][:40]}")
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to insert {order['comanda_productie']}: {e}")
|
||||
|
||||
# Commit the transaction
|
||||
conn.commit()
|
||||
|
||||
# Show summary
|
||||
cursor.execute("SELECT COUNT(*) FROM order_for_labels")
|
||||
total_orders = cursor.fetchone()[0]
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Test data insertion completed!")
|
||||
print(f"Inserted: {inserted} new orders")
|
||||
print(f"Total orders in database: {total_orders}")
|
||||
print(f"{'='*60}")
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return True
|
||||
|
||||
except pymysql.Error as e:
|
||||
print(f"Database error: {e}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Unexpected error: {e}")
|
||||
return False
|
||||
|
||||
if __name__ == '__main__':
|
||||
success = insert_test_data()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user