LaOsaCoop/Odoo16#74 add pos_barcode_block_on_error
This commit is contained in:
parent
f4bc2ee66b
commit
a24b4392d6
4 changed files with 134 additions and 0 deletions
35
pos_barcode_block_on_error/README.rst
Normal file
35
pos_barcode_block_on_error/README.rst
Normal 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
|
||||||
16
pos_barcode_block_on_error/__manifest__.py
Normal file
16
pos_barcode_block_on_error/__manifest__.py
Normal 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,
|
||||||
|
}
|
||||||
16
pos_barcode_block_on_error/static/src/css/error_popup.css
Normal file
16
pos_barcode_block_on_error/static/src/css/error_popup.css
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue