diff --git a/README.md b/README.md index 4ea44d9..8dd0953 100755 --- a/README.md +++ b/README.md @@ -189,6 +189,16 @@ For deployments with multiple tablets or workstations: - Both tablets use the same POS configuration in Odoo - Each tablet prints to its own printer automatically +### Bypassing Bluetooth Printer on Specific Devices + +If you have a setup where multiple devices share the same POS configuration, but one device has a built-in printer (or uses another printing method) and shouldn't use the Bluetooth thermal printer, you can explicitly bypass the Bluetooth printer on that specific device: + +1. Open the POS session on the device that should **not** use the Bluetooth printer. +2. Click the Bluetooth printer icon in the navbar. +3. In the configuration dialog, check the **Bypass Bluetooth Printer on this device** checkbox. +4. This device will now ignore the Bluetooth printing logic and fall back to Odoo's standard printing (allowing built-in printers to intercept it normally). +5. Other devices using the same POS configuration will remain unaffected and can continue using their Bluetooth printers. + ## Usage ### Normal Operation diff --git a/static/src/js/bluetooth_printer_config.js b/static/src/js/bluetooth_printer_config.js index f29c4c1..dd50720 100755 --- a/static/src/js/bluetooth_printer_config.js +++ b/static/src/js/bluetooth_printer_config.js @@ -45,6 +45,7 @@ export class BluetoothPrinterConfig extends Component { // UI state showConfiguration: false, isTesting: false, + bypassBluetooth: false, // Error state lastError: null @@ -60,6 +61,7 @@ export class BluetoothPrinterConfig extends Component { this.posConfigId = this.props.posConfigId || 1; onWillStart(() => { + this.state.bypassBluetooth = this.storageManager.getBypassStatus(this.posConfigId); this._loadSavedConfiguration(); }); } @@ -263,6 +265,21 @@ export class BluetoothPrinterConfig extends Component { this._saveConfiguration(); } + /** + * Handle bypass toggle + * @param {Event} event - Change event + */ + onBypassChange(event) { + this.state.bypassBluetooth = event.target.checked; + this.storageManager.setBypassStatus(this.posConfigId, this.state.bypassBluetooth); + + if (this.state.bypassBluetooth) { + this._showNotification('Bluetooth printer bypassed on this device', 'info'); + } else { + this._showNotification('Bluetooth printer enabled on this device', 'info'); + } + } + /** * Handle paper width change * @param {Event} event - Change event diff --git a/static/src/js/pos_receipt_printer.js b/static/src/js/pos_receipt_printer.js index 139711c..e0585d6 100755 --- a/static/src/js/pos_receipt_printer.js +++ b/static/src/js/pos_receipt_printer.js @@ -76,6 +76,24 @@ patch(PosPrinterService.prototype, { // Check if a Bluetooth printer is configured (from localStorage) // We don't need POS config - we check if user has configured a printer const storage = new BluetoothPrinterStorage(); + + // Check if user has explicitly bypassed bluetooth printer for this device + // We default to config ID 1 since it's hardcoded here as well + if (storage.getBypassStatus(1)) { + console.log('[BluetoothPrint] Bluetooth printer bypassed on this device, using standard print'); + try { + const result = await originalPrintHtml.call(this, el); + if (result === false) { + await this._printViaBrowserDialog(el); + } + return true; + } catch (error) { + console.error('[BluetoothPrint] Error calling originalPrintHtml:', error); + await this._printViaBrowserDialog(el); + return true; + } + } + const config = storage.loadConfiguration(1); // Default POS config ID if (!config || !config.deviceId) { diff --git a/static/src/js/storage_manager.js b/static/src/js/storage_manager.js index 51094db..250ff85 100755 --- a/static/src/js/storage_manager.js +++ b/static/src/js/storage_manager.js @@ -14,6 +14,36 @@ export class BluetoothPrinterStorage { this._deviceId = null; } + /** + * Get the bypass status for this device and pos config + * + * @param {number} posConfigId - POS configuration ID + * @returns {boolean} Whether bluetooth printer is bypassed + */ + getBypassStatus(posConfigId) { + if (!posConfigId) return false; + const deviceId = this.getDeviceId(); + const key = `${this.storagePrefix}_bypass_${deviceId}_${posConfigId}`; + return localStorage.getItem(key) === 'true'; + } + + /** + * Set the bypass status for this device and pos config + * + * @param {number} posConfigId - POS configuration ID + * @param {boolean} status - Bypass status + */ + setBypassStatus(posConfigId, status) { + if (!posConfigId) return; + const deviceId = this.getDeviceId(); + const key = `${this.storagePrefix}_bypass_${deviceId}_${posConfigId}`; + if (status) { + localStorage.setItem(key, 'true'); + } else { + localStorage.removeItem(key); + } + } + /** * Get or generate a unique device identifier * Uses a combination of browser fingerprinting and stored UUID diff --git a/static/src/xml/bluetooth_printer_config.xml b/static/src/xml/bluetooth_printer_config.xml index 6240afa..9137244 100755 --- a/static/src/xml/bluetooth_printer_config.xml +++ b/static/src/xml/bluetooth_printer_config.xml @@ -21,6 +21,25 @@ + +
+
+ + +

+ Check this if this specific device uses a built-in printer or another printing method. + This setting is device-specific and will not affect other POS devices. +

+
+
+

1. Scan for Devices