feat: implement dynamic POS configuration ID resolution and UI updates for printer bypass functionality

This commit is contained in:
Suherdy Yacob 2026-05-20 06:59:57 +07:00
parent cc38ae44c9
commit 0f225a7bfb
5 changed files with 43 additions and 11 deletions

View File

@ -68,6 +68,12 @@
box-shadow: 0 0 8px rgba(220, 53, 69, 0.6);
}
/* Bypassed Status - Grey */
.bluetooth-status-indicator-bypassed {
background-color: #6c757d;
box-shadow: 0 0 8px rgba(108, 117, 125, 0.4);
}
/* Pulse Animation for Connecting State */
@keyframes bluetooth-pulse {
0% {

View File

@ -265,14 +265,15 @@ 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);
// Notify connection status widget about the change immediately
if (this.bluetoothManager && typeof this.bluetoothManager._emit === 'function') {
this.bluetoothManager._emit('connection-status-changed', this.bluetoothManager.getConnectionInfo());
}
if (this.state.bypassBluetooth) {
this._showNotification('Bluetooth printer bypassed on this device', 'info');
} else {

View File

@ -4,6 +4,7 @@ import { Component, useState, onWillStart, onWillUnmount } from "@odoo/owl";
import { useService } from "@web/core/utils/hooks";
import { BluetoothPrinterConfig } from "./bluetooth_printer_config";
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
import { BluetoothPrinterStorage } from "./storage_manager";
/**
* Bluetooth Connection Status Widget
@ -23,6 +24,7 @@ export class BluetoothConnectionStatus extends Component {
setup() {
this.dialog = useService("dialog");
this.notification = useService("notification");
this.storageManager = new BluetoothPrinterStorage();
this.state = useState({
status: 'disconnected',
@ -109,6 +111,12 @@ export class BluetoothConnectionStatus extends Component {
this.state.reconnectAttempts = info.reconnectAttempts;
this.state.isReconnecting = info.isReconnecting;
this.state.timestamp = info.timestamp;
// Check if bypassed on this device
const posConfigId = this.props.posConfigId || 1;
if (this.storageManager.getBypassStatus(posConfigId)) {
this.state.status = 'bypassed';
}
}
/**
@ -135,6 +143,8 @@ export class BluetoothConnectionStatus extends Component {
return 'fa fa-bluetooth-b';
case 'connecting':
return 'fa fa-bluetooth';
case 'bypassed':
return 'fa fa-ban';
case 'error':
return 'fa fa-exclamation-triangle';
default:
@ -158,6 +168,8 @@ export class BluetoothConnectionStatus extends Component {
return this.state.isReconnecting
? `Reconnecting... (${this.state.reconnectAttempts}/3)`
: 'Connecting...';
case 'bypassed':
return 'Printer Bypassed (Web Print)';
case 'error':
return 'Connection Error';
default:

View File

@ -50,6 +50,11 @@ const originalPrintHtml = PosPrinterService.prototype.printHtml;
// Patch the PosPrinterService to add bluetooth printing functionality
patch(PosPrinterService.prototype, {
setup(env) {
this.env = env;
super.setup(...arguments);
},
/**
* Override the printHtml method to use bluetooth printer
* Falls back to browser print on any failure
@ -74,15 +79,17 @@ patch(PosPrinterService.prototype, {
console.log('[BluetoothPrint] Web Bluetooth API available');
// 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();
// Get POS config ID dynamically from POS store service
const pos = this.env?.services?.pos;
const posConfigId = pos?.config?.id || 1;
// 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)) {
if (storage.getBypassStatus(posConfigId)) {
console.log('[BluetoothPrint] Bluetooth printer bypassed on this device, using standard print');
try {
const result = await originalPrintHtml.call(this, el);
const result = await originalPrintHtml.apply(this, arguments);
if (result === false) {
await this._printViaBrowserDialog(el);
}
@ -94,13 +101,13 @@ patch(PosPrinterService.prototype, {
}
}
const config = storage.loadConfiguration(1); // Default POS config ID
const config = storage.loadConfiguration(posConfigId);
if (!config || !config.deviceId) {
console.log('[BluetoothPrint] No Bluetooth printer configured, using standard print');
console.log('[BluetoothPrint] Calling originalPrintHtml with:', el);
try {
const result = await originalPrintHtml.call(this, el);
const result = await originalPrintHtml.apply(this, arguments);
console.log('[BluetoothPrint] originalPrintHtml returned:', result);
// If original method returned false, it didn't handle the print
@ -174,7 +181,7 @@ patch(PosPrinterService.prototype, {
} catch (dialogError) {
console.error('[BluetoothPrint] Browser print dialog also failed:', dialogError);
// Last resort - try original method
return await originalPrintHtml.call(this, el);
return await originalPrintHtml.apply(this, arguments);
}
}
},

View File

@ -54,6 +54,12 @@ patch(PosStore.prototype, {
return;
}
// Check if user has explicitly bypassed bluetooth printer for this device
if (storageManager.getBypassStatus(this.config.id)) {
console.log('Bluetooth printer is bypassed for this device. Skipping initialization.');
return;
}
// Load printer configuration from local storage
const config = storageManager.loadConfiguration(this.config.id);