Skip to content

Commit e01d0bc

Browse files
✨ pos_qr_scan barcode scanning ability
1 parent 68a1f0d commit e01d0bc

File tree

12 files changed

+186
-38
lines changed

12 files changed

+186
-38
lines changed

pos_qr_scan/README.rst

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,31 @@
11
=========================
2-
QR Code Scanning in POS
2+
POS QR/Barcode Scanning
33
=========================
44

5-
Scans QR codes via device's camera.
5+
Scans QR codes and barcodes via device's camera.
6+
7+
the module supports next barcode codings:
8+
9+
* code 128
10+
* ean
11+
* ean 8
12+
* code 39
13+
* code 39 vin
14+
* codabar
15+
* upc
16+
* upc e
17+
* i2of5
18+
* code 93
619

720
Usage
821
=====
922

10-
To subscribe to scanning event use following code in js::
23+
To subscribe to qr scanning event use following code in js::
1124

1225
var core = require('web.core');
1326
core.bus.on('qr_scanned', this, function(value){
1427
// your handler here
15-
})
16-
28+
});
1729

1830
Credits
1931
=======
@@ -41,4 +53,4 @@ Usage instructions: `<doc/index.rst>`_
4153

4254
Changelog: `<doc/changelog.rst>`_
4355

44-
Tested on Odoo 11.0 c7171795f891335e8a8b6d5a6b796c28cea77fea
56+
Tested on Odoo 12.0 53dcdd5a9e22429a9638f68674264436ce21e42b

pos_qr_scan/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
2+
3+
from . import models

