summaryrefslogtreecommitdiff
path: root/addons/point_of_sale/static/src/js/barcode_reader.js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/point_of_sale/static/src/js/barcode_reader.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/point_of_sale/static/src/js/barcode_reader.js')
-rw-r--r--addons/point_of_sale/static/src/js/barcode_reader.js158
1 files changed, 158 insertions, 0 deletions
diff --git a/addons/point_of_sale/static/src/js/barcode_reader.js b/addons/point_of_sale/static/src/js/barcode_reader.js
new file mode 100644
index 00000000..10f5b9a2
--- /dev/null
+++ b/addons/point_of_sale/static/src/js/barcode_reader.js
@@ -0,0 +1,158 @@
+odoo.define('point_of_sale.BarcodeReader', function (require) {
+"use strict";
+
+var core = require('web.core');
+
+// this module interfaces with the barcode reader. It assumes the barcode reader
+// is set-up to act like a keyboard. Use connect() and disconnect() to activate
+// and deactivate the barcode reader. Use set_action_callbacks to tell it
+// what to do when it reads a barcode.
+var BarcodeReader = core.Class.extend({
+ actions:[
+ 'product',
+ 'cashier',
+ 'client',
+ ],
+
+ init: function (attributes) {
+ this.pos = attributes.pos;
+ this.action_callbacks = {};
+ this.exclusive_callbacks = {};
+ this.proxy = attributes.proxy;
+ this.remote_scanning = false;
+ this.remote_active = 0;
+
+ this.barcode_parser = attributes.barcode_parser;
+
+ this.action_callback_stack = [];
+
+ core.bus.on('barcode_scanned', this, function (barcode) {
+ this.scan(barcode);
+ });
+ },
+
+ set_barcode_parser: function (barcode_parser) {
+ this.barcode_parser = barcode_parser;
+ },
+
+ // when a barcode is scanned and parsed, the callback corresponding
+ // to its type is called with the parsed_barcode as a parameter.
+ // (parsed_barcode is the result of parse_barcode(barcode))
+ //
+ // callbacks is a Map of 'actions' : callback(parsed_barcode)
+ // that sets the callback for each action. if a callback for the
+ // specified action already exists, it is replaced.
+ //
+ // possible actions include :
+ // 'product' | 'cashier' | 'client' | 'discount'
+ set_action_callback: function (name, callback) {
+ if (this.action_callbacks[name]) {
+ this.action_callbacks[name].add(callback);
+ } else {
+ this.action_callbacks[name] = new Set([callback]);
+ }
+ },
+
+ remove_action_callback: function(name, callback) {
+ if (!callback) {
+ delete this.action_callbacks[name];
+ return;
+ }
+ const callbacks = this.action_callbacks[name];
+ if (callbacks) {
+ callbacks.delete(callback);
+ if (callbacks.size === 0) {
+ delete this.action_callbacks[name];
+ }
+ }
+ },
+
+ /**
+ * Allow setting of exclusive callbacks. If there are exclusive callbacks,
+ * these callbacks are called neglecting the regular callbacks. This is
+ * useful for rendered Components that wants to take exclusive access
+ * to the barcode reader.
+ *
+ * @param {String} name
+ * @param {Function} callback function that takes parsed barcode
+ */
+ set_exclusive_callback: function (name, callback) {
+ if (this.exclusive_callbacks[name]) {
+ this.exclusive_callbacks[name].add(callback);
+ } else {
+ this.exclusive_callbacks[name] = new Set([callback]);
+ }
+ },
+
+ remove_exclusive_callback: function (name, callback) {
+ if (!callback) {
+ delete this.exclusive_callbacks[name];
+ return;
+ }
+ const callbacks = this.exclusive_callbacks[name];
+ if (callbacks) {
+ callbacks.delete(callback);
+ if (callbacks.size === 0) {
+ delete this.exclusive_callbacks[name];
+ }
+ }
+ },
+
+ scan: function (code) {
+ if (!code) return;
+
+ const callbacks = Object.keys(this.exclusive_callbacks).length
+ ? this.exclusive_callbacks
+ : this.action_callbacks;
+
+ const parsed_result = this.barcode_parser.parse_barcode(code);
+ if (callbacks[parsed_result.type]) {
+ [...callbacks[parsed_result.type]].map((cb) => cb(parsed_result));
+ } else if (callbacks.error) {
+ [...callbacks.error].map((cb) => cb(parsed_result));
+ } else {
+ console.warn('Ignored Barcode Scan:', parsed_result);
+ }
+
+ },
+
+ // the barcode scanner will listen on the hw_proxy/scanner interface for
+ // scan events until disconnect_from_proxy is called
+ connect_to_proxy: function () {
+ var self = this;
+ this.remote_scanning = true;
+ if (this.remote_active >= 1) {
+ return;
+ }
+ this.remote_active = 1;
+
+ function waitforbarcode(){
+ return self.proxy.connection.rpc('/hw_proxy/scanner',{},{shadow: true, timeout:7500})
+ .then(function (barcode) {
+ if (!self.remote_scanning) {
+ self.remote_active = 0;
+ return;
+ }
+ self.scan(barcode);
+ waitforbarcode();
+ },
+ function () {
+ if (!self.remote_scanning) {
+ self.remote_active = 0;
+ return;
+ }
+ waitforbarcode();
+ });
+ }
+ waitforbarcode();
+ },
+
+ // the barcode scanner will stop listening on the hw_proxy/scanner remote interface
+ disconnect_from_proxy: function () {
+ this.remote_scanning = false;
+ },
+});
+
+return BarcodeReader;
+
+});