diff --git a/addons/point_of_sale/static/src/js/pos_db.js b/addons/point_of_sale/static/src/js/pos_db.js index a38457a9f8d..59ea0da1684 100644 --- a/addons/point_of_sale/static/src/js/pos_db.js +++ b/addons/point_of_sale/static/src/js/pos_db.js @@ -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; diff --git a/addons/point_of_sale/static/src/js/pos_devices.js b/addons/point_of_sale/static/src/js/pos_devices.js index c7d96eccffc..d39597c0b02 100644 --- a/addons/point_of_sale/static/src/js/pos_devices.js +++ b/addons/point_of_sale/static/src/js/pos_devices.js @@ -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 { diff --git a/addons/point_of_sale/static/src/js/pos_models.js b/addons/point_of_sale/static/src/js/pos_models.js index b4684c037b2..ee0c770e6e6 100644 --- a/addons/point_of_sale/static/src/js/pos_models.js +++ b/addons/point_of_sale/static/src/js/pos_models.js @@ -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; }, }); diff --git a/addons/point_of_sale/static/src/js/pos_screens.js b/addons/point_of_sale/static/src/js/pos_screens.js index 07f1071fa6d..310d80a3603 100644 --- a/addons/point_of_sale/static/src/js/pos_screens.js +++ b/addons/point_of_sale/static/src/js/pos_screens.js @@ -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. diff --git a/addons/point_of_sale/static/src/js/pos_widgets.js b/addons/point_of_sale/static/src/js/pos_widgets.js index a30a0ebe521..34de4cf567f 100644 --- a/addons/point_of_sale/static/src/js/pos_widgets.js +++ b/addons/point_of_sale/static/src/js/pos_widgets.js @@ -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);