feat: add device-specific bypass option for bluetooth printing in POS configuration

This commit is contained in:
Suherdy Yacob 2026-05-19 10:03:56 +07:00
parent a0ce35c237
commit cc38ae44c9
5 changed files with 94 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -21,6 +21,25 @@
</span>
</div>
<!-- Bypass Toggle Section -->
<div class="bluetooth-config-section" style="background-color: #fff3cd; border-color: #ffeeba; color: #856404; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
<div class="form-group form-check" style="margin-bottom: 0;">
<input type="checkbox"
class="form-check-input"
id="bypassBluetooth"
t-model="state.bypassBluetooth"
t-on-change="onBypassChange"
style="width: 1.5em; height: 1.5em; margin-top: 0.1em; cursor: pointer;"/>
<label class="form-check-label" for="bypassBluetooth" style="margin-left: 10px; font-weight: bold; font-size: 1.1em; cursor: pointer;">
Bypass Bluetooth Printer on this device
</label>
<p class="form-text mt-2 mb-0 text-muted" style="margin-left: 32px;">
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.
</p>
</div>
</div>
<!-- Scan Section -->
<div class="bluetooth-config-section">
<h4>1. Scan for Devices</h4>