pos_bluetooth_thermal_printer/static/src/js/pos_session_integration.js
2025-11-21 05:52:53 +07:00

266 lines
9.0 KiB
JavaScript

/** @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<void>}
*/
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<void>}
*/
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<void>}
*/
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<void>}
*/
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}`);
}
}
});