Updated to print service power shell

This commit is contained in:
2025-09-21 16:42:18 +03:00
parent 7a1785d048
commit ed8ebd9e76
23 changed files with 4711 additions and 139 deletions

View File

@@ -1061,6 +1061,153 @@ For support, contact your system administrator.
'error': str(e)
}), 500
@bp.route('/create_service_package', methods=['POST'])
def create_service_package():
"""Create and serve ZIP package of Windows Print Service"""
import os
import zipfile
from flask import current_app, jsonify
try:
# Path to the windows_print_service directory
service_dir = os.path.join(os.path.dirname(os.path.dirname(current_app.root_path)), 'windows_print_service')
print(f"Looking for service files in: {service_dir}")
if not os.path.exists(service_dir):
return jsonify({
'success': False,
'error': f'Windows service directory not found: {service_dir}'
}), 500
# Create static directory if it doesn't exist
static_dir = os.path.join(current_app.root_path, 'static')
os.makedirs(static_dir, exist_ok=True)
zip_filename = 'quality_recticel_print_service.zip'
zip_path = os.path.join(static_dir, zip_filename)
# Create ZIP file with Windows service package
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
files_added = 0
# Add all service files to ZIP (prioritize native PowerShell solution)
for root, dirs, files in os.walk(service_dir):
for file in files:
# Include all relevant files, with focus on native PowerShell solution
if file.endswith(('.ps1', '.bat', '.md', '.json', '.js', '.html', '.css', '.png', '.txt')):
file_path = os.path.join(root, file)
# Create relative path for archive
arcname = os.path.relpath(file_path, service_dir)
# Skip Python files in favor of PowerShell native solution
if file.endswith('.py') and not file.startswith('print_service'):
print(f"Skipping Python file (using native solution): {file_path}")
continue
print(f"Adding service file: {file_path} as {arcname}")
zipf.write(file_path, arcname)
files_added += 1
# Add installation instructions for native PowerShell solution
installation_readme = """# Quality Recticel Windows Print Service - Native Edition
## INSTALLATION INSTRUCTIONS (Native PowerShell - Zero Dependencies!)
### Prerequisites:
- Windows 10/11 or Windows Server 2016+
- Administrator privileges
- Google Chrome browser
- PowerShell (included with Windows)
### Quick Installation (Under 3 Minutes):
1. **Extract Files**: Extract this ZIP to any temporary location
✅ No permanent installation directory needed - files are copied during installation
2. **Install Native Service**: Right-click on 'install_native_service.bat' and select "Run as administrator"
✅ Pure PowerShell implementation - no Python or external dependencies required
3. **Install Chrome Extension**:
- Open Chrome → chrome://extensions/
- Enable "Developer mode"
- Click "Load unpacked" → Select the 'chrome_extension' folder
4. **Verify Installation**: Visit http://localhost:8765/health in your browser
Expected response: {"status": "healthy", "platform": "Windows PowerShell"}
### What Gets Installed:
- ✅ Native Windows Print Service (PowerShell-based, zero dependencies)
- ✅ Auto-start service configuration
- ✅ Service recovery options (automatic restart)
- ✅ Comprehensive logging system
### Files Included:
- 🔧 install_native_service.bat - Native PowerShell installer (RUN AS ADMIN)
- 🖥️ print_service.ps1 - Main PowerShell service (native Windows)
- 🗑️ uninstall_service.bat - Complete removal script
- 🌐 chrome_extension/ - Complete Chrome extension
- 📚 Documentation files (QUICK_SETUP_NATIVE.md, INSTALLATION_GUIDE.md, README.md)
### Native Advantages:
- 🚀 No Python dependencies - pure PowerShell
- ⚡ Faster startup and lower memory usage
- 🛡️ Enterprise-ready with Microsoft components only
- 📦 Tiny footprint - minimal system impact
### Support:
- 📖 Read QUICK_SETUP_NATIVE.md for 3-minute setup guide
- 📋 Read INSTALLATION_GUIDE.md for complete documentation
- 🛠️ Read README.md for technical details
### Service URLs:
- Health Check: http://localhost:8765/health
- Printer List: http://localhost:8765/printers
- API Documentation: See README.md
### Troubleshooting:
1. Service not starting? Run install_service.bat as Administrator
2. Can't connect? Check Windows Firewall (port 8765)
3. Chrome extension not working? Reload extension in chrome://extensions/
Installation takes ~5 minutes • Zero maintenance required
"""
zipf.writestr('INSTALLATION_README.txt', installation_readme)
files_added += 1
print(f"Total service files added to ZIP: {files_added}")
# Verify ZIP was created
if os.path.exists(zip_path):
zip_size = os.path.getsize(zip_path)
print(f"Service ZIP file created: {zip_path}, size: {zip_size} bytes")
if zip_size > 0:
return jsonify({
'success': True,
'download_url': f'/static/{zip_filename}',
'files_included': files_added,
'zip_size': zip_size
})
else:
return jsonify({
'success': False,
'error': 'ZIP file was created but is empty'
}), 500
else:
return jsonify({
'success': False,
'error': 'Failed to create service ZIP file'
}), 500
except Exception as e:
print(f"Error creating service package: {e}")
import traceback
traceback.print_exc()
return jsonify({
'success': False,
'error': str(e)
}), 500
@bp.route('/test_extension_files')
def test_extension_files():
"""Test route to check extension files"""

View File

