LaOsaCoop/Odoo16#74 add pos_barcode_block_on_error

This commit is contained in:
Luis 2025-09-17 12:03:08 +02:00
parent f4bc2ee66b
commit a24b4392d6
4 changed files with 134 additions and 0 deletions

View file

@ -0,0 +1,35 @@
POS: Block barcode scanning on error popup
=========================================
Summary
-------
This Point of Sale extension prevents the POS from processing further barcode
scans while the "barcode not found" error popup is visible. It also avoids the
scanner's Enter/Escape keystrokes from closing the popup, so the cashier must
explicitly dismiss it (click/tap) before continuing.
Features
--------
- Takes exclusive control of the barcode reader while the error popup is shown.
- Prevents scanner-triggered keyboard "clicks" from closing the popup.
- Keeps the initial error message visible; subsequent scans are ignored.
- Includes CSS to highlight the error popup for better visibility.
Usage
-----
- Scan a non-existent barcode in the POS.
- The error popup will show.
- Further scans will be ignored while the popup is visible.
- Close the popup via mouse/touch to resume scanning.
Limitations
-----------
- While the popup is open, all barcode actions are blocked (product, client,
weight, price, discount, GS1, etc.). Customize the hook if you need
exceptions.
Credits
-------
- Author: Criptomart
- License: AGPL-3

View file

@ -0,0 +1,16 @@
{
"name": "POS: Block barcode scanning on error popup",
"version": "16.0.1.0.0",
"summary": "Stops processing new barcodes while ErrorBarcodePopup is shown.",
"category": "Point of Sale",
"license": "AGPL-3",
"author": "Criptomart",
"depends": ["point_of_sale"],
"assets": {
"point_of_sale.assets": [
"pos_barcode_block_on_error/static/src/js/error_barcode_popup_block.js",
"pos_barcode_block_on_error/static/src/css/error_popup.css",
],
},
"installable": True,
}

View file

@ -0,0 +1,16 @@
/* Emphasize the error popup for unknown barcode */
/* Make the whole popup background red and invert text for visibility */
.popup.popup-barcode {
background-color: #c62828 !important; /* strong red background */
color: #fff !important; /* default text to white */
}
.popup.popup-barcode .title,
.popup.popup-barcode .body {
color: #fff !important;
font-weight: 600;
}
.popup.popup-barcode .footer .button.cancel {
background: #fff !important; /* white button on red bg */
color: #c62828 !important; /* red text */
border-color: #fff !important;
}

View file

@ -0,0 +1,67 @@
/** @odoo-module */
/**
* Block barcode processing while ErrorBarcodePopup is visible by taking
* exclusive control of the barcode reader, and release it when closing.
*/
import Registries from "point_of_sale.Registries";
import ErrorBarcodePopup from "point_of_sale.ErrorBarcodePopup";
import { useBarcodeReader } from "point_of_sale.custom_hooks";
const ErrorBarcodePopupBlock = (ErrorPopup) =>
class extends ErrorPopup {
setup() {
super.setup(...arguments);
// Prevent keyboard-triggered clicks (Enter on focused button)
owl.onMounted(() => {
this.__clickHandler = (ev) => {
// Keyboard-triggered clicks usually have detail === 0
if (ev && ev.detail === 0) {
ev.preventDefault();
ev.stopPropagation();
}
};
if (this.el) {
this.el.addEventListener('click', this.__clickHandler, true);
}
});
// Take exclusive control using POS hook so subsequent scans are ignored
useBarcodeReader({
product: () => {},
quantity: () => {},
weight: () => {},
price: () => {},
client: () => {},
discount: () => {},
cashier: () => {},
error: () => {},
gs1: () => {},
}, true);
}
willUnmount() {
// useBarcodeReader cleans up automatically on unmount
if (this.el && this.__clickHandler) {
this.el.removeEventListener('click', this.__clickHandler, true);
}
super.willUnmount(...arguments);
}
// Only accept real pointer clicks to close the popup; ignore keyboard/programmatic events
async confirm(ev) {
if (ev && ev.type === 'click' && ev.isTrusted && ev.detail > 0) {
return super.confirm();
}
}
cancel(ev) {
if (ev && ev.type === 'click' && ev.isTrusted && ev.detail > 0) {
return super.cancel();
}
}
};
Registries.Component.extend(ErrorBarcodePopup, ErrorBarcodePopupBlock);
export default ErrorBarcodePopup;