pos_qr_scan/__manifest__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
# Copyright 2018-2019 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
2+
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
3+
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
14
{
25
"name": """QR Code Scanning in POS""",
36
"summary": """Scans QR codes via device's camera""",
47
"category": "Point of Sale",
58
# "live_test_url": "",
69
"images": ["images/main.png"],
7-
"version": "12.0.1.0.2",
10+
"version": "12.0.2.0.0",
811
"application": False,
912

1013
"author": "IT-Projects LLC, KolushovAlexandr",
@@ -20,6 +23,7 @@
2023
"external_dependencies": {"python": [], "bin": []},
2124
"data": [
2225
"views/assets.xml",
26+
'views/pos_config.xml',
2327
],
2428
"qweb": [
2529
"static/src/xml/templates.xml",

pos_qr_scan/doc/changelog.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
`2.0.0`
2+
-------
3+
4+
- **Improvement:** - Barcode scanner added
5+
16
`1.0.2`
27
-------
38

pos_qr_scan/doc/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
=========================
2-
QR Code Scanning in POS
2+
POS QR/Barcode Scanning
33
=========================
44

55
Installation

pos_qr_scan/models/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)
2+
3+
from . import pos_config

pos_qr_scan/models/pos_config.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2019 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
2+
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
3+
4+
from odoo import api, fields, models
5+
6+
7+
class PosConfig(models.Model):
8+
_inherit = 'pos.config'
9+
10+
use_only_qr_scan = fields.Boolean('Only QR scanning')
11+
use_only_barcode_scan = fields.Boolean('Only Barcode scanning')
12+
13+
@api.onchange('use_only_qr_scan')
14+
def _onchange_use_only_qr_scan(self):
15+
if self.use_only_qr_scan:
16+
self.use_only_barcode_scan = False
17+
18+
@api.onchange('use_only_barcode_scan')
19+
def _onchange_use_only_barcode_scan(self):
20+
if self.use_only_barcode_scan:
21+
self.use_only_qr_scan = False

pos_qr_scan/static/lib/Quagga/quagga.min.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pos_qr_scan/static/src/js/qr_scan.js

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
2-
Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
2+
Copyright 2018-2019 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
33
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). */
44
odoo.define('pos_qr_scan', function(require){
55
var exports = {};
@@ -9,6 +9,7 @@ odoo.define('pos_qr_scan', function(require){
99
var gui = require('point_of_sale.gui');
1010
var PopupWidget = require('point_of_sale.popups');
1111
var screens = require('point_of_sale.screens');
12+
Quagga = window.Quagga;
1213

1314
var QrButton = screens.ActionButtonWidget.extend({
1415
template: 'QrButton',
@@ -32,17 +33,76 @@ odoo.define('pos_qr_scan', function(require){
3233
var self = this;
3334
this.gUM = false;
3435
this._super(options);
35-
this.generate_qr_scanner();
36+
this.prepare_video_element();
37+
var config = this.pos.config;
38+
if (config.use_only_qr_scan) {
39+
this.generate_qr_scanner();
40+
} else if (config.use_only_barcode_scan) {
41+
this.generate_barcode_scanner();
42+
} else {
43+
this.generate_qr_scanner();
44+
this.generate_barcode_scanner();
45+
}
46+
this.read_callback = options.read_callback || this.read;
47+
},
48+
init: function(parent, args) {
49+
this._super(parent, args);
50+
},
51+
generate_barcode_scanner: function () {
52+
var self = this;
53+
Quagga.init({
54+
inputStream : {
55+
name : "Live",
56+
type : "LiveStream",
57+
target: document.querySelector('#preview') // Or '#yourElement' (optional)
58+
},
59+
decoder : {
60+
readers : [
61+
"code_128_reader",
62+
"ean_reader",
63+
"ean_8_reader",
64+
"code_39_reader",
65+
"code_39_vin_reader",
66+
"codabar_reader",
67+
"upc_reader",
68+
"upc_e_reader",
69+
"i2of5_reader",
70+
"code_93_reader",
71+
]
72+
}
73+
}, function(err) {
74+
if (err) {
75+
console.log(err);
76+
return
77+
}
78+
console.log("Initialization finished. Ready to start");
79+
Quagga.start();
80+
});
81+
82+
Quagga.onDetected(function(result) {
83+
var code = result.codeResult.code;
84+
85+
if (this.lastResult !== code) {
86+
this.lastResult = code;
87+
var $node = null,
88+
canvas = Quagga.canvas.dom.image;
89+
self.read_callback(code, 'barcode');
90+
}
91+
});
3692
},
3793
click_cancel: function() {
38-
this.stop_camera();
3994
this._super(arguments);
95+
this.stop_camera();
4096
},
4197
stop_camera: function(camera){
4298
this.cam_is_on = false;
4399
if (this.stream){
44100
this.stream.getTracks()[0].stop();
45101
}
102+
if (!this.pos.config.use_only_qr_scan) {
103+
Quagga.stop();
104+
Quagga.offDetected();
105+
}
46106
},
47107
add_button: function(content) {
48108
var button = document.createElement('div');
@@ -64,16 +124,16 @@ odoo.define('pos_qr_scan', function(require){
64124
return cam.deviceId === id;
65125
});
66126
},
67-
generate_qr_scanner: function() {
68-
var options = false;
69-
var self = this;
127+
prepare_video_element: function() {
70128
this.video_element = document.getElementById("preview");
71129
$(this.video_element).on('click',function(){
72130
self.click_cancel();
73131
});
132+
var options = false;
133+
var self = this;
74134
if(navigator.mediaDevices && navigator.mediaDevices.enumerateDevices){
75135
this.capture_timeout = 700;
76-
try{
136+
try {
77137
navigator.mediaDevices.enumerateDevices().then(function(devices) {
78138
self.video_devices = _.filter(devices, function(d) {
79139
return d.kind === 'videoinput';
@@ -96,31 +156,35 @@ odoo.define('pos_qr_scan', function(require){
96156
}
97157
self.start_webcam(options);
98158
});
99-
}
100-
catch(e){
159+
} catch(e){
101160
alert(e);
102161
}
103-
}
104-
else{
162+
} else{
105163
console.log("no navigator.mediaDevices.enumerateDevices" );
106-
this.start_webcam(options);
107164
}
108165
},
166+
generate_qr_scanner: function() {
167+
this.cam_is_on = true;
168+
setTimeout(function(){
169+
self.captureToCanvas();
170+
}, this.capture_timeout);
171+
},
109172

110-
read: function(result){
173+
read: function(result, method){
174+
method = method || 'qr';
111175
// Trigger event on scanning and close camera window
112176
if (this.pos.debug){
113-
console.log('QR scanned', result);
177+
console.log(method.toUpperCase() + ' scanned', result);
114178
}
115-
core.bus.trigger('qr_scanned', result);
116-
posmodel.gui.popup_instances.qr_scan.click_cancel();
179+
this.click_cancel();
180+
core.bus.trigger(method + '_scanned', result);
117181
},
118182

119183
start_webcam: function(options){
120184
var self = this;
121185
this.initCanvas(800, 600);
122186
qrcode.callback = function(value){
123-
self.read(value);
187+
self.read_callback(value, 'qr');
124188
}
125189
if(navigator.mediaDevices.getUserMedia){
126190
navigator.mediaDevices.getUserMedia({video: options, audio: false}).
@@ -141,11 +205,6 @@ odoo.define('pos_qr_scan', function(require){
141205
webkit = true;
142206
navigator.webkitGetUserMedia({video:options, audio: false}, success, error);
143207
}
144-
145-
this.cam_is_on = true;
146-
setTimeout(function(){
147-
self.captureToCanvas();
148-
}, this.capture_timeout);
149208
},
150209

151210
success: function(stream){

pos_qr_scan/static/src/xml/templates.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
3+
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). -->
24
<templates id="template" xml:space="preserve">
35

46
<t t-name="QrButton">
57
<div class='control-button'>
6-
<i class='fa fa-qrcode' /> QR Scan
8+
<i class='fa fa-qrcode' /> QR / Barcode Scan
79
</div>
810
</t>
911

@@ -15,7 +17,7 @@
1517
</div>
1618
<div class="transparent_sidebar">
1719
<div class="title">
18-
<p>QR Scanning</p>
20+
<p>QR / Barcode Scanning</p>
1921
</div>
2022
<div class="body">
2123
<p>Cameras:</p>

0 commit comments

Comments
 (0)