@@ -0,0 +1,361 @@
# Quality Recticel Windows Print Service - Installation Guide
## 📋 Overview
The Quality Recticel Windows Print Service enables **silent PDF printing** directly from the web application through a Chrome extension. This system eliminates the need for manual PDF downloads and provides seamless label printing functionality.
## 🏗️ System Architecture
```
Web Application (print_module.html)
Windows Print Service (localhost:8765)
Chrome Extension (Native Messaging)
Windows Print System
```
## 📦 Package Contents
```
windows_print_service/
├── print_service.py # Main Windows service (Flask API)
├── service_manager.py # Service installation & management
├── install_service.bat # Automated installation script
├── chrome_extension/ # Chrome extension files
│ ├── manifest.json # Extension configuration
│ ├── background.js # Service worker
│ ├── content.js # Page integration
│ ├── popup.html # Extension UI
│ ├── popup.js # Extension logic
│ └── icons/ # Extension icons
└── INSTALLATION_GUIDE.md # This documentation
```
## 🔧 Prerequisites
### System Requirements
- **Operating System**: Windows 10/11 (64-bit)
- **Python**: Python 3.8 or higher
- **Browser**: Google Chrome (latest version)
- **Privileges**: Administrator access required for installation
### Python Dependencies
The following packages will be installed automatically:
- `flask` - Web service framework
- `flask-cors` - Cross-origin resource sharing
- `requests` - HTTP client library
- `pywin32` - Windows service integration
## 🚀 Installation Process
### Step 1: Download and Extract Files
1. Download the `windows_print_service` folder to your system
2. Extract to a permanent location (e.g., `C:\QualityRecticel\PrintService\`)
3. **Do not move or delete this folder after installation**
### Step 2: Install Windows Service
#### Method A: Automated Installation (Recommended)
1. **Right-click** on `install_service.bat`
2. Select **"Run as administrator"**
3. Click **"Yes"** when Windows UAC prompt appears
4. Wait for installation to complete
#### Method B: Manual Installation
If the automated script fails, follow these steps:
```bash
# Open Command Prompt as Administrator
cd C:\path\to\windows_print_service
# Install Python dependencies
pip install flask flask-cors requests pywin32
# Install Windows service
python service_manager.py install
# Add firewall exception
netsh advfirewall firewall add rule name="Quality Recticel Print Service" dir=in action=allow protocol=TCP localport=8765
# Create Chrome extension registry entry
reg add "HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\com.qualityrecticel.printservice" /ve /d "%cd%\chrome_extension\manifest.json" /f
```
### Step 3: Install Chrome Extension
1. Open **Google Chrome**
2. Navigate to `chrome://extensions/`
3. Enable **"Developer mode"** (toggle in top-right corner)
4. Click **"Load unpacked"**
5. Select the `chrome_extension` folder
6. Verify the extension appears with a printer icon
### Step 4: Verify Installation
#### Check Windows Service Status
1. Press `Win + R`, type `services.msc`, press Enter
2. Look for **"Quality Recticel Print Service"**
3. Status should show **"Running"**
4. Startup type should be **"Automatic"**
#### Test API Endpoints
Open a web browser and visit:
- **Health Check**: `http://localhost:8765/health`
- **Printer List**: `http://localhost:8765/printers`
Expected response for health check:
```json
{
"status": "healthy",
"service": "Quality Recticel Print Service",
"version": "1.0",
"timestamp": "2025-09-21T10:30:00"
}
```
#### Test Chrome Extension
1. Click the extension icon in Chrome toolbar
2. Verify it shows "Service Status: Connected ✅"
3. Check that printers are listed
4. Try the "Test Print" button
## 🔄 Web Application Integration
The web application automatically detects the Windows service and adapts the user interface:
### Service Available (Green Button)
- Button text: **"🖨️ Print Labels (Silent)"**
- Functionality: Direct printing to default printer
- User experience: Click → Labels print immediately
### Service Unavailable (Blue Button)
- Button text: **"📄 Generate PDF"**
- Functionality: PDF download for manual printing
- User experience: Click → PDF downloads to browser
### Detection Logic
```javascript
// Automatic service detection on page load
const response = await fetch('http://localhost:8765/health');
if (response.ok) {
// Service available - enable silent printing
} else {
// Service unavailable - fallback to PDF download
}
```
## 🛠️ Configuration
### Service Configuration
The service runs with the following default settings:
| Setting | Value | Description |
|---------|-------|-------------|
| **Port** | 8765 | Local API port |
| **Host** | localhost | Service binding |
| **Startup** | Automatic | Starts with Windows |
| **Printer** | Default | Uses system default printer |
| **Copies** | 1 | Default print copies |
### Chrome Extension Permissions
The extension requires these permissions:
- `printing` - Access to printer functionality
- `nativeMessaging` - Communication with Windows service
- `activeTab` - Access to current webpage
- `storage` - Save extension settings
## 🔍 Troubleshooting
### Common Issues
#### 1. Service Not Starting
**Symptoms**: API not accessible at localhost:8765
**Solutions**:
```bash
# Check service status
python -c "from service_manager import service_status; service_status()"
# Restart service manually
python service_manager.py restart
# Check Windows Event Viewer for service errors
```
#### 2. Chrome Extension Not Working
**Symptoms**: Extension shows "Service Status: Disconnected ❌"
**Solutions**:
- Verify Windows service is running
- Check firewall settings (port 8765 must be open)
- Reload the Chrome extension
- Restart Chrome browser
#### 3. Firewall Blocking Connection
**Symptoms**: Service runs but web page can't connect
**Solutions**:
```bash
# Add firewall rule manually
netsh advfirewall firewall add rule name="Quality Recticel Print Service" dir=in action=allow protocol=TCP localport=8765
# Or disable Windows Firewall temporarily to test
```
#### 4. Permission Denied Errors
**Symptoms**: Installation fails with permission errors
**Solutions**:
- Ensure running as Administrator
- Check Windows UAC settings
- Verify Python installation permissions
#### 5. Print Jobs Not Processing
**Symptoms**: API accepts requests but nothing prints
**Solutions**:
- Check default printer configuration
- Verify printer drivers are installed
- Test manual printing from other applications
- Check Windows Print Spooler service
### Log Files
Check these locations for troubleshooting:
| Component | Log Location |
|-----------|--------------|
| **Windows Service** | `print_service.log` (same folder as service) |
| **Chrome Extension** | Chrome DevTools → Extensions → Background page |
| **Windows Event Log** | Event Viewer → Windows Logs → System |
### Diagnostic Commands
```bash
# Check service status
python service_manager.py status
# Test API manually
curl http://localhost:8765/health
# List available printers
curl http://localhost:8765/printers
# Check Windows service
sc query QualityRecticelPrintService
# Check listening ports
netstat -an | findstr :8765
```
## 🔄 Maintenance
### Updating the Service
1. Stop the current service:
```bash
python service_manager.py stop
```
2. Replace service files with new versions
3. Restart the service:
```bash
python service_manager.py start
```
### Uninstalling
#### Remove Chrome Extension
1. Go to `chrome://extensions/`
2. Find "Quality Recticel Print Service"
3. Click "Remove"
#### Remove Windows Service
```bash
# Run as Administrator
python service_manager.py uninstall
```
#### Remove Firewall Rule
```bash
netsh advfirewall firewall delete rule name="Quality Recticel Print Service"
```
## 📞 Support Information
### API Endpoints Reference
| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/health` | GET | Service health check |
| `/printers` | GET | List available printers |
| `/print/pdf` | POST | Print PDF from URL |
| `/print/silent` | POST | Silent print with metadata |
### Request Examples
**Silent Print Request**:
```json
POST /print/silent
{
"pdf_url": "http://localhost:5000/generate_labels_pdf/123",
"printer_name": "default",
"copies": 1,
"silent": true,
"order_id": "123",
"quantity": "10"
}
```
**Expected Response**:
```json
{
"success": true,
"message": "Print job sent successfully",
"job_id": "print_20250921_103000",
"printer": "HP LaserJet Pro",
"timestamp": "2025-09-21T10:30:00"
}
```
## 📚 Technical Details
### Service Architecture
- **Framework**: Flask (Python)
- **Service Type**: Windows Service (pywin32)
- **Communication**: HTTP REST API + Native Messaging
- **Security**: Localhost binding only (127.0.0.1:8765)
### Chrome Extension Architecture
- **Manifest Version**: 3
- **Service Worker**: Handles background print requests
- **Content Script**: Integrates with Quality Recticel web pages
- **Native Messaging**: Communicates with Windows service
### Security Considerations
- Service only accepts local connections (localhost)
- No external network access required
- Chrome extension runs in sandboxed environment
- Windows service runs with system privileges (required for printing)
---
## 📋 Quick Start Checklist
- [ ] Download `windows_print_service` folder
- [ ] Right-click `install_service.bat` → "Run as administrator"
- [ ] Install Chrome extension from `chrome_extension` folder
- [ ] Verify service at `http://localhost:8765/health`
- [ ] Test printing from Quality Recticel web application
**Installation Time**: ~5 minutes
**User Training Required**: Minimal (automatic detection and fallback)
**Maintenance**: Zero (auto-starts with Windows)
For additional support, check the log files and diagnostic commands listed above.

View File

@@ -0,0 +1,69 @@
# 🚀 Quality Recticel Print Service - Quick Setup
## 📦 What You Get
- **Silent PDF Printing** - No more manual downloads!
- **Automatic Detection** - Smart fallback when service unavailable
- **Zero Configuration** - Works out of the box
## ⚡ 2-Minute Installation
### Step 1: Install Windows Service
1. **Right-click** `install_service.bat`
2. Select **"Run as administrator"**
3. Click **"Yes"** and wait for completion
### Step 2: Install Chrome Extension
1. Open Chrome → `chrome://extensions/`
2. Enable **"Developer mode"**
3. Click **"Load unpacked"** → Select `chrome_extension` folder
### Step 3: Verify Installation
- Visit: `http://localhost:8765/health`
- Should see: `{"status": "healthy"}`
## 🎯 How It Works
| Service Status | Button Appearance | What Happens |
|---------------|-------------------|--------------|
| **Running** ✅ | 🖨️ **Print Labels (Silent)** (Green) | Direct printing |
| **Not Running** ❌ | 📄 **Generate PDF** (Blue) | PDF download |
## ⚠️ Troubleshooting
| Problem | Solution |
|---------|----------|
| **Service won't start** | Run `install_service.bat` as Administrator |
| **Chrome extension not working** | Reload extension in `chrome://extensions/` |
| **Can't connect to localhost:8765** | Check Windows Firewall (port 8765) |
| **Nothing prints** | Verify default printer is set up |
## 🔧 Management Commands
```bash
# Check service status
python service_manager.py status
# Restart service
python service_manager.py restart
# Uninstall service
python service_manager.py uninstall
```
## 📍 Important Notes
-**Auto-starts** with Windows - no manual intervention needed
- 🔒 **Local only** - service only accessible from same computer
- 🖨️ **Uses default printer** - configure your default printer in Windows
- 💾 **Don't move files** after installation - keep folder in same location
## 🆘 Quick Support
**Service API**: `http://localhost:8765`
**Health Check**: `http://localhost:8765/health`
**Printer List**: `http://localhost:8765/printers`
**Log File**: `print_service.log` (same folder as installation)
---
*Installation takes ~5 minutes • Zero maintenance required • Works with existing Quality Recticel web application*

View File

@@ -0,0 +1,348 @@
# Quality Recticel Windows Print Service
## 🏗️ Technical Architecture
Local Windows service providing REST API for silent PDF printing via Chrome extension integration.
```
┌─────────────────────────────────────────────────────────────┐
│ Quality Recticel Web App │
│ (print_module.html) │
└─────────────────────┬───────────────────────────────────────┘
│ HTTP Request
┌─────────────────────────────────────────────────────────────┐
│ Windows Print Service │
│ (localhost:8765) │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ Flask │ │ CORS │ │ PDF Handler │ │
│ │ Server │ │ Support │ │ │ │
│ └─────────────┘ └──────────────┘ └─────────────────┘ │
└─────────────────────┬───────────────────────────────────────┘
│ Native Messaging
┌─────────────────────────────────────────────────────────────┐
│ Chrome Extension │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ Background │ │ Content │ │ Popup │ │
│ │ Service │ │ Script │ │ UI │ │
│ │ Worker │ │ │ │ │ │
│ └─────────────┘ └──────────────┘ └─────────────────┘ │
└─────────────────────┬───────────────────────────────────────┘
│ Windows API
┌─────────────────────────────────────────────────────────────┐
│ Windows Print System │
└─────────────────────────────────────────────────────────────┘
```
## 📁 Project Structure
```
windows_print_service/
├── 📄 print_service.py # Main Flask service
├── 📄 service_manager.py # Windows service wrapper
├── 📄 install_service.bat # Installation script
├── 📄 INSTALLATION_GUIDE.md # Complete documentation
├── 📄 QUICK_SETUP.md # User quick reference
├── 📄 README.md # This file
└── 📁 chrome_extension/ # Chrome extension
├── 📄 manifest.json # Extension manifest v3
├── 📄 background.js # Service worker
├── 📄 content.js # Page content integration
├── 📄 popup.html # Extension popup UI
├── 📄 popup.js # Popup functionality
└── 📁 icons/ # Extension icons
```
## 🚀 API Endpoints
### Base URL: `http://localhost:8765`
| Endpoint | Method | Description | Request Body | Response |
|----------|--------|-------------|--------------|----------|
| `/health` | GET | Service health check | None | `{"status": "healthy", ...}` |
| `/printers` | GET | List available printers | None | `{"printers": [...]}` |
| `/print/pdf` | POST | Print PDF from URL | `{"url": "...", "printer": "..."}` | `{"success": true, ...}` |
| `/print/silent` | POST | Silent print with metadata | `{"pdf_url": "...", "order_id": "..."}` | `{"success": true, ...}` |
### Example API Usage
```javascript
// Health Check
const health = await fetch('http://localhost:8765/health');
const status = await health.json();
// Silent Print
const printRequest = {
pdf_url: 'http://localhost:5000/generate_labels_pdf/123',
printer_name: 'default',
copies: 1,
silent: true,
order_id: '123',
quantity: '10'
};
const response = await fetch('http://localhost:8765/print/silent', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(printRequest)
});
```
## 🔧 Development Setup
### Prerequisites
- Python 3.8+
- Windows 10/11
- Chrome Browser
- Administrator privileges
### Local Development
```bash
# Clone/download the project
cd windows_print_service
# Install dependencies
pip install flask flask-cors requests pywin32
# Run development server (not as service)
python print_service.py
# Install as Windows service
python service_manager.py install
# Service management
python service_manager.py start
python service_manager.py stop
python service_manager.py restart
python service_manager.py uninstall
```
### Chrome Extension Development
```bash
# Load extension in Chrome
chrome://extensions/ → Developer mode ON → Load unpacked
# Debug extension
chrome://extensions/ → Details → Background page (for service worker)
chrome://extensions/ → Details → Inspect views (for popup)
```
## 📋 Configuration
### Service Configuration (`print_service.py`)
```python
class WindowsPrintService:
def __init__(self, host='127.0.0.1', port=8765):
self.host = host # Localhost binding only
self.port = port # Service port
self.app = Flask(__name__)
```
### Chrome Extension Permissions (`manifest.json`)
```json
{
"permissions": [
"printing", // Access to printer API
"nativeMessaging", // Communication with Windows service
"activeTab", // Current tab access
"storage" // Extension settings storage
]
}
```
## 🔄 Integration Flow
### 1. Service Detection
```javascript
// Web page detects service availability
const isServiceAvailable = await checkServiceHealth();
updatePrintButton(isServiceAvailable);
```
### 2. Print Request Flow
```
User clicks print → Web app → Windows service → Chrome extension → Printer
```
### 3. Fallback Mechanism
```
Service unavailable → Fallback to PDF download → Manual printing
```
## 🛠️ Customization
### Adding New Print Options
```python
# In print_service.py
@app.route('/print/custom', methods=['POST'])
def print_custom():
data = request.json
# Custom print logic here
return jsonify({'success': True})
```
### Modifying Chrome Extension
```javascript
// In background.js - Add new message handler
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'CUSTOM_PRINT') {
// Custom print logic
}
});
```
### Web Application Integration
```javascript
// In print_module.html - Modify print function
async function customPrintFunction(orderId) {
const response = await fetch('http://localhost:8765/print/custom', {
method: 'POST',
body: JSON.stringify({orderId, customOptions: {...}})
});
}
```
## 🧪 Testing
### Unit Tests (Future Enhancement)
```python
# test_print_service.py
import unittest
from print_service import WindowsPrintService
class TestPrintService(unittest.TestCase):
def test_health_endpoint(self):
# Test implementation
pass
```
### Manual Testing Checklist
- [ ] Service starts automatically on Windows boot
- [ ] API endpoints respond correctly
- [ ] Chrome extension loads without errors
- [ ] Print jobs execute successfully
- [ ] Fallback works when service unavailable
- [ ] Firewall allows port 8765 traffic
## 📊 Monitoring & Logging
### Log Files
- **Service Log**: `print_service.log` (Flask application logs)
- **Windows Event Log**: Windows Services logs
- **Chrome DevTools**: Extension console logs
### Health Monitoring
```python
# Monitor service health
import requests
try:
response = requests.get('http://localhost:8765/health', timeout=5)
if response.status_code == 200:
print("✅ Service healthy")
except:
print("❌ Service unavailable")
```
## 🔒 Security Considerations
### Network Security
- **Localhost Only**: Service binds to 127.0.0.1 (no external access)
- **No Authentication**: Relies on local machine security
- **Firewall Rule**: Port 8765 opened for local connections only
### Chrome Extension Security
- **Manifest V3**: Latest security standards
- **Minimal Permissions**: Only necessary permissions requested
- **Sandboxed**: Runs in Chrome's security sandbox
### Windows Service Security
- **System Service**: Runs with appropriate Windows service privileges
- **Print Permissions**: Requires printer access (normal for print services)
## 🚀 Deployment
### Production Deployment
1. **Package Distribution**:
```bash
# Create deployment package
zip -r quality_recticel_print_service.zip windows_print_service/
```
2. **Installation Script**: Use `install_service.bat` for end users
3. **Group Policy Deployment**: Deploy Chrome extension via enterprise policies
### Enterprise Considerations
- **Silent Installation**: Modify `install_service.bat` for unattended install
- **Registry Deployment**: Pre-configure Chrome extension registry entries
- **Network Policies**: Ensure firewall policies allow localhost:8765
## 📚 Dependencies
### Python Packages
```
flask>=2.3.0 # Web framework
flask-cors>=4.0.0 # CORS support
requests>=2.31.0 # HTTP client
pywin32>=306 # Windows service integration
```
### Chrome APIs
- `chrome.printing.*` - Printing functionality
- `chrome.runtime.*` - Extension messaging
- `chrome.nativeMessaging.*` - Native app communication
## 🐛 Debugging
### Common Debug Commands
```bash
# Check service status
sc query QualityRecticelPrintService
# Test API manually
curl http://localhost:8765/health
# Check listening ports
netstat -an | findstr :8765
# View service logs
type print_service.log
```
### Chrome Extension Debugging
```javascript
// In background.js - Add debug logging
console.log('Print request received:', message);
// In popup.js - Test API connection
fetch('http://localhost:8765/health')
.then(r => r.json())
.then(data => console.log('Service status:', data));
```
---
## 📄 License & Support
**Project**: Quality Recticel Print Service
**Version**: 1.0
**Compatibility**: Windows 10/11, Chrome 88+
**Maintenance**: Zero-maintenance after installation
For technical support, refer to `INSTALLATION_GUIDE.md` troubleshooting section.

View File

@@ -1,103 +1,250 @@
{% extends "base.html" %}
{% block title %}Chrome Extension Download{% endblock %}
{% block title %}Quality Recticel Print Service Downloads{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h3 class="mb-0">🖨️ Quality Recticel Print Helper - Chrome Extension</h3>
<!-- Header Section -->
<div class="row justify-content-center mb-4">
<div class="col-md-12">
<div class="text-center">
<h1 class="display-4">🖨️ Quality Recticel Print Service</h1>
<p class="lead">Professional Silent Printing Solution for Windows</p>
</div>
</div>
</div>
<!-- Overview Card -->
<div class="row justify-content-center mb-4">
<div class="col-md-10">
<div class="card border-primary">
<div class="card-header bg-primary text-white">
<h3 class="mb-0"><EFBFBD> Complete Printing Solution</h3>
</div>
<div class="card-body">
<div class="alert alert-info">
<strong>Direct Printing Solution:</strong> This Chrome extension enables direct printing from the Print Module to your default printer without browser dialogs.
<div class="row">
<div class="col-md-6">
<h5>🏆 What You Get:</h5>
<ul>
<li><strong>Silent PDF Printing</strong> - No manual downloads</li>
<li><strong>Automatic Detection</strong> - Smart service fallback</li>
<li><strong>Zero Configuration</strong> - Works out of the box</li>
<li><strong>Auto-Start Service</strong> - Boots with Windows</li>
<li><strong>Professional Integration</strong> - Seamless workflow</li>
</ul>
</div>
<div class="col-md-6">
<h5>🔧 System Components:</h5>
<ul>
<li>🖥️ <strong>Windows Print Service</strong> - Local API (localhost:8765)</li>
<li>🌐 <strong>Chrome Extension</strong> - Browser integration</li>
<li>📄 <strong>Web Integration</strong> - Smart button detection</li>
<li>🔄 <strong>Fallback System</strong> - PDF download backup</li>
<li>🛡️ <strong>Security</strong> - Local-only connections</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Download Cards Row -->
<div class="row justify-content-center">
<!-- Windows Service Card -->
<div class="col-md-5 mb-4">
<div class="card h-100 border-success">
<div class="card-header bg-success text-white text-center">
<h4 class="mb-0">🖥️ Windows Print Service</h4>
<small>Core printing engine</small>
</div>
<div class="card-body d-flex flex-column">
<div class="alert alert-success">
<strong>🚀 Install First:</strong> The Windows service provides the printing API and must be installed before the Chrome extension.
</div>
<h4>Features:</h4>
<h5>📦 Package Contents:</h5>
<ul>
<li>✅ Print labels directly to default printer</li>
<li>✅ No browser print dialogs</li>
<li>✅ Automatic printer detection</li>
<li>✅ Print status notifications</li>
<li>✅ Enhanced print button with visual feedback</li>
<li>🔧 <code>install_service.bat</code> - One-click installer</li>
<li>🖥️ <code>print_service.py</code> - Main service application</li>
<li>⚙️ <code>service_manager.py</code> - Service management</li>
<li>🌐 <code>chrome_extension/</code> - Browser extension</li>
<li>📚 Complete documentation package</li>
</ul>
<h4>Installation Instructions:</h4>
<h5>⚡ Quick Install:</h5>
<ol>
<li><strong>Download Extension Files:</strong>
<div class="mt-2 mb-3">
<button class="btn btn-primary" id="download-extension-btn">
📥 Download Chrome Extension (.zip)
</button>
<br><br>
<div class="alert alert-info" style="font-size: 12px;">
<strong>Alternative:</strong> Download individual files:
<br>
<a href="{{ url_for('main.extension_files', filename='manifest.json') }}" target="_blank">manifest.json</a> |
<a href="{{ url_for('main.extension_files', filename='background.js') }}" target="_blank">background.js</a> |
<a href="{{ url_for('main.extension_files', filename='content.js') }}" target="_blank">content.js</a> |
<a href="{{ url_for('main.extension_files', filename='popup.html') }}" target="_blank">popup.html</a> |
<a href="{{ url_for('main.extension_files', filename='popup.js') }}" target="_blank">popup.js</a>
<li>Download and extract the service package</li>
<li><strong>Right-click</strong> <code>install_service.bat</code></li>
<li>Select <strong>"Run as administrator"</strong></li>
<li>Wait for installation to complete</li>
</ol>
<div class="text-center mt-auto">
<button class="btn btn-success btn-lg mb-2" id="download-service-btn">
📥 Download Windows Service
</button>
<br>
<small class="text-muted">Complete package (~50KB)</small>
</div>
</div>
</div>
</div>
<!-- Chrome Extension Card -->
<div class="col-md-5 mb-4">
<div class="card h-100 border-info">
<div class="card-header bg-info text-white text-center">
<h4 class="mb-0">🌐 Chrome Extension</h4>
<small>Browser integration</small>
</div>
<div class="card-body d-flex flex-column">
<div class="alert alert-info">
<strong>🔗 Install Second:</strong> The Chrome extension connects your browser to the Windows service for seamless printing.
</div>
<h5>🎯 Features:</h5>
<ul>
<li>🖨️ Silent printing via native messaging</li>
<li>🔍 Automatic service detection</li>
<li>📊 Print status monitoring</li>
<li>🔄 Graceful fallback to PDF download</li>
<li>⚙️ Printer management interface</li>
</ul>
<h5>🚀 Quick Install:</h5>
<ol>
<li>Download and extract extension files</li>
<li>Open Chrome → <code>chrome://extensions/</code></li>
<li>Enable <strong>"Developer mode"</strong></li>
<li>Click <strong>"Load unpacked"</strong> → Select folder</li>
</ol>
<div class="text-center mt-auto">
<button class="btn btn-info btn-lg mb-2" id="download-extension-btn">
📥 Download Chrome Extension
</button>
<br>
<small class="text-muted">Extension package (~15KB)</small>
<hr>
<div class="text-center">
<small class="text-muted">Individual files:</small><br>
<a href="{{ url_for('main.extension_files', filename='manifest.json') }}" target="_blank" class="btn btn-sm btn-outline-secondary">manifest.json</a>
<a href="{{ url_for('main.extension_files', filename='background.js') }}" target="_blank" class="btn btn-sm btn-outline-secondary">background.js</a>
<a href="{{ url_for('main.extension_files', filename='content.js') }}" target="_blank" class="btn btn-sm btn-outline-secondary">content.js</a>
<a href="{{ url_for('main.extension_files', filename='popup.html') }}" target="_blank" class="btn btn-sm btn-outline-secondary">popup.html</a>
<a href="{{ url_for('main.extension_files', filename='popup.js') }}" target="_blank" class="btn btn-sm btn-outline-secondary">popup.js</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Documentation Section -->
<div class="row justify-content-center mb-4">
<div class="col-md-10">
<div class="card border-warning">
<div class="card-header bg-warning text-dark">
<h4 class="mb-0">📚 Documentation & Support</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="card h-100">
<div class="card-header bg-success text-white text-center">
<h6 class="mb-0">⚡ Quick Setup Guide</h6>
</div>
<div class="card-body text-center">
<p class="card-text">2-minute installation guide with visual steps and troubleshooting tips.</p>
<a href="/static/documentation/QUICK_SETUP.md" target="_blank" class="btn btn-success">
📖 Quick Setup
</a>
</div>
</div>
</li>
<li><strong>Extract Files:</strong>
<p>Extract the downloaded ZIP file to a folder on your computer (e.g., Desktop/print_extension)</p>
</li>
<li><strong>Open Chrome Extensions:</strong>
<p>In Google Chrome, go to: <code>chrome://extensions/</code></p>
</li>
<li><strong>Enable Developer Mode:</strong>
<p>Toggle the "Developer mode" switch in the top-right corner</p>
</li>
<li><strong>Load Extension:</strong>
<p>Click "Load unpacked" and select the folder where you extracted the files</p>
</li>
<li><strong>Verify Installation:</strong>
<p>The extension icon 🖨️ should appear in your Chrome toolbar</p>
</li>
</ol>
<h4>Usage:</h4>
<ol>
<li>Navigate to the <a href="{{ url_for('main.print_module') }}" target="_blank">Print Module</a></li>
<li>Select an order from the table</li>
<li>Click the enhanced "🖨️ Print Direct" button</li>
<li>The label will print automatically to your default printer</li>
</ol>
<div class="alert alert-warning">
<strong>System Requirements:</strong>
<ul class="mb-0">
<li>Google Chrome browser (version 88 or higher)</li>
<li>Default printer configured on your system</li>
<li>Printer drivers installed and working</li>
</ul>
</div>
<div class="col-md-4">
<div class="card h-100">
<div class="card-header bg-primary text-white text-center">
<h6 class="mb-0">📋 Complete Guide</h6>
</div>
<div class="card-body text-center">
<p class="card-text">Comprehensive installation documentation with troubleshooting and API reference.</p>
<a href="/static/documentation/INSTALLATION_GUIDE.md" target="_blank" class="btn btn-primary">
📚 Full Documentation
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100">
<div class="card-header bg-info text-white text-center">
<h6 class="mb-0">🛠️ Technical Reference</h6>
</div>
<div class="card-body text-center">
<p class="card-text">Developer documentation with API specs and customization examples.</p>
<a href="/static/documentation/README.md" target="_blank" class="btn btn-info">
🔧 Developer Docs
</a>
</div>
</div>
</div>
</div>
<div class="alert alert-success">
<strong>Troubleshooting:</strong>
<ul class="mb-0">
<li>Click the extension icon 🖨️ to test printer connection</li>
<li>Check Chrome's printer settings: <code>chrome://settings/printing</code></li>
<li>Ensure your default printer is set correctly</li>
<li>Reload the Print Module page after installing the extension</li>
</ul>
</div>
</div>
</div>
</div>
<!-- System Requirements -->
<div class="row justify-content-center mb-4">
<div class="col-md-10">
<div class="card border-secondary">
<div class="card-header bg-secondary text-white">
<h4 class="mb-0">⚙️ System Requirements & Information</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h5>💻 Requirements:</h5>
<ul>
<li><strong>OS:</strong> Windows 10/11 (64-bit)</li>
<li><strong>Python:</strong> 3.8+ (auto-installed if missing)</li>
<li><strong>Browser:</strong> Google Chrome (latest)</li>
<li><strong>Privileges:</strong> Administrator (for installation only)</li>
<li><strong>Network:</strong> Localhost access (no internet required)</li>
</ul>
</div>
<div class="col-md-6">
<h5>🔍 How It Works:</h5>
<div class="alert alert-light">
<ol class="mb-0">
<li>🌐 Web page detects service status</li>
<li>🖨️ <strong>Service Available</strong> → Green "Print Labels (Silent)" button</li>
<li>📄 <strong>Service Unavailable</strong> → Blue "Generate PDF" button</li>
<li>🔄 Automatic fallback ensures printing always works</li>
</ol>
</div>
</div>
</div>
<div class="mt-4 text-center">
<a href="{{ url_for('main.print_module') }}" class="btn btn-success">
</div>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="row justify-content-center mb-5">
<div class="col-md-8 text-center">
<div class="card border-dark">
<div class="card-body">
<h5>🚀 Ready to Start?</h5>
<p class="text-muted">Installation takes ~5 minutes • Zero maintenance required</p>
<div class="btn-group-vertical btn-group-lg" role="group">
<a href="{{ url_for('main.print_module') }}" class="btn btn-success btn-lg">
🖨️ Go to Print Module
</a>
<button class="btn btn-secondary" onclick="window.close()">
Close
Close Window
</button>
</div>
</div>
@@ -107,12 +254,53 @@
</div>
<script>
// Create ZIP file dynamically when download is requested
// Windows Service Download Handler
document.getElementById('download-service-btn').addEventListener('click', function(e) {
e.preventDefault();
// Show loading state
const originalText = this.innerHTML;
this.innerHTML = '⏳ Preparing Windows Service Package...';
this.disabled = true;
// Create the Windows service package
fetch('/create_service_package', {method: 'POST'})
.then(response => response.json())
.then(data => {
if (data.success) {
// Start download
window.location.href = data.download_url;
// Show success message
setTimeout(() => {
this.innerHTML = '✅ Download Started!';
}, 500);
// Reset button
setTimeout(() => {
this.innerHTML = originalText;
this.disabled = false;
}, 3000);
} else {
alert('Error creating Windows service package: ' + data.error);
this.innerHTML = originalText;
this.disabled = false;
}
})
.catch(error => {
alert('Error: ' + error.message);
this.innerHTML = originalText;
this.disabled = false;
});
});
// Chrome Extension Download Handler
document.getElementById('download-extension-btn').addEventListener('click', function(e) {
e.preventDefault();
// Show loading state
this.innerHTML = '⏳ Preparing Download...';
const originalText = this.innerHTML;
this.innerHTML = '⏳ Preparing Chrome Extension Package...';
this.disabled = true;
// Create the extension package
@@ -123,22 +311,78 @@ document.getElementById('download-extension-btn').addEventListener('click', func
// Start download
window.location.href = data.download_url;
// Show success message
setTimeout(() => {
this.innerHTML = '✅ Download Started!';
}, 500);
// Reset button
setTimeout(() => {
this.innerHTML = '📥 Download Chrome Extension (.zip)';
this.innerHTML = originalText;
this.disabled = false;
}, 2000);
}, 3000);
} else {
alert('Error creating extension package: ' + data.error);
this.innerHTML = '📥 Download Chrome Extension (.zip)';
this.innerHTML = originalText;
this.disabled = false;
}
})
.catch(error => {
alert('Error: ' + error.message);
this.innerHTML = '📥 Download Chrome Extension (.zip)';
this.innerHTML = originalText;
this.disabled = false;
});
});
// Documentation links - track clicks for analytics
document.querySelectorAll('a[href*="/static/documentation/"]').forEach(link => {
link.addEventListener('click', function(e) {
// Could add analytics tracking here
console.log('Documentation accessed:', this.href);
});
});
// Show installation progress tips
function showInstallationTips() {
const tips = [
'💡 Tip: The Windows service automatically starts with your computer',
'💡 Tip: Both components work together - install the service first',
'💡 Tip: Check the documentation for troubleshooting common issues',
'💡 Tip: The system gracefully falls back to PDF downloads if needed'
];
let tipIndex = 0;
const tipContainer = document.createElement('div');
tipContainer.className = 'alert alert-info position-fixed';
tipContainer.style.cssText = 'bottom: 20px; right: 20px; max-width: 300px; z-index: 1000;';
function showNextTip() {
if (tipIndex < tips.length) {
tipContainer.innerHTML = `
<button type="button" class="btn-close float-end" onclick="this.parentElement.remove()"></button>
${tips[tipIndex]}
`;
if (!document.body.contains(tipContainer)) {
document.body.appendChild(tipContainer);
}
tipIndex++;
setTimeout(showNextTip, 8000); // Show next tip after 8 seconds
} else {
setTimeout(() => {
if (document.body.contains(tipContainer)) {
tipContainer.remove();
}
}, 5000);
}
}
// Start showing tips after 3 seconds
setTimeout(showNextTip, 3000);
}
// Initialize tips when page loads
document.addEventListener('DOMContentLoaded', showInstallationTips);
</script>
{% endblock %}

