feat: add device-specific bypass option for bluetooth printing in POS configuration
This commit is contained in:
parent
a0ce35c237
commit
cc38ae44c9
10
README.md
10
README.md
@ -189,6 +189,16 @@ For deployments with multiple tablets or workstations:
|
|||||||
- Both tablets use the same POS configuration in Odoo
|
- Both tablets use the same POS configuration in Odoo
|
||||||
- Each tablet prints to its own printer automatically
|
- 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
|
## Usage
|
||||||
|
|
||||||
### Normal Operation
|
### Normal Operation
|
||||||
|
|||||||
@ -45,6 +45,7 @@ export class BluetoothPrinterConfig extends Component {
|
|||||||
// UI state
|
// UI state
|
||||||
showConfiguration: false,
|
showConfiguration: false,
|
||||||
isTesting: false,
|
isTesting: false,
|
||||||
|
bypassBluetooth: false,
|
||||||
|
|
||||||
// Error state
|
// Error state
|
||||||
lastError: null
|
lastError: null
|
||||||
@ -60,6 +61,7 @@ export class BluetoothPrinterConfig extends Component {
|
|||||||
this.posConfigId = this.props.posConfigId || 1;
|
this.posConfigId = this.props.posConfigId || 1;
|
||||||
|
|
||||||
onWillStart(() => {
|
onWillStart(() => {
|
||||||
|
this.state.bypassBluetooth = this.storageManager.getBypassStatus(this.posConfigId);
|
||||||
this._loadSavedConfiguration();
|
this._loadSavedConfiguration();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -263,6 +265,21 @@ export class BluetoothPrinterConfig extends Component {
|
|||||||
this._saveConfiguration();
|
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
|
* Handle paper width change
|
||||||
* @param {Event} event - Change event
|
* @param {Event} event - Change event
|
||||||
|
|||||||
@ -76,6 +76,24 @@ patch(PosPrinterService.prototype, {
|
|||||||
// Check if a Bluetooth printer is configured (from localStorage)
|
// Check if a Bluetooth printer is configured (from localStorage)
|
||||||
// We don't need POS config - we check if user has configured a printer
|
// We don't need POS config - we check if user has configured a printer
|
||||||
const storage = new BluetoothPrinterStorage();
|
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
|
const config = storage.loadConfiguration(1); // Default POS config ID
|
||||||
|
|
||||||
if (!config || !config.deviceId) {
|
if (!config || !config.deviceId) {
|
||||||
|
|||||||
@ -14,6 +14,36 @@ export class BluetoothPrinterStorage {
|
|||||||
this._deviceId = null;
|
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
|
* Get or generate a unique device identifier
|
||||||
* Uses a combination of browser fingerprinting and stored UUID
|
* Uses a combination of browser fingerprinting and stored UUID
|
||||||
|
|||||||
@ -21,6 +21,25 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</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 -->
|
<!-- Scan Section -->
|
||||||
<div class="bluetooth-config-section">
|
<div class="bluetooth-config-section">
|
||||||
<h4>1. Scan for Devices</h4>
|
<h4>1. Scan for Devices</h4>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user