[IMP] point_of_sale: support for non ean13 barcodes using the Internal Reference field
bzr revid: fva@openerp.com-20130923145139-iu3ds9tcfzy1ffcf
This commit is contained in:
parent
13f6d59043
commit
e03f3aa288
|
@ -82,7 +82,7 @@ class PointOfSaleController(http.Controller):
|
|||
"""
|
||||
print 'scan_item_success: ' + str(ean)
|
||||
|
||||
@http.route('/pos/scan_item_error_unrecognized')
|
||||
@http.route('/pos/scan_item_error_unrecognized', type='json', auth='admin')
|
||||
def scan_item_error_unrecognized(self, ean):
|
||||
"""
|
||||
A product has been scanned without success
|
||||
|
|
|
@ -43,6 +43,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.category_by_id = {};
|
||||
this.root_category_id = 0;
|
||||
|
@ -197,6 +198,9 @@ function openerp_pos_db(instance, module){
|
|||
if(product.ean13){
|
||||
this.product_by_ean13[product.ean13] = product;
|
||||
}
|
||||
if(product.default_code){
|
||||
this.product_by_reference[product.default_code] = product;
|
||||
}
|
||||
}
|
||||
},
|
||||
add_packagings: function(packagings){
|
||||
|
@ -241,6 +245,9 @@ function openerp_pos_db(instance, module){
|
|||
}
|
||||
return undefined;
|
||||
},
|
||||
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 = [];
|
||||
|
|
|
@ -450,7 +450,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
// it will check its validity then return an object containing various
|
||||
// information about the ean.
|
||||
// most importantly :
|
||||
// - ean : the ean
|
||||
// - code : the ean
|
||||
// - type : the type of the ean:
|
||||
// 'price' | 'weight' | 'unit' | 'cashier' | 'client' | 'discount' | 'error'
|
||||
//
|
||||
|
@ -460,13 +460,16 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
// - unit : if the encoded value has a unit, it will be put there.
|
||||
// not to be confused with the 'unit' type, which represent an unit of a
|
||||
// unique product
|
||||
// - base_code : the ean code with all the encoding parts set to zero; the one put on
|
||||
// the product in the backend
|
||||
|
||||
parse_ean: function(ean){
|
||||
var parse_result = {
|
||||
type:'unknown', //
|
||||
encoding: 'ean13',
|
||||
type:'unknown',
|
||||
prefix:'',
|
||||
ean:ean,
|
||||
base_ean: ean,
|
||||
code:ean,
|
||||
base_code: ean,
|
||||
id:'',
|
||||
value: 0,
|
||||
unit: 'none',
|
||||
|
@ -487,13 +490,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
parse_result.type = 'error';
|
||||
} else if( match_prefix(this.price_prefix_set,'price')){
|
||||
parse_result.id = ean.substring(0,7);
|
||||
parse_result.base_ean = this.sanitize_ean(ean.substring(0,7));
|
||||
parse_result.base_code = this.sanitize_ean(ean.substring(0,7));
|
||||
parse_result.value = Number(ean.substring(7,12))/100.0;
|
||||
parse_result.unit = 'euro';
|
||||
} else if( match_prefix(this.weight_prefix_set,'weight')){
|
||||
parse_result.id = ean.substring(0,7);
|
||||
parse_result.value = Number(ean.substring(7,12))/1000.0;
|
||||
parse_result.base_ean = this.sanitize_ean(ean.substring(0,7));
|
||||
parse_result.base_code = this.sanitize_ean(ean.substring(0,7));
|
||||
parse_result.unit = 'Kg';
|
||||
} else if( match_prefix(this.client_prefix_set,'client')){
|
||||
parse_result.id = ean.substring(0,7);
|
||||
|
@ -502,7 +505,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
parse_result.id = ean.substring(0,7);
|
||||
} else if( match_prefix(this.discount_prefix_set,'discount')){
|
||||
parse_result.id = ean.substring(0,7);
|
||||
parse_result.base_ean = this.sanitize_ean(ean.substring(0,7));
|
||||
parse_result.base_code = this.sanitize_ean(ean.substring(0,7));
|
||||
parse_result.value = Number(ean.substring(7,12))/100.0;
|
||||
parse_result.unit = '%';
|
||||
} else {
|
||||
|
@ -512,9 +515,19 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
}
|
||||
return parse_result;
|
||||
},
|
||||
|
||||
on_ean: function(ean){
|
||||
var parse_result = this.parse_ean(ean);
|
||||
|
||||
scan: function(type,code){
|
||||
console.log('scan',type,code);
|
||||
if (type === 'ean13'){
|
||||
var parse_result = this.parse_ean(code);
|
||||
}else if(type === 'reference'){
|
||||
var parse_result = {
|
||||
encoding: 'reference',
|
||||
type: 'unit',
|
||||
code: code,
|
||||
prefix: '',
|
||||
};
|
||||
}
|
||||
|
||||
if (parse_result.type === 'error') { //most likely a checksum error, raise warning
|
||||
console.warn('WARNING: barcode checksum error:',parse_result);
|
||||
|
@ -522,7 +535,6 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
if(this.action_callback['product']){
|
||||
this.action_callback['product'](parse_result);
|
||||
}
|
||||
//this.trigger("codebar",parse_result );
|
||||
}else{
|
||||
if(this.action_callback[parse_result.type]){
|
||||
this.action_callback[parse_result.type](parse_result);
|
||||
|
@ -530,41 +542,43 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
}
|
||||
},
|
||||
|
||||
on_reference: function(code){
|
||||
if(this.action_callback['reference']){
|
||||
this.action_callback['reference'](code);
|
||||
}
|
||||
},
|
||||
|
||||
// starts catching keyboard events and tries to interpret codebar
|
||||
// calling the callbacks when needed.
|
||||
connect: function(){
|
||||
|
||||
var self = this;
|
||||
var codeNumbers = [];
|
||||
var timeStamp = 0;
|
||||
var lastTimeStamp = 0;
|
||||
var code = "";
|
||||
var timeStamp = 0;
|
||||
var onlynumbers = true;
|
||||
|
||||
// The barcode readers acts as a keyboard, we catch all keyup events and try to find a
|
||||
// barcode sequence in the typed keys, then act accordingly.
|
||||
this.handler = function(e){
|
||||
//We only care about numbers
|
||||
if (e.which >= 48 && e.which < 58){
|
||||
if(timeStamp + 50 < new Date().getTime()){
|
||||
code = "";
|
||||
onlynumbers = true;
|
||||
}
|
||||
|
||||
// The barcode reader sends keystrokes with a specific interval.
|
||||
// We look if the typed keys fit in the interval.
|
||||
if (codeNumbers.length === 0) {
|
||||
timeStamp = new Date().getTime();
|
||||
} else {
|
||||
if (lastTimeStamp + 30 < new Date().getTime()) {
|
||||
// not a barcode reader
|
||||
codeNumbers = [];
|
||||
timeStamp = new Date().getTime();
|
||||
}
|
||||
}
|
||||
codeNumbers.push(e.which - 48);
|
||||
lastTimeStamp = new Date().getTime();
|
||||
if (codeNumbers.length === 13) {
|
||||
//We have found what seems to be a valid codebar
|
||||
self.on_ean(codeNumbers.join(''));
|
||||
codeNumbers = [];
|
||||
}
|
||||
} else {
|
||||
// NaN
|
||||
codeNumbers = [];
|
||||
timeStamp = new Date().getTime();
|
||||
|
||||
if( e.which < 48 || e.which >= 58 ){ // not a number
|
||||
onlynumbers = false;
|
||||
}
|
||||
|
||||
code += String.fromCharCode(e.which);
|
||||
|
||||
if(code.length >= 2 && self.pos.db.get_product_by_reference(code)){
|
||||
self.scan('reference',code);
|
||||
code = "";
|
||||
onlynumbers = true;
|
||||
}else if(code.length === 13 && onlynumbers){
|
||||
self.scan('ean13',code);
|
||||
code = "";
|
||||
onlynumbers = true;
|
||||
}
|
||||
};
|
||||
$('body').on('keypress', this.handler);
|
||||
|
|
|
@ -428,19 +428,23 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
return tried_all;
|
||||
},
|
||||
|
||||
scan_product: function(parsed_ean){
|
||||
scan_product: function(parsed_code){
|
||||
var self = this;
|
||||
var product = this.db.get_product_by_ean13(parsed_ean.base_ean);
|
||||
var selectedOrder = this.get('selectedOrder');
|
||||
if(parsed_code.encoding === 'ean13'){
|
||||
var product = this.db.get_product_by_ean13(parsed_code.base_code);
|
||||
}else if(parsed_code.encoding === 'reference'){
|
||||
var product = this.db.get_product_by_reference(parsed_code.code);
|
||||
}
|
||||
|
||||
if(!product){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(parsed_ean.type === 'price'){
|
||||
selectedOrder.addProduct(new module.Product(product), {price:parsed_ean.value});
|
||||
}else if(parsed_ean.type === 'weight'){
|
||||
selectedOrder.addProduct(new module.Product(product), {quantity:parsed_ean.value, merge:false});
|
||||
if(parsed_code.type === 'price'){
|
||||
selectedOrder.addProduct(new module.Product(product), {price:parsed_code.value});
|
||||
}else if(parsed_code.type === 'weight'){
|
||||
selectedOrder.addProduct(new module.Product(product), {quantity:parsed_code.value, merge:false});
|
||||
}else{
|
||||
selectedOrder.addProduct(new module.Product(product));
|
||||
}
|
||||
|
|
|
@ -160,29 +160,29 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
// what happens when a product is scanned :
|
||||
// it will add the product to the order and go to barcode_product_screen. Or show barcode_product_error_popup if
|
||||
// there's an error.
|
||||
barcode_product_action: function(ean){
|
||||
barcode_product_action: function(code){
|
||||
var self = this;
|
||||
if(self.pos.scan_product(ean)){
|
||||
self.pos.proxy.scan_item_success(ean);
|
||||
if(self.pos.scan_product(code)){
|
||||
self.pos.proxy.scan_item_success(code);
|
||||
if(self.barcode_product_screen){
|
||||
self.pos_widget.screen_selector.set_current_screen(self.barcode_product_screen);
|
||||
}
|
||||
}else{
|
||||
self.pos.proxy.scan_item_error_unrecognized(ean);
|
||||
self.pos.proxy.scan_item_error_unrecognized(code);
|
||||
if(self.barcode_product_error_popup && self.pos_widget.screen_selector.get_user_mode() !== 'cashier'){
|
||||
self.pos_widget.screen_selector.show_popup(self.barcode_product_error_popup);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// what happens when a cashier id barcode is scanned.
|
||||
// the default behavior is the following :
|
||||
// - if there's a user with a matching ean, put it as the active 'cashier', go to cashier mode, and return true
|
||||
// - else : do nothing and return false. You probably want to extend this to show and appropriate error popup...
|
||||
barcode_cashier_action: function(ean){
|
||||
barcode_cashier_action: function(code){
|
||||
var users = this.pos.get('user_list');
|
||||
for(var i = 0, len = users.length; i < len; i++){
|
||||
if(users[i].ean13 === ean.ean){
|
||||
if(users[i].ean13 === code.code){
|
||||
this.pos.set('cashier',users[i]);
|
||||
this.pos_widget.username.refresh();
|
||||
this.pos.proxy.cashier_mode_activated();
|
||||
|
@ -190,7 +190,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
return true;
|
||||
}
|
||||
}
|
||||
this.pos.proxy.scan_item_error_unrecognized(ean);
|
||||
this.pos.proxy.scan_item_error_unrecognized(code);
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -198,28 +198,28 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
// the default behavior is the following :
|
||||
// - if there's a user with a matching ean, put it as the active 'client' and return true
|
||||
// - else : return false.
|
||||
barcode_client_action: function(ean){
|
||||
barcode_client_action: function(code){
|
||||
var partners = this.pos.get('partner_list');
|
||||
for(var i = 0, len = partners.length; i < len; i++){
|
||||
if(partners[i].ean13 === ean.ean){
|
||||
if(partners[i].ean13 === code.code){
|
||||
this.pos.get('selectedOrder').set_client(partners[i]);
|
||||
this.pos_widget.username.refresh();
|
||||
this.pos.proxy.scan_item_success(ean);
|
||||
this.pos.proxy.scan_item_success(code);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
this.pos.proxy.scan_item_error_unrecognized(ean);
|
||||
this.pos.proxy.scan_item_error_unrecognized(code);
|
||||
return false;
|
||||
//TODO start the transaction
|
||||
},
|
||||
|
||||
// what happens when a discount barcode is scanned : the default behavior
|
||||
// is to set the discount on the last order.
|
||||
barcode_discount_action: function(ean){
|
||||
this.pos.proxy.scan_item_success(ean);
|
||||
barcode_discount_action: function(code){
|
||||
this.pos.proxy.scan_item_success(code);
|
||||
var last_orderline = this.pos.get('selectedOrder').getLastOrderline();
|
||||
if(last_orderline){
|
||||
last_orderline.set_discount(ean.value)
|
||||
last_orderline.set_discount(code.value)
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -292,10 +292,10 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
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(ean){ self.barcode_cashier_action(ean); } : undefined ,
|
||||
'product': self.barcode_product_action ? function(ean){ self.barcode_product_action(ean); } : undefined ,
|
||||
'client' : self.barcode_client_action ? function(ean){ self.barcode_client_action(ean); } : undefined ,
|
||||
'discount': self.barcode_discount_action ? function(ean){ self.barcode_discount_action(ean); } : undefined,
|
||||
'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 ,
|
||||
'client' : self.barcode_client_action ? function(code){ self.barcode_client_action(code); } : undefined ,
|
||||
'discount': self.barcode_discount_action ? function(code){ self.barcode_discount_action(code); } : undefined,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -405,7 +405,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.pos.barcode_reader.save_callbacks();
|
||||
this.pos.barcode_reader.reset_action_callbacks();
|
||||
this.pos.barcode_reader.set_action_callback({
|
||||
'cashier': function(ean){
|
||||
'cashier': function(code){
|
||||
clearInterval(this.intervalID);
|
||||
self.pos.proxy.cashier_mode_activated();
|
||||
self.pos_widget.screen_selector.set_user_mode('cashier');
|
||||
|
@ -683,14 +683,14 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
show_numpad: false,
|
||||
show_leftpane: false,
|
||||
barcode_product_action: function(ean){
|
||||
barcode_product_action: function(code){
|
||||
this.pos.proxy.transaction_start();
|
||||
this._super(ean);
|
||||
this._super(code);
|
||||
},
|
||||
|
||||
barcode_client_action: function(ean){
|
||||
barcode_client_action: function(code){
|
||||
this.pos.proxy.transaction_start();
|
||||
this._super(ean);
|
||||
this._super(code);
|
||||
$('.goodbye-message').addClass('oe_hidden');
|
||||
this.pos_widget.screen_selector.show_popup('choose-receipt');
|
||||
},
|
||||
|
|
|
@ -753,12 +753,15 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
this.$('.button.custom_ean').click(function(){
|
||||
var ean = self.pos.barcode_reader.sanitize_ean(self.$('input.ean').val() || '0');
|
||||
self.$('input.ean').val(ean);
|
||||
self.pos.barcode_reader.on_ean(ean);
|
||||
self.pos.barcode_reader.scan('ean13',ean);
|
||||
});
|
||||
this.$('.button.reference').click(function(){
|
||||
self.pos.barcode_reader.scan('reference',self.$('input.ean').val());
|
||||
});
|
||||
_.each(this.eans, function(ean, name){
|
||||
self.$('.button.'+name).click(function(){
|
||||
self.$('input.ean').val(ean);
|
||||
self.pos.barcode_reader.on_ean(ean);
|
||||
self.pos.barcode_reader.scan('ean13',ean);
|
||||
});
|
||||
});
|
||||
_.each(this.events, function(name){
|
||||
|
|
|
@ -494,6 +494,7 @@
|
|||
<li class="button lemon_price">1.54€ Lemon</li>
|
||||
<li class="button unknown_product">Unknown Product</li>
|
||||
<li class="button invalid_ean">Invalid Ean</li>
|
||||
<li class="button reference">Reference</li>
|
||||
</ul>
|
||||
|
||||
<p class="category">Hardware Status</p>
|
||||
|
|
Loading…
Reference in New Issue