View File

@@ -236,12 +236,35 @@ table tbody tr.selected td {
</div>
</div>
<!-- PDF Information -->
<div style="width: 100%; margin-top: 15px; padding: 0 15px; text-align: center;">
<div style="background: #e8f4f8; border: 1px solid #bee5eb; border-radius: 6px; padding: 12px; font-size: 11px; color: #0c5460;">
<strong>📄 PDF Label Generation</strong><br>
Labels will be generated as PDF files for universal printing compatibility.<br>
<small style="color: #6c757d;">Works with any browser and printer - no extensions needed!</small>
<!-- Printer Selection and Service Setup -->
<div style="width: 100%; margin-top: 15px; padding: 0 15px;">
<!-- Printer Selection -->
<div class="mb-3">
<label for="printer-select" class="form-label" style="font-size: 13px; font-weight: 600; color: #495057; margin-bottom: 5px;">
🖨️ Choose Printer
</label>
<select id="printer-select" class="form-control" style="font-size: 12px; padding: 6px 10px;">
<option value="default">Default Printer</option>
<option value="detecting" disabled>Detecting printers...</option>
</select>
<small id="printer-status" class="text-muted" style="font-size: 10px;">
Checking for available printers...
</small>
</div>
<!-- Service Installation Link -->
<div class="text-center">
<div style="background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; padding: 10px; margin-bottom: 10px;">
<div style="font-size: 11px; color: #856404; margin-bottom: 8px;">
<strong><EFBFBD> Upgrade to Silent Printing</strong>
</div>
<a href="{{ url_for('main.download_extension') }}" class="btn btn-warning btn-sm" target="_blank" style="font-size: 11px; padding: 4px 12px;">
📥 Install Print Service & Extension
</a>
<div style="font-size: 9px; color: #6c757d; margin-top: 5px;">
5-minute setup • Auto-starts with Windows • Silent printing
</div>
</div>
</div>
</div>
@@ -568,12 +591,242 @@ function addFallbackPrintHandler() {
}
}
// Windows Print Service Integration
const PRINT_SERVICE_URL = 'http://localhost:8765';
let printServiceAvailable = false;
let availablePrinters = [];
// Check print service availability on page load
window.addEventListener('DOMContentLoaded', function() {
checkPrintServiceAvailability();
initializePrinterDropdown();
});
function initializePrinterDropdown() {
const select = document.getElementById('printer-select');
if (!select) return;
select.innerHTML = `
<option value="default">Default Printer</option>
<option value="detecting" disabled>Detecting printers...</option>
`;
}
async function checkPrintServiceAvailability() {
const printerStatus = document.getElementById('printer-status');
try {
printerStatus.textContent = 'Checking Windows Print Service...';
const response = await fetch(`${PRINT_SERVICE_URL}/health`, {
method: 'GET',
signal: AbortSignal.timeout(3000)
});
if (response.ok) {
printServiceAvailable = true;
console.log('✅ Windows Print Service is available');
updatePrintButtonForService(true);
await loadAvailablePrinters();
} else {
throw new Error('Service not responding');
}
} catch (error) {
printServiceAvailable = false;
console.log('⚠️ Windows Print Service not available, using fallback PDF download');
updatePrintButtonForService(false);
updatePrinterStatus('Windows Print Service not detected - PDF download mode');
}
}
async function loadAvailablePrinters() {
try {
const response = await fetch(`${PRINT_SERVICE_URL}/printers`);
if (response.ok) {
const data = await response.json();
availablePrinters = data.printers || [];
updatePrinterDropdown();
updatePrinterStatus(`${availablePrinters.length} printer(s) detected via Windows service`);
}
} catch (error) {
console.warn('Failed to load printers:', error);
updatePrinterStatus('Failed to detect printers - using default');
}
}
function updatePrinterDropdown() {
const select = document.getElementById('printer-select');
if (!select) return;
// Clear and rebuild options
select.innerHTML = '<option value="default">Default Printer (Recommended)</option>';
availablePrinters.forEach((printer, index) => {
const option = document.createElement('option');
option.value = printer.name || printer;
option.textContent = `${printer.name || printer}`;
if (printer.is_default) {
option.textContent += ' (Default)';
option.selected = true;
}
select.appendChild(option);
});
if (availablePrinters.length === 0) {
const option = document.createElement('option');
option.value = 'none';
option.textContent = 'No printers detected';
option.disabled = true;
select.appendChild(option);
}
}
function updatePrinterStatus(message) {
const status = document.getElementById('printer-status');
if (status) {
status.textContent = message;
}
}
function getSelectedPrinter() {
const select = document.getElementById('printer-select');
return select ? select.value : 'default';
}
function updatePrintButtonForService(serviceAvailable) {
const printButton = document.getElementById('print-label-btn');
if (!printButton) return;
if (serviceAvailable) {
printButton.innerHTML = '🖨️ Print Labels (Silent)';
printButton.title = 'Print labels directly to selected printer using Windows service';
printButton.style.background = '#28a745'; // Green for direct print
} else {
printButton.innerHTML = '📄 Generate PDF';
printButton.title = 'Generate PDF for manual printing (Windows service not available)';
printButton.style.background = '#007bff'; // Blue for PDF download
}
}
// Enhanced print function with Windows service support
async function printLabelsWithService(orderId, prodOrder, quantity) {
try {
// Generate PDF URL
const pdfUrl = `${window.location.origin}/generate_labels_pdf/${orderId}`;
// Get selected printer from dropdown
const selectedPrinter = getSelectedPrinter();
// Prepare print data for service
const printData = {
pdf_url: pdfUrl,
printer_name: selectedPrinter,
copies: 1,
silent: true,
order_id: orderId,
quantity: quantity
};
// Send to Windows service
const response = await fetch(`${PRINT_SERVICE_URL}/print/silent`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(printData)
});
const result = await response.json();
if (response.ok && result.success) {
// Success - labels printed silently
const printerName = selectedPrinter === 'default' ? 'default printer' : selectedPrinter;
alert(`✅ Labels printed successfully!\n\n📊 Order: ${prodOrder}\n📦 Quantity: ${quantity} labels\n🖨️ Printer: ${printerName}\n📋 Sequential: ${prodOrder}-001 to ${prodOrder}-${String(quantity).padStart(3, '0')}\n\n🎯 Printed silently via Windows service!`);
// Update order status in database
await updatePrintedStatus(orderId);
return true;
} else {
throw new Error(result.error || 'Print service failed');
}
} catch (error) {
console.error('Windows service print error:', error);
throw error;
}
}
// Fallback PDF download function
async function downloadPDFLabels(orderId, prodOrder, quantity) {
try {
// Generate PDF
const response = await fetch(`/generate_labels_pdf/${orderId}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
if (!response.ok) {
const data = await response.json().catch(() => ({}));
throw new Error(data.error || `HTTP ${response.status}`);
}
// Get filename from response headers
const contentDisposition = response.headers.get('Content-Disposition');
let filename = `labels_${prodOrder}_qty${quantity}.pdf`;
if (contentDisposition) {
const matches = contentDisposition.match(/filename="?([^"]+)"?/);
if (matches) filename = matches[1];
}
const blob = await response.blob();
// Download PDF
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
// Show success message
alert(`📄 PDF downloaded successfully!\n\n📊 Order: ${prodOrder}\n📦 Quantity: ${quantity} labels\n📁 File: ${filename}\n📋 Sequential: ${prodOrder}-001 to ${prodOrder}-${String(quantity).padStart(3, '0')}\n\n➡️ Please print the PDF manually`);
return true;
} catch (error) {
console.error('PDF download error:', error);
throw error;
}
}
// Update printed status in database
async function updatePrintedStatus(orderId) {
try {
const response = await fetch(`/update_printed_status/${orderId}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
if (response.ok) {
// Refresh the orders table
setTimeout(() => {
document.getElementById('check-db-btn').click();
}, 1000);
}
} catch (error) {
console.warn('Failed to update printed status:', error);
}
}
// PDF generation handler
function addPDFGenerationHandler() {
const printButton = document.getElementById('print-label-btn');
if (printButton) {
printButton.addEventListener('click', function(e) {
printButton.addEventListener('click', async function(e) {
e.preventDefault();
// Get selected order
@@ -594,61 +847,41 @@ function addPDFGenerationHandler() {
// Show loading state
const originalText = printButton.innerHTML;
printButton.innerHTML = '⏳ Generating PDF...';
const originalColor = printButton.style.background;
printButton.innerHTML = '⏳ Processing...';
printButton.disabled = true;
// Generate PDF
fetch(`/generate_labels_pdf/${orderId}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
.then(response => {
if (!response.ok) {
return response.json().then(data => {
throw new Error(data.error || `HTTP ${response.status}`);
});
try {
let success = false;
// Try Windows service first if available
if (printServiceAvailable) {
try {
success = await printLabelsWithService(orderId, prodOrder, quantity);
} catch (serviceError) {
console.warn('Windows service failed, falling back to PDF download:', serviceError);
printServiceAvailable = false; // Mark as unavailable for this session
updatePrintButtonForService(false);
}
}
// Get filename from response headers or create default
const contentDisposition = response.headers.get('Content-Disposition');
let filename = `labels_${prodOrder}_qty${quantity}.pdf`;
if (contentDisposition) {
const matches = contentDisposition.match(/filename="?([^"]+)"?/);
if (matches) filename = matches[1];
// Fallback to PDF download if service failed or unavailable
if (!success) {
success = await downloadPDFLabels(orderId, prodOrder, quantity);
}
return response.blob().then(blob => ({ blob, filename }));
})
.then(({ blob, filename }) => {
// Create download link
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
// Show success message
alert(`✅ PDF generated successfully!\n\n📄 ${quantity} labels created for ${prodOrder}\n📋 Sequential numbering: ${prodOrder}-001 to ${prodOrder}-${String(quantity).padStart(3, '0')}\n📁 File: ${filename}\n\n➡️ The PDF is ready to print from your browser!`);
// Refresh the orders table to show updated print status
setTimeout(() => {
document.getElementById('check-db-btn').click();
}, 1000);
})
.catch(error => {
console.error('PDF generation error:', error);
alert(`❌ Error generating PDF: ${error.message}\n\nPlease try again or contact support.`);
})
.finally(() => {
} catch (error) {
console.error('Print operation failed:', error);
alert(`❌ Print operation failed: ${error.message}\n\nPlease check:\n• Windows Print Service is running\n• Chrome extension is installed\n• Network connectivity\n• PDF generation permissions`);
} finally {
// Reset button state
printButton.innerHTML = originalText;
printButton.style.background = originalColor;
printButton.disabled = false;
});
// Recheck service availability for next operation
setTimeout(checkPrintServiceAvailability, 2000);
}
});
}
}