[FIX] Barcode nomenclature generalized to Code128 in PoS

This commit is contained in:
Aaron Bohy
2014-11-26 11:46:17 +01:00
committed by Frédéric van der Essen
parent 809144f8a2
commit 97039fb591
7 changed files with 155 additions and 112 deletions
+5 -5
View File
@@ -24,7 +24,7 @@ function openerp_pos_db(instance, module){
this.product_by_id = {};
this.product_by_ean13 = {};
this.product_by_category_id = {};
this.product_by_reference = {};
//this.product_by_reference = {};
this.partner_sorted = [];
this.partner_by_id = {};
@@ -201,9 +201,9 @@ function openerp_pos_db(instance, module){
if(product.ean13){
this.product_by_ean13[product.ean13] = product;
}
if(product.default_code){
/*if(product.default_code){
this.product_by_reference[product.default_code] = product;
}
}*/
}
},
add_packagings: function(packagings){
@@ -354,9 +354,9 @@ function openerp_pos_db(instance, module){
}
return undefined;
},
get_product_by_reference: function(ref){
/*get_product_by_reference: function(ref){
return this.product_by_reference[ref];
},
},*/
get_product_by_category: function(category_id){
var product_ids = this.product_by_category_id[category_id];
var list = [];
+94 -86
View File
@@ -473,17 +473,16 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
}
},
// when an ean is scanned and parsed, the callback corresponding
// to its type is called with the parsed_ean as a parameter.
// (parsed_ean is the result of parse_ean(ean))
// 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_ean)
// 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(action, callback){
if(arguments.length == 2){
this.action_callback[action] = callback;
@@ -501,6 +500,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
this.action_callback[action] = undefined;
}
},
// returns the checksum of the ean, or -1 if the ean has not the correct length, ean must be a string
ean_checksum: function(ean){
var code = ean.split('');
@@ -519,11 +519,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
total = oddsum * 3 + evensum;
return Number((10 - total % 10) % 10);
},
// returns true if the ean is a valid EAN codebar number by checking the control digit.
// ean must be a string
check_ean: function(ean){
return /^\d+$/.test(ean) && this.ean_checksum(ean) === Number(ean[ean.length-1]);
},
// 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);
@@ -533,63 +529,80 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
}
return ean.substr(0,12) + this.ean_checksum(ean);
},
// attempts to interpret an ean (string encoding an ean)
// it will check its validity then return an object containing various
// information about the 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 ean
// - type : the type of the ean:
// 'price' | 'weight' | 'product' | 'cashier' | 'client' | 'discount' | 'error'
// - code : the barcode
// - type : the type of the barcode:
// 'price' | 'weight' | 'product' | 'cashier' | 'client' | 'discount' | 'lot' |
// 'package' | 'location' | 'error'
//
// - value : if the id encodes a numerical value, it will be put there
// - base_code : the ean code with all the encoding parts set to zero; the one put on
// - 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_ean: function(ean){
parse_barcode: function(barcode){
var self = this;
var parse_result = {
encoding: 'ean13',
var parsed_result = {
encoding: '',
type:'error',
code:ean,
base_code: ean,
code:barcode,
base_code: barcode,
value: 0,
};
if (!this.pos.nomenclature) {
return parse_result;
return parsed_result;
}
if (!this.check_ean(ean)){
return parse_result;
}
// The barcode can contain any alphanumerical character, including ( and )
/*if (!/^[A-Za-z0-9()]+$/.test(barcode)){
return parsed_result;
}*/
function is_number(char){
var n = char.charCodeAt(0);
return n >= 48 && n <= 57;
}
function match_pattern(ean,pattern){
for(var i = 0; i < pattern.length; i++){
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];
var e = ean[i];
if( is_number(p) && p !== e ){
if(p === "{" || p === "}"){
numerical_content = !numerical_content;
j--;
continue;
}
if(!numerical_content && p !== '*' && p !== barcode[j]){
return false;
}
}
return true;
}
function get_value(ean,pattern){
function get_value(barcode,pattern){
var value = 0;
var decimals = 0;
for(var i = 0; i < pattern.length; i++){
var numerical_content = false;
for(var i = 0, j = 0; i < pattern.length; i++, j++){
var p = pattern[i];
var v = parseInt(ean[i]);
if( p === 'N'){
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 ....
}else if(p === 'D'){ // FIXME precision ....
decimals += 1;
value += v * Math.pow(10,-decimals);
}
@@ -597,65 +610,58 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
return value;
}
function get_basecode(ean,pattern){
function get_basecode(barcode,pattern,encoding){
var base = '';
for(var i = 0; i < pattern.length; i++){
var numerical_content = false;
for(var i = 0, j = 0; i < pattern.length; i++, j++){
var p = pattern[i];
var v = ean[i];
if( p === 'x' || is_number(p)){
base += v;
}else{
if(p === "{" || p === "}"){
numerical_content = !numerical_content;
j--;
continue;
}
if(numerical_content){
base += '0';
}
else{
base += barcode[j];
}
}
return self.sanitize_ean(base);
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(ean,rules[i].pattern)) {
parse_result.type = rules[i].type;
parse_result.value = get_value(ean,rules[i].pattern);
parse_result.base_code = get_basecode(ean,rules[i].pattern);
return parse_result;
if (match_pattern(barcode,rules[i].pattern)) {
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 parse_result;
return parsed_result;
},
scan: function(code){
if(code.length < 3){
return;
}else if(code.length === 13 && this.check_ean(code)){
var parse_result = this.parse_ean(code);
}else if(code.length === 12 && this.check_ean('0'+code)){
// many barcode scanners strip the leading zero of ean13 barcodes.
// This is because ean-13 are UCP-A with an additional zero at the beginning,
// so by stripping zeros you get retrocompatibility with UCP-A systems.
var parse_result = this.parse_ean('0'+code);
}else if(this.pos.db.get_product_by_reference(code)){
var parse_result = {
encoding: 'reference',
type: 'product',
code: code,
};
}else{
var parse_result = {
encoding: 'error',
type: 'error',
code: code,
};
}
if(parse_result.type in {'product':'', 'weight':'', 'price':'', 'discount':''}){ //ean is associated to a product
var parsed_result = this.parse_barcode(code);
if(parsed_result.type in {'product':'', 'weight':'', 'price':''}){ //barcode is associated to a product
if(this.action_callback['product']){
this.action_callback['product'](parse_result);
this.action_callback['product'](parsed_result);
}
}else{
if(this.action_callback[parse_result.type]){
this.action_callback[parse_result.type](parse_result);
}
else{
if(this.action_callback[parsed_result.type]){
this.action_callback[parsed_result.type](parsed_result);
}
}
},
@@ -696,7 +702,9 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
// Internal Ref 5449 vs EAN13 5449000...
timeout = setTimeout(function(){
self.scan(code);
if(code.length >= 3){
self.scan(code);
}
code = "";
onlynumbers = true;
},100);
+7 -7
View File
@@ -322,21 +322,21 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
},
}, {
model: 'barcode.rule',
fields: ['name','sequence','type','pattern'],
fields: ['name','sequence','type','encoding','pattern'],
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++) {
/*for (var i = 0; i < rules.length; i++) {
var pattern = rules[i].pattern;
pattern = pattern.replace(/[x\*]/gi,'x');
while (pattern.length < 12) {
pattern += 'x';
pattern += '';
}
rules[i].pattern = pattern;
}
}*/
}
},
}, {
@@ -719,11 +719,11 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
scan_product: function(parsed_code){
var self = this;
var selectedOrder = this.get_order();
if(parsed_code.encoding === 'ean13'){
//if(parsed_code.encoding === 'barcode'){
var product = this.db.get_product_by_ean13(parsed_code.base_code);
}else if(parsed_code.encoding === 'reference'){
/*}else if(parsed_code.encoding === 'reference'){
var product = this.db.get_product_by_reference(parsed_code.code);
}
}*/
if(!product){
return false;
@@ -233,7 +233,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
this.pos_widget.set_leftpane_visible(this.show_leftpane);
this.pos_widget.username.set_user_mode(this.pos_widget.screen_selector.get_user_mode());
this.pos.barcode_reader.set_action_callback({
'cashier': self.barcode_cashier_action ? function(code){ self.barcode_cashier_action(code); } : undefined ,
'product': self.barcode_product_action ? function(code){ self.barcode_product_action(code); } : undefined ,
+3 -2
View File
@@ -138,7 +138,8 @@ class barcode_rule(osv.osv):
'barcode_nomenclature_id': fields.many2one('barcode.nomenclature','Barcode Nomenclature'),
'sequence': fields.integer('Sequence', help='Used to order rules such that rules with a smaller sequence match first'),
#'encoding': fields.selection([('any','Any'),('ean13','EAN-13'),('ean8','EAN-8'),('codabar','Codabar'),('upca','UPC-A'),('upce','UPC-E')],'Encoding',help='This rule will apply only if the barcode is encoded with the specified encoding'),
'type': fields.selection([('product','Unit Product'),('weight','Weighted Product'),('price','Priced Product'),('discount','Discounted Product'),('client','Client'),('cashier','Cashier')],'Type', required=True),
'encoding': fields.selection([('any','Any'),('ean13','EAN-13')],'Encoding',required=True,help='This rule will apply only if the barcode is encoded with the specified encoding'),
'type': fields.selection([('product','Unit Product'),('weight','Weighted Product'),('price','Priced Product'),('discount','Discounted Product'),('client','Client'),('cashier','Cashier'),('location','Location'),('lot','Lot'),('package','Package')],'Type', required=True),
'pattern': fields.char('Barcode Pattern', size=32, help="The barcode matching pattern"),
#'alias': fields.char('Alias',size=32,help='The matched pattern will alias to this barcode'),
}
@@ -146,5 +147,5 @@ class barcode_rule(osv.osv):
_defaults = {
'type': 'product',
'pattern': '*',
#'encoding': 'any',
'encoding': 'any',
}
+2
View File
@@ -15,6 +15,7 @@
<tree string='Tables'>
<field name="name" />
<field name="type" />
<field name="encoding" />
<field name="pattern" />
<field name="sequence" />
</tree>
@@ -58,6 +59,7 @@
<field name="name" />
<field name="sequence" />
<field name="type" />
<field name="encoding"/>
<field name="pattern" />
</group>
</form>
+44 -11
View File
@@ -8,8 +8,9 @@
<record id="barcode_rule_product" model="barcode.rule">
<field name="name">Product Barcodes</field>
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">60</field>
<field name="sequence">90</field>
<field name="type">product</field>
<field name="encoding">ean13</field>
<field name="pattern">*</field>
</record>
@@ -18,23 +19,26 @@
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">50</field>
<field name="type">cashier</field>
<field name="encoding">any</field>
<field name="pattern">041</field>
</record>
<record id="barcode_rule_client" model="barcode.rule">
<field name="name">Client Barcodes</field>
<field name="name">Customer Barcodes</field>
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">40</field>
<field name="type">client</field>
<field name="encoding">any</field>
<field name="pattern">042</field>
</record>
<record id="barcode_rule_weight" model="barcode.rule">
<field name="name">Weight Barcodes</field>
<record id="barcode_rule_weight_three_dec" model="barcode.rule">
<field name="name">Weight Barcodes 3 Decimals</field>
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">30</field>
<field name="sequence">36</field>
<field name="type">weight</field>
<field name="pattern">21*****NNDDD*</field>
<field name="encoding">ean13</field>
<field name="pattern">21*****{NNDDD}*</field>
</record>
<record id="barcode_rule_discount" model="barcode.rule">
@@ -42,15 +46,44 @@
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">20</field>
<field name="type">discount</field>
<field name="pattern">22********NN*</field>
<field name="encoding">any</field>
<field name="pattern">22{NN}*</field>
</record>
<record id="barcode_rule_price" model="barcode.rule">
<field name="name">Price Barcodes</field>
<record id="barcode_rule_price_two_dec" model="barcode.rule">
<field name="name">Price Barcodes 2 Decimals</field>
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">10</field>
<field name="sequence">14</field>
<field name="type">price</field>
<field name="pattern">23*****NNNDD*</field>
<field name="encoding">ean13</field>
<field name="pattern">23*****{NNNDD}*</field>
</record>
<record id="barcode_rule_package" model="barcode.rule">
<field name="name">Package barcodes</field>
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">70</field>
<field name="type">package</field>
<field name="encoding">any</field>
<field name="pattern">PACK*</field>
</record>
<record id="barcode_rule_lot" model="barcode.rule">
<field name="name">Lot barcodes</field>
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">80</field>
<field name="type">lot</field>
<field name="encoding">any</field>
<field name="pattern">10*</field>
</record>
<record id="barcode_rule_location" model="barcode.rule">
<field name="name">Location barcodes</field>
<field name="barcode_nomenclature_id" ref="default_barcode_nomenclature"/>
<field name="sequence">60</field>
<field name="type">location</field>
<field name="encoding">any</field>
<field name="pattern">414*</field>
</record>
</data>
</openerp>