[IMP] barcodes,point_of_sale : parse_code js function moved to barcodes module
This commit is contained in:
committed by
Frédéric van der Essen
parent
d18e7f008c
commit
c72674a01e
@@ -44,6 +44,7 @@ This module unlocks several advanced barcode features:
|
||||
'data/barcodes_data.xml',
|
||||
'barcodes_view.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'views/templates.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
function openerp_barcode_reader(instance,module){
|
||||
|
||||
module.BarcodeReader = instance.web.Class.extend({
|
||||
|
||||
// returns the checksum of the ean13, or -1 if the ean has not the correct length, ean must be a string
|
||||
ean_checksum: function(ean){
|
||||
var code = ean.split('');
|
||||
if(code.length !== 13){
|
||||
return -1;
|
||||
}
|
||||
var oddsum = 0, evensum = 0, total = 0;
|
||||
code = code.reverse().splice(1);
|
||||
for(var i = 0; i < code.length; i++){
|
||||
if(i % 2 == 0){
|
||||
oddsum += Number(code[i]);
|
||||
}else{
|
||||
evensum += Number(code[i]);
|
||||
}
|
||||
}
|
||||
total = oddsum * 3 + evensum;
|
||||
return Number((10 - total % 10) % 10);
|
||||
},
|
||||
|
||||
// returns a valid zero padded ean13 from an ean prefix. the ean prefix must be a string.
|
||||
sanitize_ean: function(ean){
|
||||
ean = ean.substr(0,13);
|
||||
|
||||
for(var n = 0, count = (13 - ean.length); n < count; n++){
|
||||
ean = ean + '0';
|
||||
}
|
||||
return ean.substr(0,12) + this.ean_checksum(ean);
|
||||
},
|
||||
|
||||
// attempts to interpret a barcode (string encoding a barcode Code-128)
|
||||
// it will return an object containing various information about the barcode.
|
||||
// most importantly :
|
||||
// - code : the barcode
|
||||
// - type : the type of the barcode (e.g. alias, unit product, weighted product...)
|
||||
//
|
||||
// - value : if the barcode encodes a numerical value, it will be put there
|
||||
// - base_code : the barcode with all the encoding parts set to zero; the one put on
|
||||
// the product in the backend
|
||||
parse_barcode: function(barcode, nomenclature){
|
||||
var self = this;
|
||||
var parsed_result = {
|
||||
encoding: '',
|
||||
type:'error',
|
||||
code:barcode,
|
||||
base_code: barcode,
|
||||
value: 0,
|
||||
};
|
||||
|
||||
if (!nomenclature) {
|
||||
console.log(this);
|
||||
console.log("nomenclature does not exist");
|
||||
return parsed_result;
|
||||
}
|
||||
|
||||
function match_pattern(barcode,pattern){
|
||||
if(barcode.length < pattern.replace(/[{}]/g, '').length){
|
||||
return false; // Match of this pattern is impossible
|
||||
}
|
||||
var numerical_content = false; // Used to detect when we are between { }
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(p === "{" || p === "}"){
|
||||
numerical_content = !numerical_content;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!numerical_content && p !== '*' && p !== barcode[j]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function get_value(barcode,pattern){
|
||||
var value = 0;
|
||||
var decimals = 0;
|
||||
var numerical_content = false;
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(!numerical_content && p !== "{"){
|
||||
continue;
|
||||
}
|
||||
else if(p === "{"){
|
||||
numerical_content = true;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
else if(p === "}"){
|
||||
break;
|
||||
}
|
||||
|
||||
var v = parseInt(barcode[j]);
|
||||
if(p === 'N'){
|
||||
value *= 10;
|
||||
value += v;
|
||||
}else if(p === 'D'){ // FIXME precision ....
|
||||
decimals += 1;
|
||||
value += v * Math.pow(10,-decimals);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function get_basecode(barcode,pattern,encoding){
|
||||
var base = '';
|
||||
var numerical_content = false;
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(p === "{" || p === "}"){
|
||||
numerical_content = !numerical_content;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(numerical_content){
|
||||
base += '0';
|
||||
}
|
||||
else{
|
||||
base += barcode[j];
|
||||
}
|
||||
}
|
||||
for(i=j; i<barcode.length; i++){ // Read the rest of the barcode
|
||||
base += barcode[i];
|
||||
}
|
||||
if(encoding === "ean13"){
|
||||
base = self.sanitize_ean(base);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
var rules = nomenclature.rules;
|
||||
for (var i = 0; i < rules.length; i++) {
|
||||
if (match_pattern(barcode,rules[i].pattern)) {
|
||||
if(rules[i].type === 'alias') {
|
||||
barcode = rules[i].alias;
|
||||
parsed_result.code = barcode;
|
||||
parsed_result.type = 'alias';
|
||||
}
|
||||
else {
|
||||
parsed_result.encoding = rules[i].encoding;
|
||||
parsed_result.type = rules[i].type;
|
||||
parsed_result.value = get_value(barcode,rules[i].pattern);
|
||||
parsed_result.base_code = get_basecode(barcode,rules[i].pattern,parsed_result.encoding);
|
||||
return parsed_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parsed_result;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
openerp.barcodes = function(instance) {
|
||||
"use strict";
|
||||
|
||||
instance.barcode_reader = {};
|
||||
var module = instance.barcode_reader;
|
||||
|
||||
openerp_barcode_reader(instance,module); // import barcodes.js
|
||||
};
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- <template id="assets_frontend" inherit_id="web.assets_common">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/barcodes.js"></script>
|
||||
</xpath>
|
||||
</template>-->
|
||||
<template id="assets_backend" name="barcodes assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/barcode_reader.js"></script>
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/main.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -3,6 +3,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
||||
"use strict";
|
||||
|
||||
var _t = instance.web._t;
|
||||
var barcode_reader_module = instance.barcode_reader;
|
||||
|
||||
// the JobQueue schedules a sequence of 'jobs'. each job is
|
||||
// a function returning a deferred. the queue waits for each job to finish
|
||||
@@ -441,7 +442,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
||||
// 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.
|
||||
module.BarcodeReader = instance.web.Class.extend({
|
||||
//module.BarcodeReader = instance.web.Class.extend({
|
||||
barcode_reader_module.BarcodeReader.include({
|
||||
actions:[
|
||||
'product',
|
||||
'cashier',
|
||||
@@ -501,160 +503,9 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
||||
}
|
||||
},
|
||||
|
||||
// returns the checksum of the ean13, or -1 if the ean has not the correct length, ean must be a string
|
||||
ean_checksum: function(ean){
|
||||
var code = ean.split('');
|
||||
if(code.length !== 13){
|
||||
return -1;
|
||||
}
|
||||
var oddsum = 0, evensum = 0, total = 0;
|
||||
code = code.reverse().splice(1);
|
||||
for(var i = 0; i < code.length; i++){
|
||||
if(i % 2 == 0){
|
||||
oddsum += Number(code[i]);
|
||||
}else{
|
||||
evensum += Number(code[i]);
|
||||
}
|
||||
}
|
||||
total = oddsum * 3 + evensum;
|
||||
return Number((10 - total % 10) % 10);
|
||||
},
|
||||
|
||||
// returns a valid zero padded ean13 from an ean prefix. the ean prefix must be a string.
|
||||
sanitize_ean:function(ean){
|
||||
ean = ean.substr(0,13);
|
||||
|
||||
for(var n = 0, count = (13 - ean.length); n < count; n++){
|
||||
ean = ean + '0';
|
||||
}
|
||||
return ean.substr(0,12) + this.ean_checksum(ean);
|
||||
},
|
||||
|
||||
// attempts to interpret a barcode (string encoding a barcode Code-128)
|
||||
// it will return an object containing various information about the barcode.
|
||||
// most importantly :
|
||||
// - code : the barcode
|
||||
// - type : the type of the barcode:
|
||||
// 'price' | 'weight' | 'product' | 'cashier' | 'client' | 'discount' | 'lot' |
|
||||
// 'package' | 'location' | 'error'
|
||||
//
|
||||
// - value : if the barcode encodes a numerical value, it will be put there
|
||||
// - base_code : the barcode with all the encoding parts set to zero; the one put on
|
||||
// the product in the backend
|
||||
parse_barcode: function(barcode){
|
||||
var self = this;
|
||||
var parsed_result = {
|
||||
encoding: '',
|
||||
type:'error',
|
||||
code:barcode,
|
||||
base_code: barcode,
|
||||
value: 0,
|
||||
};
|
||||
|
||||
if (!this.pos.nomenclature) {
|
||||
return parsed_result;
|
||||
}
|
||||
|
||||
function match_pattern(barcode,pattern){
|
||||
if(barcode.length < pattern.replace(/[{}]/g, '').length){
|
||||
return false; // Match of this pattern is impossible
|
||||
}
|
||||
var numerical_content = false; // Used to detect when we are between { }
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(p === "{" || p === "}"){
|
||||
numerical_content = !numerical_content;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!numerical_content && p !== '*' && p !== barcode[j]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function get_value(barcode,pattern){
|
||||
var value = 0;
|
||||
var decimals = 0;
|
||||
var numerical_content = false;
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(!numerical_content && p !== "{"){
|
||||
continue;
|
||||
}
|
||||
else if(p === "{"){
|
||||
numerical_content = true;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
else if(p === "}"){
|
||||
break;
|
||||
}
|
||||
|
||||
var v = parseInt(barcode[j]);
|
||||
if(p === 'N'){
|
||||
value *= 10;
|
||||
value += v;
|
||||
}else if(p === 'D'){ // FIXME precision ....
|
||||
decimals += 1;
|
||||
value += v * Math.pow(10,-decimals);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function get_basecode(barcode,pattern,encoding){
|
||||
var base = '';
|
||||
var numerical_content = false;
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(p === "{" || p === "}"){
|
||||
numerical_content = !numerical_content;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(numerical_content){
|
||||
base += '0';
|
||||
}
|
||||
else{
|
||||
base += barcode[j];
|
||||
}
|
||||
}
|
||||
for(i=j; i<barcode.length; i++){ // Read the rest of the barcode
|
||||
base += barcode[i];
|
||||
}
|
||||
if(encoding === "ean13"){
|
||||
base = self.sanitize_ean(base);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
var rules = this.pos.nomenclature.rules;
|
||||
for (var i = 0; i < rules.length; i++) {
|
||||
if (match_pattern(barcode,rules[i].pattern)) {
|
||||
if(rules[i].type === 'alias') {
|
||||
barcode = rules[i].alias;
|
||||
parsed_result.code = barcode;
|
||||
parsed_result.type = 'alias';
|
||||
}
|
||||
else {
|
||||
parsed_result.encoding = rules[i].encoding;
|
||||
parsed_result.type = rules[i].type;
|
||||
parsed_result.value = get_value(barcode,rules[i].pattern);
|
||||
parsed_result.base_code = get_basecode(barcode,rules[i].pattern,parsed_result.encoding);
|
||||
return parsed_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parsed_result;
|
||||
},
|
||||
|
||||
scan: function(code){
|
||||
var parsed_result = this.parse_barcode(code);
|
||||
|
||||
var parsed_result = this.pos.barcode_reader.parse_barcode(code, this.pos.nomenclature);
|
||||
|
||||
if(parsed_result.type in {'product':'', 'weight':'', 'price':''}){ //barcode is associated to a product
|
||||
if(this.action_callback['product']){
|
||||
this.action_callback['product'](parsed_result);
|
||||
|
||||
@@ -3,6 +3,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
||||
|
||||
var QWeb = instance.web.qweb;
|
||||
var _t = instance.web._t;
|
||||
var barcode_reader_module = instance.barcode_reader;
|
||||
|
||||
var round_di = instance.web.round_decimals;
|
||||
var round_pr = instance.web.round_precision
|
||||
@@ -26,9 +27,9 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
||||
this.pos_widget = attributes.pos_widget;
|
||||
|
||||
this.proxy = new module.ProxyDevice(this); // used to communicate to the hardware devices via a local proxy
|
||||
|
||||
this.barcode_reader = new module.BarcodeReader({'pos': this, proxy:this.proxy}); // used to read barcodes
|
||||
|
||||
|
||||
this.barcode_reader = new barcode_reader_module.BarcodeReader({'pos': this, proxy:this.proxy}); // used to read barcodes
|
||||
|
||||
this.proxy_queue = new module.JobQueue(); // used to prevent parallels communications to the proxy
|
||||
this.db = new module.PosDB(); // a local database used to search trough products and categories & store pending orders
|
||||
this.debug = jQuery.deparam(jQuery.param.querystring()).debug !== undefined; //debug mode
|
||||
@@ -83,8 +84,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
||||
if(self.config.use_proxy){
|
||||
return self.connect_to_proxy();
|
||||
}
|
||||
});
|
||||
|
||||
}); // used to read barcodes);
|
||||
},
|
||||
|
||||
// releases ressources holds by the model at the end of life of the posmodel
|
||||
@@ -224,7 +224,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
||||
for (var i = 0; i < orders.length; i++) {
|
||||
self.pos_session.sequence_number = Math.max(self.pos_session.sequence_number, orders[i].data.sequence_number+1);
|
||||
}
|
||||
},
|
||||
},
|
||||
},{
|
||||
model: 'stock.location',
|
||||
fields: [],
|
||||
@@ -306,40 +306,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
||||
self.cashregisters_by_id[self.cashregisters[i].id] = self.cashregisters[i];
|
||||
}
|
||||
},
|
||||
}, {
|
||||
model: 'barcode.nomenclature',
|
||||
fields: ['name','rule_ids'],
|
||||
domain: function(self){ return [] },
|
||||
loaded: function(self,nomenclatures){
|
||||
if (self.config.barcode_nomenclature_id) {
|
||||
for (var i = 0; i < nomenclatures.length; i++) {
|
||||
if (nomenclatures[i].id === self.config.barcode_nomenclature_id[0]) {
|
||||
self.nomenclature = nomenclatures[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
self.nomenclature = self.nomenclature || null;
|
||||
},
|
||||
}, {
|
||||
model: 'barcode.rule',
|
||||
fields: ['name','sequence','type','encoding','pattern','alias'],
|
||||
domain: function(self){ return [['barcode_nomenclature_id','=',self.nomenclature ? self.nomenclature.id : 0]]; },
|
||||
loaded: function(self,rules){
|
||||
if (self.nomenclature) {
|
||||
rules = rules.sort(function(a,b){ return a.sequence - b.sequence; });
|
||||
self.nomenclature.rules = rules;
|
||||
/*for (var i = 0; i < rules.length; i++) {
|
||||
var pattern = rules[i].pattern;
|
||||
pattern = pattern.replace(/[x\*]/gi,'x');
|
||||
|
||||
while (pattern.length < 12) {
|
||||
pattern += '';
|
||||
}
|
||||
rules[i].pattern = pattern;
|
||||
}*/
|
||||
}
|
||||
},
|
||||
}, {
|
||||
}, {
|
||||
label: 'fonts',
|
||||
loaded: function(self){
|
||||
var fonts_loaded = new $.Deferred();
|
||||
@@ -392,6 +359,30 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
||||
|
||||
return logo_loaded;
|
||||
},
|
||||
}, {
|
||||
model: 'barcode.nomenclature',
|
||||
fields: ['name','rule_ids'],
|
||||
domain: function(self){ return [] },
|
||||
loaded: function(self,nomenclatures){
|
||||
if (self.config.barcode_nomenclature_id) {
|
||||
for (var i = 0; i < nomenclatures.length; i++) {
|
||||
if (nomenclatures[i].id === self.config.barcode_nomenclature_id[0]) {
|
||||
self.nomenclature = nomenclatures[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
self.nomenclature = self.nomenclature || null;
|
||||
},
|
||||
}, {
|
||||
model: 'barcode.rule',
|
||||
fields: ['name','sequence','type','encoding','pattern','alias'],
|
||||
domain: function(self){ return [['barcode_nomenclature_id','=',self.nomenclature ? self.nomenclature.id : 0]]; },
|
||||
loaded: function(self,rules){
|
||||
if (self.nomenclature) {
|
||||
rules = rules.sort(function(a,b){ return a.sequence - b.sequence; });
|
||||
self.nomenclature.rules = rules;
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
|
||||
Reference in New Issue
Block a user