[WIP] point_of_sale: much progress on the indexeddb backend

bzr revid: fva@openerp.com-20120809172113-ex3o5vyt4ckv4au6
This commit is contained in:
Frédéric van der Essen 2012-08-09 19:21:13 +02:00
parent dc8f543d17
commit 03b79a9832
5 changed files with 275 additions and 351 deletions

View File

@ -146,6 +146,8 @@ function openerp_pos_db(instance, module){
productStore.createIndex('category','category', {unique:false});
var imageStore = this.db.createObjectStore('images', {keyPath: 'id'});
var categoryStore = this.db.createObjectStore('categories', {keypath:'name'});
},
_add_data: function(store, data){
@ -286,6 +288,9 @@ function openerp_pos_db(instance, module){
}
}
},
/* the callback function will be called with all products as parameter, by increasing id.
* if the callback returns 'break' the iteration will stop
*/
for_all_products: function(callback){
var transaction = this.db.transaction('products');
var objectStore = transaction.objectStore('products');
@ -299,6 +304,29 @@ function openerp_pos_db(instance, module){
}
};
},
/* the callback function will be called with all products as parameter by increasing id.
* if the callback returns 'break', the iteration will stop
* if the callback returns a product object, it will be inserted in the db, possibly
* overwriting an existing product. The intended usage is for the callback to return a
* modified version version of the product with the same id. Anything else and you're on your own.
*/
modify_all_products: function(callback){
var transaction = this.db.transaction('products','readwrite');
var objectStore = transaction.objectStore('products');
objectStore.openCursor().onsuccess = function(event){
var cursor = event.target.result;
if(cursor){
var ret = callback(cursor.value);
if(ret === undefined || ret === null){
cursor.continue();
}else if(ret === 'break'){
return;
}else{
objectStore.put(ret);
}
}
};
},
});
window.PosDB = module.PosDB;
@ -310,7 +338,74 @@ function openerp_pos_db(instance, module){
this.name = options.name || this.name;
this.limit = options.limit || this.limit;
this.products = this.name + '_products';
this.images = this.name + '_images';
this.categories = this.name + '_categories';
this.category_by_id = {};
this.root_category_id = 0;
this.category_products = {};
this.category_ancestors = {};
this.category_childs = {};
this.category_parent = {};
},
get_category_by_id: function(categ_id){
if(categ_id instanceof Array){
var list = [];
for(var i = 0, len = categ_id.length; i < len; i++){
var cat = this.category_by_id[categ_id[i]];
if(cat){
list.push(cat);
}else{
console.error("get_category_by_id: no category has id:",categ_id[i]);
}
}
return list;
}else{
return this.category_by_id[categ_id];
}
},
get_category_childs_ids: function(categ_id){
return this.category_childs[categ_id] || [];
},
get_category_ancestors_ids: function(categ_id){
return this.category_ancestors[categ_id] || [];
},
get_category_parent_id: function(categ_id){
return this.category_parent[categ_id] || this.root_category_id;
},
add_categories: function(categories){
var self = this;
if(!this.category_by_id[this.root_category_id]){
this.category_by_id[this.root_category_id] = {
id : this.root_category_id,
name : 'Root',
};
}
for(var i=0, len = categories.length; i < len; i++){
console.log('putting category : ',categories[i].id, categories[i].name);
this.category_by_id[categories[i].id] = categories[i];
}
for(var i=0, len = categories.length; i < len; i++){
var cat = categories[i];
var parent_id = cat.parent_id[0] || this.root_category_id;
console.log('category parent',cat.id, parent_id);
this.category_parent[cat.id] = cat.parent_id[0];
if(!this.category_childs[parent_id]){
this.category_childs[parent_id] = [];
}
this.category_childs[parent_id].push(cat.id);
}
function make_ancestors(cat_id, ancestors){
self.category_ancestors[cat_id] = ancestors;
ancestors = ancestors.slice(0);
ancestors.push(cat_id);
var childs = self.category_childs[cat_id] || [];
for(var i=0, len = childs.length; i < len; i++){
make_ancestors(childs[i], ancestors);
}
}
make_ancestors(this.root_category_id, []);
},
_get_products: function(){
var products = localStorage[this.products];
@ -323,39 +418,51 @@ function openerp_pos_db(instance, module){
_set_products: function(products){
localStorage[this.products] = JSON.stringify(products);
},
_get_images: function(){
var images = localStorage[this.images];
if(images){
return JSON.parse(images) || {};
_get_categories: function(){
var categories = localStorage[this.categories];
if(categories){
return JSON.parse(categories) || {};
}else{
return {};
}
},
_set_images: function(images){
localStorage[this.images] = JSON.stringify(images);
_set_categories: function(categories){
localStorage[this.categories] = JSON.stringify(categories);
},
add_product: function(products){
var stored_images = this._get_images();
var stored_products = this._get_products();
var stored_categories = this._get_categories();
if(!products instanceof Array){
products = [products];
}
for(var i = 0, len = products.length; i < len; i++){
var product = products[i];
if(product.product_image_small){
product = _.clone(product);
stored_images[product.id] = product.product_image_small;
delete product['product_image_small'];
var categ_id = product.pos_categ_id[0];
if(!stored_categories[categ_id]){
stored_categories[categ_id] = [];
}
stored_categories[categ_id].push(product.id);
var ancestors = this.get_category_ancestors_ids(categ_id) || [];
console.log('ancestors:',ancestors);
for(var j = 0; j < ancestors.length; j++){
if(! stored_categories[ancestors[j]]){
stored_categories[ancestors[j]] = [];
}
stored_categories[ancestors[j]].push(product.id);
}
stored_products[product.id] = product;
}
this._set_images(stored_images);
this._set_products(stored_products);
this._set_categories(stored_categories);
},
clear: function(done_callback){
localStorage.removeItem(this.products);
localStorage.removeItem(this.images);
localStorage.removeItem(this.categories);
if(done_callback){
done_callback();
}
},
_count_props : function(obj){
if(obj.__count__){
@ -373,9 +480,6 @@ function openerp_pos_db(instance, module){
get_product_count: function(result_callback){
result_callback(this._count_props(this._get_products()));
},
get_image_count: function(result_callback){
result_callback(this._count_props(this._get_images()));
},
get_product_by_id: function(id, result_callback){
var products = this._get_products();
result_callback( products[id] );
@ -400,66 +504,55 @@ function openerp_pos_db(instance, module){
}
result_callback(undefined);
},
get_product_by_category: function(category, result_callback){
var products = this._get_products();
get_product_by_category: function(category_id, result_callback){
var stored_categories = this._get_categories();
var stored_products = this._get_products();
var product_ids = stored_categories[category_id];
var list = [];
for(var i in products){
if( products[i] && products[i].category === category){
list.push(products[i]);
}
for(var i = 0, len = product_ids.length; i < len; i++){
list.push(stored_products[product_ids[i]]);
}
result_callback(list);
},
get_product_image: function(product, result_callback){
var images = this._get_images();
result_callback(images[product.id]);
},
search_product: function(fields, query, result_callback){
var products = this._get_products();
var list = [];
if(typeof query !== 'string'){
if(query.toString){
query = query.toString();
}else{
throw new Error('search_product: the query must be a string or must be convertible to string');
search_product_in_category: function(category_id, fields, query, result_callback){
var self = this;
this.get_product_by_category(category_id, function(products){
var list = [];
query = query.toString().toLowerCase();
if(!(fields instanceof Array)){
fields = [fields];
}
}
query = query.toLowerCase();
if(!(fields instanceof Array)){
fields = [fields];
}
for(var i in products){
for(var j = 0, jlen = fields.length; j < jlen; j++){
var field = products[i][fields[j]];
if(field === null || field === undefined){
continue;
}
if(typeof field !== 'string'){
if(field.toString){
field = field.toString();
}else{
for(var i in products){
for(var j = 0, jlen = fields.length; j < jlen; j++){
var field = products[i][fields[j]];
if(field === null || field === undefined){
continue;
}
}
if(field.toLowerCase().indexOf(query) != -1){
list.push(products[i]);
break;
if(typeof field !== 'string'){
if(field.toString){
field = field.toString();
}else{
continue;
}
}
if(field.toLowerCase().indexOf(query) != -1){
list.push(products[i]);
break;
}
}
}
}
result_callback(list);
result_callback(list);
});
},
for_all_products: function(callback){
var products = this._get_products();
for(var i in products){
var ret = callback(products[i]);
if(ret === 'break'){
break;
}
}
add_order: function(order,done_callback){
},
remove_order: function(order_id, done_callback){
},
get_orders: function(result_callback){
},
});
window.PosLS = module.PosLS;

View File

@ -277,41 +277,37 @@ 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('');
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 true if the ean is a valid EAN codebar number by checking the control digit.
// ean must be a string
check_ean: function(ean){
var code = ean.split('');
for(var i = 0; i < code.length; i++){
code[i] = Number(code[i]);
return 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);
for(var n = 0, count = (13 - ean.length); n < count; n++){
ean = ean + '0';
}
var st1 = code.slice();
var st2 = st1.slice(0,st1.length-1).reverse();
// some EAN13 barcodes have a length of 12, as they start by 0
while (st2.length < 12) {
st2.push(0);
}
var countSt3 = 1;
var st3 = 0;
$.each(st2, function() {
if (countSt3%2 === 1) {
st3 += this;
}
countSt3 ++;
});
st3 *= 3;
var st4 = 0;
var countSt4 = 1;
$.each(st2, function() {
if (countSt4%2 === 0) {
st4 += this;
}
countSt4 ++;
});
var st5 = st3 + st4;
var cd = (10 - (st5%10)) % 10;
return code[code.length-1] === cd;
return ean.substr(0,12) + this.ean_checksum(ean);
},
// attempts to interpret an ean (string encoding an ean)
@ -334,6 +330,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
type:'unknown', //
prefix:'',
ean:ean,
base_ean: ean,
id:'',
value: 0,
unit: 'none',
@ -355,18 +352,22 @@ 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.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.unit = 'Kg';
} else if( match_prefix(this.client_prefix_set,'client')){
parse_result.id = ean.substring(0,7);
parse_result.unit = 'Kg';
} else if( match_prefix(this.cashier_prefix_set,'cashier')){
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.value = Number(ean.substring(7,12))/100.0;
parse_result.unit = '%';
} else {

View File

@ -64,17 +64,16 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
initialize: function(session, attributes) {
Backbone.Model.prototype.initialize.call(this, attributes);
var self = this;
this.session = session;
this.dao = new module.LocalStorageDAO(); // used to store the order's data on the Hard Drive
this.ready = $.Deferred(); // used to notify the GUI that the PosModel has loaded all resources
this.flush_mutex = new $.Mutex(); // used to make sure the orders are sent to the server once at time
//this.build_tree = _.bind(this.build_tree, this); // ???
this.session = session;
this.categories = {};
this.root_category = null;
this.weightable_categories = []; // a flat list of all categories that directly contain weightable products
this.barcode_reader = new module.BarcodeReader({'pos': this}); // used to read barcodes
this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy
this.db = new module.PosLS(); // a database used to store the products and product images
this.proxy = new module.ProxyDevice(); // used to communicate to the hardware devices via a local proxy
this.db = new module.PosLS(); // a database used to store the products and categories
window.db = this.db;
// pos settings
this.use_scale = false;
@ -267,30 +266,14 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
return session_data_def;
});
// associate the products with their categories
var prod_process_def = $.when(cat_def, session_def)
.pipe(function(){
var product_list = self.get('product_list');
var categories = self.get('categories');
var cat_by_id = {};
for(var i = 0; i < categories.length; i++){
cat_by_id[categories[i].id] = categories[i];
}
//set the parent in the category
for(var i = 0; i < categories.length; i++){
categories[i].parent_category = cat_by_id[categories[i].parent_id[0]];
}
for(var i = 0; i < product_list.length; i++){
product_list[i].pos_category = cat_by_id[product_list[i].pos_categ_id[0]];
}
});
// when all the data has loaded, we compute some stuff, and declare the Pos ready to be used.
$.when(pack_def, cat_def, user_def, users_def, uom_def, session_def, tax_def, prod_process_def, user_def, this.flush())
$.when(pack_def, cat_def, user_def, users_def, uom_def, session_def, tax_def, user_def, this.flush())
.then(function(){
self.build_categories();
self.db.clear();
self.db.add_categories(self.get('categories'));
self.db.add_product(self.get('product_list'));
self.set({'cashRegisters' : new module.CashRegisterCollection(self.get('bank_statements'))});
//self.log_loaded_data(); //Uncomment if you want to log the data to the console for easier debugging
self.log_loaded_data(); //Uncomment if you want to log the data to the console for easier debugging
self.ready.resolve();
},function(){
//we failed to load some backend data, or the backend was badly configured.
@ -325,7 +308,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
// order and a valid selected order
on_removed_order: function(removed_order){
if( this.get('orders').isEmpty()){
this.add_and_select_order(new module.Order({ pos: this }));
this.add_new_order();
}
if( this.get('selectedOrder') === removed_order){
this.set({ selectedOrder: this.get('orders').last() });
@ -340,13 +323,13 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
});
},
add_and_select_order: function(newOrder) {
(this.get('orders')).add(newOrder);
return this.set({
selectedOrder: newOrder
});
//creates a new empty order and sets it as the current order
add_new_order: function(){
var order = new module.Order({pos:this});
this.get('orders').add(order);
this.set('selectedOrder', order);
},
// attemps to send all pending orders ( stored in the DAO ) to the server.
// it will do it one by one, and remove the successfully sent ones from the DAO once
// it has been confirmed that they have been received.
@ -390,119 +373,25 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
});
},
// this adds several properties to the categories in order to make it easier to diplay them
// fields added include the list of product relevant to each category, list of child categories,
// list of ancestors, etc.
build_categories : function(){
var categories = this.get('categories');
var products = this.get('product_list');
//append the content of array2 into array1
function append(array1, array2){
for(var i = 0, len = array2.length; i < len; i++){
array1.push(array2[i]);
scan_product: function(parsed_ean){
var self = this;
var def = new $.Deferred();
this.db.get_product_by_ean13(parsed_ean.base_ean, function(product){
var selectedOrder = this.get('selectedOrder');
if(!product){
def.reject('product-not-found: '+parsed_ean.base_ean);
return;
}
}
function appendSet(set1, set2){
for(key in set2){
set1[key] = set2[key];
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});
}else{
selectedOrder.addProduct(new module.Product(product));
}
}
var categories_by_id = {};
for(var i = 0; i < categories.length; i++){
categories_by_id[categories[i].id] = categories[i];
}
this.categories_by_id = categories_by_id;
var root_category = {
name : 'Root',
id : 0,
parent : null,
childrens : [],
};
// add parent and childrens field to categories, find root_categories
for(var i = 0; i < categories.length; i++){
var cat = categories[i];
cat.parent = categories_by_id[cat.parent_id[0]];
if(!cat.parent){
root_category.childrens.push(cat);
cat.parent = root_category;
}
cat.childrens = [];
for(var j = 0; j < cat.child_id.length; j++){
cat.childrens.push(categories_by_id[ cat.child_id[j] ]);
}
}
categories.push(root_category);
// set some default fields for next steps
for(var i = 0; i < categories.length; i++){
var cat = categories[i];
cat.product_list = []; //list of all products in the category
cat.product_set = {}; // [product.id] === true if product is in category
cat.weightable_product_list = [];
cat.weightable_product_set = {};
cat.weightable = false; //true if directly contains weightable products
}
this.root_category = root_category;
//we add the products to the categories.
for(var i = 0, len = products.length; i < len; i++){
var product = products[i];
var cat = categories_by_id[product.pos_categ_id[0]];
if(cat){
cat.product_list.push(product);
cat.product_set[product.id] = true;
if(product.to_weight){
cat.weightable_product_list.push(product);
cat.weightable_product_set[product.id] = true;
cat.weightable = true;
}
}
}
// we build a flat list of all categories that directly contains weightable products
this.weightable_categories = [];
for(var i = 0, len = categories.length; i < len; i++){
var cat = categories[i];
if(cat.weightable){
this.weightable_categories.push(cat);
}
}
// add ancestor field to categories, contains the list of parents of parents, from root to parent
function make_ancestors(cat, ancestors){
cat.ancestors = ancestors.slice(0);
ancestors.push(cat);
for(var i = 0; i < cat.childrens.length; i++){
make_ancestors(cat.childrens[i], ancestors.slice(0));
}
}
//add the products of the subcategories to the parent categories
function make_products(cat){
for(var i = 0; i < cat.childrens.length; i++){
make_products(cat.childrens[i]);
append(cat.product_list, cat.childrens[i].product_list);
append(cat.weightable_product_list, cat.childrens[i].weightable_product_list);
appendSet(cat.product_set, cat.childrens[i].product_set);
appendSet(cat.weightable_product_set, cat.childrens[i].weightable_product_set);
}
}
make_ancestors(root_category,[]);
make_products(root_category);
def.resolve();
});
return def;
},
});

View File

@ -159,17 +159,20 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
// 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){
if(this.pos_widget.scan_product(ean)){
this.pos.proxy.scan_item_success(ean);
if(this.barcode_product_screen){
this.pos_widget.screen_selector.set_current_screen(this.barcode_product_screen);
}
}else{
this.pos.proxy.scan_item_error_unrecognized(ean);
if(this.barcode_product_error_popup && this.pos_widget.screen_selector.get_user_mode() !== 'cashier'){
this.pos_widget.screen_selector.show_popup(this.barcode_product_error_popup);
}
}
var self = this;
this.pos_widget.scan_product(ean)
.done(function(){
self.pos.proxy.scan_item_success(ean);
if(self.barcode_product_screen){
self.pos_widget.screen_selector.set_current_screen(self.barcode_product_screen);
}
})
.fail(function(){
self.pos.proxy.scan_item_error_unrecognized(ean);
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.

View File

@ -396,29 +396,21 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
// changes the category. if undefined, sets to root category
set_category : function(category){
var db = this.pos.db;
if(!category){
this.category = this.pos.root_category;
this.category = db.get_category_by_id(db.root_category_id);
}else{
this.category = category;
}
this.breadcrumb = [];
for(var i = 1; i < this.category.ancestors.length; i++){
this.breadcrumb.push(this.category.ancestors[i]);
var ancestors_ids = db.get_category_ancestors_ids(this.category.id);
for(var i = 1; i < ancestors_ids.length; i++){
this.breadcrumb.push(db.get_category_by_id(ancestors_ids[i]));
}
if(this.category !== this.pos.root_category){
if(this.category.id !== db.root_category_id){
this.breadcrumb.push(this.category);
}
if(this.product_type === 'weightable'){
this.subcategories = [];
for(var i = 0; i < this.category.childrens.length; i++){
if(this.category.childrens[i].weightable_product_list.length > 0){
this.subcategories.push( this.category.childrens[i]);
}
}
}else{
this.subcategories = this.category.childrens || [];
}
this.subcategories = db.get_category_by_id(db.get_category_childs_ids(this.category.id));
},
renderElement: function(){
@ -443,7 +435,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
$(button).appendTo(this.$('.category-list')).click(function(event){
var id = category.id;
var cat = self.pos.categories_by_id[id];
var cat = self.pos.db.get_category_by_id(id);
self.set_category(cat);
self.renderElement();
self.search_and_categories(cat);
@ -452,7 +444,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
// breadcrumb click actions
this.$(".oe-pos-categories-list a").click(function(event){
var id = $(event.target).data("category-id");
var category = self.pos.categories_by_id[id];
var category = self.pos.db.get_category_by_id(id);
self.set_category(category);
self.renderElement();
self.search_and_categories(category);
@ -475,50 +467,39 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
// filters the products, and sets up the search callbacks
search_and_categories: function(category){
var self = this;
var all_products = this.pos.get('product_list');
var all_packages = this.pos.get('product.packaging');
// find all products belonging to the current category
var products = [];
if(this.product_type === 'weightable'){
products = all_products.filter( function(product){
return self.category.weightable_product_set[product.id];
});
}else{
products = all_products.filter( function(product){
return self.category.product_set[product.id];
});
}
this.pos.db.get_product_by_category(this.category.id, function(products){
// product lists watch for reset events on 'products' to re-render.
// FIXME that means all productlist widget re-render... even the hidden ones !
self.pos.get('products').reset(products);
});
// product lists watch for reset events on 'products' to re-render.
// FIXME that means all productlist widget re-render... even the hidden ones !
this.pos.get('products').reset(products);
// find all the products whose name match the query in the searchbox
// filter the products according to the search string
this.$('.searchbox input').keyup(function(){
var results, search_str;
search_str = $(this).val().toLowerCase();
if(search_str){
results = products.filter( function(p){
return p.name.toLowerCase().indexOf(search_str) != -1 ||
(p.ean13 && p.ean13.indexOf(search_str) != -1);
query = $(this).val().toLowerCase();
if(query){
self.pos.db.search_product_in_category(self.category.id, ['name','ean13'], query, function(products){
self.pos.get('products').reset(products);
self.$('.search-clear').fadeIn();
});
self.$element.find('.search-clear').fadeIn();
}else{
results = products;
self.$element.find('.search-clear').fadeOut();
self.pos.db.get_product_by_category(self.category.id, function(products){
self.pos.get('products').reset(products);
self.$('.search-clear').fadeOut();
});
}
self.pos.get('products').reset(results);
});
this.$('.searchbox input').click(function(){
});
this.$('.searchbox input').click(function(){}); //Why ???
//reset the search when clicking on reset
this.$('.search-clear').click(function(){
self.pos.get('products').reset(products);
self.$('.searchbox input').val('').focus();
self.$('.search-clear').fadeOut();
self.pos.db.get_product_by_category(self.category.id, function(products){
self.pos.get('products').reset(products);
self.$('.searchbox input').val('').focus();
self.$('.search-clear').fadeOut();
});
});
},
});
@ -693,7 +674,9 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
self.build_currency_template();
self.renderElement();
self.$('.neworder-button').click(_.bind(self.create_new_order, self));
self.$('.neworder-button').click(function(){
self.pos.add_new_order();
});
//when a new order is created, add an order button widget
self.pos.get('orders').bind('add', function(new_order){
@ -721,7 +704,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
self.screen_selector.show_popup('error', 'Sorry, we could not find any PoS Configuration for this session');
}
self.$('.loader').animate({opacity:0},3000,'swing',function(){self.$('.loader').hide();});
self.$('.loader').animate({opacity:0},1500,'swing',function(){self.$('.loader').hide();});
self.$('.loader img').hide();
if(jQuery.deparam(jQuery.param.querystring()).debug !== undefined){
@ -851,51 +834,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
},
//FIXME this method is probably not at the right place ...
scan_product: function(parsed_ean){
var selectedOrder = this.pos.get('selectedOrder');
var scannedProductModel = this.get_product_by_ean(parsed_ean);
if (!scannedProductModel){
return false;
} else {
if(parsed_ean.type === 'price'){
selectedOrder.addProduct(new module.Product(scannedProductModel), { price:parsed_ean.value});
}else if(parsed_ean.type === 'weight'){
selectedOrder.addProduct(new module.Product(scannedProductModel), { quantity:parsed_ean.value, merge:false});
}else{
selectedOrder.addProduct(new module.Product(scannedProductModel));
}
return true;
}
},
get_product_by_ean: function(parsed_ean) {
var allProducts = this.pos.get('product_list');
var allPackages = this.pos.get('product.packaging');
var scannedProductModel = undefined;
if (parsed_ean.type === 'price' || parsed_ean.type === 'weight') {
var itemCode = parsed_ean.id;
var scannedPackaging = _.detect(allPackages, function(pack) {
return pack.ean && pack.ean.substring(0,7) === itemCode;
});
if (scannedPackaging) {
scannedProductModel = _.detect(allProducts, function(pc) { return pc.id === scannedPackaging.product_id[0];});
}else{
scannedProductModel = _.detect(allProducts, function(pc) { return pc.ean13 && (pc.ean13.substring(0,7) === parsed_ean.id);});
}
} else if(parsed_ean.type === 'unit'){
scannedProductModel = _.detect(allProducts, function(pc) { return pc.ean13 === parsed_ean.ean;}); //TODO DOES NOT SCALE
}
return scannedProductModel;
},
// creates a new order, and add it to the list of orders.
create_new_order: function() {
var new_order;
new_order = new module.Order({ pos: this.pos });
this.pos.get('orders').add(new_order);
this.pos.set({ selectedOrder: new_order });
},
changed_pending_operations: function () {
var self = this;
this.synch_notification.on_change_nbr_pending(self.pos.get('nbr_pending_operations').length);