/** @odoo-module **/ import { patch } from "@web/core/utils/patch"; import { PosStore } from "@point_of_sale/app/store/pos_store"; import { getBluetoothPrintingServices } from "./pos_receipt_printer"; import { getErrorNotificationService } from "./error_notification_service"; /** * POS Session Integration * * Extends POS session lifecycle to: * - Load printer configuration on session start * - Auto-connect to configured bluetooth printer * - Handle session cleanup on close (disconnect printer) * - Provide connection status to POS UI */ // Patch PosStore to add session lifecycle hooks patch(PosStore.prototype, { /** * Override setup to initialize bluetooth printer on session start */ async setup() { await super.setup(...arguments); // Initialize bluetooth printing if enabled if (this.config.bluetooth_printer_enabled) { await this._initializeBluetoothPrinter(); } }, /** * Initialize bluetooth printer on session start * * @private * @returns {Promise} */ async _initializeBluetoothPrinter() { console.log('Initializing bluetooth printer for POS session...'); try { const notificationService = this.env?.services?.notification || null; const errorService = getErrorNotificationService(notificationService); const services = getBluetoothPrintingServices(notificationService); const { bluetoothManager, storageManager } = services; // Check if Web Bluetooth API is available if (!bluetoothManager.isBluetoothAvailable()) { console.warn('Web Bluetooth API not available in this browser'); errorService.showNotification( 'Bluetooth printing not available in this browser. Please use Chrome, Edge, or Opera.', 'warning' ); return; } // Load printer configuration from local storage const config = storageManager.loadConfiguration(this.config.id); if (!config) { // No printer configured for this device console.log('No bluetooth printer configured for this device'); this._promptPrinterConfiguration(); return; } console.log('Found printer configuration:', config.deviceName); // Enable auto-reconnect based on saved settings const autoReconnect = config.settings?.autoReconnect !== false; bluetoothManager.setAutoReconnect(autoReconnect); // Attempt to connect to the configured printer await this._connectToConfiguredPrinter(config); } catch (error) { console.error('Failed to initialize bluetooth printer:', error); const errorService = getErrorNotificationService(); errorService.handleError(error, { operation: 'initializeBluetoothPrinter' }); } }, /** * Connect to the configured bluetooth printer * * @private * @param {Object} config - Printer configuration * @returns {Promise} */ async _connectToConfiguredPrinter(config) { const notificationService = this.env?.services?.notification || null; const errorService = getErrorNotificationService(notificationService); const services = getBluetoothPrintingServices(notificationService); const { bluetoothManager } = services; try { console.log('Attempting to connect to printer:', config.deviceName); // Try to get the previously paired device const devices = await navigator.bluetooth.getDevices(); const device = devices.find(d => d.id === config.deviceId || d.name === config.deviceName ); if (!device) { console.warn('Previously configured printer not found'); errorService.showNotification( `Printer "${config.deviceName}" not found. Please pair the printer again.`, 'warning' ); this._promptPrinterConfiguration(); return; } // Connect to the printer await bluetoothManager.connectToPrinter(device); console.log('Successfully connected to bluetooth printer'); // Success notification is now handled by error service in bluetooth manager } catch (error) { console.error('Failed to connect to bluetooth printer:', error); // Error is now handled by error notification service in bluetooth manager // Just log additional context here errorService.logError(error, { operation: 'connectToConfiguredPrinter', deviceName: config.deviceName }); } }, /** * Prompt user to configure bluetooth printer * * @private */ _promptPrinterConfiguration() { const notificationService = this.env?.services?.notification || null; const errorService = getErrorNotificationService(notificationService); // Show notification prompting user to configure printer errorService.showNotification( 'No bluetooth printer configured. Please configure a printer in POS settings.', 'info' ); // Could trigger opening the configuration dialog here // For now, we just notify the user }, /** * Clean up bluetooth printer connection on session close * * @returns {Promise} */ async closePos() { // Disconnect bluetooth printer before closing session if (this.config.bluetooth_printer_enabled) { await this._cleanupBluetoothPrinter(); } // Call parent closePos return super.closePos(...arguments); }, /** * Clean up bluetooth printer connection * * @private * @returns {Promise} */ async _cleanupBluetoothPrinter() { console.log('Cleaning up bluetooth printer connection...'); try { const services = getBluetoothPrintingServices(); const { bluetoothManager } = services; // Check if there's an active connection const status = bluetoothManager.getConnectionStatus(); if (status === 'connected' || status === 'connecting') { console.log('Disconnecting bluetooth printer...'); await bluetoothManager.disconnect(); console.log('Bluetooth printer disconnected'); } } catch (error) { console.error('Error cleaning up bluetooth printer:', error); // Don't throw - session close should continue even if cleanup fails } }, /** * Get bluetooth printer connection status * * @returns {Object} Connection status information */ getBluetoothPrinterStatus() { if (!this.config.bluetooth_printer_enabled) { return { enabled: false, status: 'disabled' }; } try { const services = getBluetoothPrintingServices(); const { bluetoothManager } = services; return { enabled: true, ...bluetoothManager.getConnectionInfo() }; } catch (error) { console.error('Error getting bluetooth printer status:', error); return { enabled: true, status: 'error', lastError: error.message }; } }, /** * Get bluetooth printer manager instance * Used by UI components to access the manager * * @returns {BluetoothPrinterManager|null} */ getBluetoothPrinterManager() { if (!this.config.bluetooth_printer_enabled) { return null; } try { const services = getBluetoothPrintingServices(); return services.bluetoothManager; } catch (error) { console.error('Error getting bluetooth printer manager:', error); return null; } }, /** * Show bluetooth-related notification * * @private * @param {string} message - Notification message * @param {string} type - Notification type: 'success', 'warning', 'info', 'danger' */ _showBluetoothNotification(message, type = 'info') { // Use Odoo's notification system if available if (this.env.services.notification) { this.env.services.notification.add(message, { type: type, sticky: false }); } else { console.log(`[${type.toUpperCase()}] ${message}`); } } });