[IMP] point_of_sale: IndexedDB: the LocalStorage DB is working now
bzr revid: fva@openerp.com-20120810135832-7xb3yq0r1p829nv1
This commit is contained in:
parent
78d8b5d394
commit
760939d83f
|
@ -1,15 +1,20 @@
|
|||
/**
|
||||
* WIP : AS OF THIS COMMIT, THE INDEXEDB BACKEND IS IN A NON WORKING STATE
|
||||
*
|
||||
* This file contains an IndexedDB (html5 database) backend for the Point Of Sale.
|
||||
* The IDB is used to store the list of products and especially their thumbnails, which may
|
||||
* not fit in the localStorage.
|
||||
* The IDB offers a big performance boost for products lookup, but not so much for search as
|
||||
* searching is not yet implemented in the IndexedDB API and must be performed manually in JS.
|
||||
*
|
||||
* this file also contains a localstorage implementation of the database to be used by browsers
|
||||
* that don't support the indexeddb api.
|
||||
*
|
||||
*/
|
||||
function openerp_pos_db(instance, module){
|
||||
|
||||
// this is used for testing
|
||||
window.gen_products = function(options){
|
||||
var gen_products = function(options){
|
||||
options = options || {};
|
||||
var count = options.count || 100;
|
||||
var imageSize = options.imageSize || 1800;
|
||||
|
@ -60,10 +65,13 @@ function openerp_pos_db(instance, module){
|
|||
};
|
||||
|
||||
//this is used for testing
|
||||
window.log = function(x){
|
||||
var log = function(x){
|
||||
console.log(x);
|
||||
};
|
||||
|
||||
// window.gen_products = gen_products;
|
||||
// window.log = log;
|
||||
|
||||
function importIndexedDB(){
|
||||
if('indexedDB' in window){
|
||||
return true;
|
||||
|
@ -330,9 +338,12 @@ function openerp_pos_db(instance, module){
|
|||
});
|
||||
window.PosDB = module.PosDB;
|
||||
|
||||
/* PosLS is a LocalStorage based implementation of the point of sale database,
|
||||
it performs better for few products, but does not scale beyond 500 products.
|
||||
*/
|
||||
module.PosLS = instance.web.Class.extend({
|
||||
name: 'openerp_pos_ls',
|
||||
limit: 50,
|
||||
name: 'openerp_pos_ls', //the prefix of the localstorage data
|
||||
limit: 100, // the maximum number of results returned by a search
|
||||
init: function(options){
|
||||
options = options || {};
|
||||
this.name = options.name || this.name;
|
||||
|
@ -340,6 +351,10 @@ function openerp_pos_db(instance, module){
|
|||
this.products = this.name + '_products';
|
||||
this.categories = this.name + '_categories';
|
||||
|
||||
//products cache put the data in memory to avoid roundtrips to the localstorage
|
||||
this.products_cache = null;
|
||||
this.categories_cache = null;
|
||||
|
||||
this.category_by_id = {};
|
||||
this.root_category_id = 0;
|
||||
this.category_products = {};
|
||||
|
@ -347,6 +362,7 @@ function openerp_pos_db(instance, module){
|
|||
this.category_childs = {};
|
||||
this.category_parent = {};
|
||||
},
|
||||
/* returns the category object from its id */
|
||||
get_category_by_id: function(categ_id){
|
||||
if(categ_id instanceof Array){
|
||||
var list = [];
|
||||
|
@ -363,15 +379,24 @@ function openerp_pos_db(instance, module){
|
|||
return this.category_by_id[categ_id];
|
||||
}
|
||||
},
|
||||
/* returns a list of the category's child categories ids, or an empty list
|
||||
* if a category has no childs */
|
||||
get_category_childs_ids: function(categ_id){
|
||||
return this.category_childs[categ_id] || [];
|
||||
},
|
||||
/* returns a list of all ancestors (parent, grand-parent, etc) categories ids
|
||||
* starting from the root category to the direct parent */
|
||||
get_category_ancestors_ids: function(categ_id){
|
||||
return this.category_ancestors[categ_id] || [];
|
||||
},
|
||||
/* returns the parent category's id of a category, or the root_category_id if no parent.
|
||||
* the root category is parent of itself. */
|
||||
get_category_parent_id: function(categ_id){
|
||||
return this.category_parent[categ_id] || this.root_category_id;
|
||||
},
|
||||
/* adds categories definitions to the database. categories is a list of categories objects as
|
||||
* returned by the openerp server. Categories must be inserted before the products or the
|
||||
* product/ categories association may (will) not work properly */
|
||||
add_categories: function(categories){
|
||||
var self = this;
|
||||
if(!this.category_by_id[this.root_category_id]){
|
||||
|
@ -381,13 +406,11 @@ function openerp_pos_db(instance, module){
|
|||
};
|
||||
}
|
||||
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] = [];
|
||||
|
@ -407,7 +430,11 @@ function openerp_pos_db(instance, module){
|
|||
}
|
||||
make_ancestors(this.root_category_id, []);
|
||||
},
|
||||
/* this internal method returns from disc a dictionary associating ids to the products */
|
||||
_get_products: function(){
|
||||
if(this.products_cache){
|
||||
return this.products_cache;
|
||||
}
|
||||
var products = localStorage[this.products];
|
||||
if(products){
|
||||
return JSON.parse(products) || {};
|
||||
|
@ -415,10 +442,16 @@ function openerp_pos_db(instance, module){
|
|||
return {};
|
||||
}
|
||||
},
|
||||
/* this internal method saves a dictionary associating ids to product to the disc */
|
||||
_set_products: function(products){
|
||||
localStorage[this.products] = JSON.stringify(products);
|
||||
this.products_cache = products;
|
||||
},
|
||||
/* this internal method returns from disc a dictionary associating ids to the categories */
|
||||
_get_categories: function(){
|
||||
if(this.categories_cache){
|
||||
return this.categories_cache;
|
||||
}
|
||||
var categories = localStorage[this.categories];
|
||||
if(categories){
|
||||
return JSON.parse(categories) || {};
|
||||
|
@ -426,8 +459,10 @@ function openerp_pos_db(instance, module){
|
|||
return {};
|
||||
}
|
||||
},
|
||||
/* this internal method saves to disc an array associating ids to the categories */
|
||||
_set_categories: function(categories){
|
||||
localStorage[this.categories] = JSON.stringify(categories);
|
||||
this.categories_cache = categories;
|
||||
},
|
||||
add_products: function(products){
|
||||
var stored_products = this._get_products();
|
||||
|
@ -444,7 +479,6 @@ function openerp_pos_db(instance, module){
|
|||
}
|
||||
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]]){
|
||||
|
@ -457,6 +491,7 @@ function openerp_pos_db(instance, module){
|
|||
this._set_products(stored_products);
|
||||
this._set_categories(stored_categories);
|
||||
},
|
||||
/* removes all the data from the database. TODO : being able to selectively remove data */
|
||||
clear: function(done_callback){
|
||||
localStorage.removeItem(this.products);
|
||||
localStorage.removeItem(this.categories);
|
||||
|
@ -464,18 +499,15 @@ function openerp_pos_db(instance, module){
|
|||
done_callback();
|
||||
}
|
||||
},
|
||||
/* this internal methods returns the count of properties in an object. */
|
||||
_count_props : function(obj){
|
||||
if(obj.__count__){
|
||||
return obj.__count__;
|
||||
}else{
|
||||
var count = 0;
|
||||
for(var prop in obj){
|
||||
if(obj.hasOwnProperty(prop)){
|
||||
count++;
|
||||
}
|
||||
var count = 0;
|
||||
for(var prop in obj){
|
||||
if(obj.hasOwnProperty(prop)){
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
return count;
|
||||
},
|
||||
get_product_count: function(result_callback){
|
||||
result_callback(this._count_props(this._get_products()));
|
||||
|
@ -509,50 +541,54 @@ function openerp_pos_db(instance, module){
|
|||
var stored_products = this._get_products();
|
||||
var product_ids = stored_categories[category_id];
|
||||
var list = [];
|
||||
for(var i = 0, len = product_ids.length; i < len; i++){
|
||||
for(var i = 0, len = Math.min(product_ids.length,this.limit); i < len; i++){
|
||||
list.push(stored_products[product_ids[i]]);
|
||||
}
|
||||
result_callback(list);
|
||||
},
|
||||
/* returns as a parameter of the result_callback function a list of products with :
|
||||
* - a category that is or is a child of category_id,
|
||||
* - a field in fields that contains a value that contains the query
|
||||
* If a search is started before the previous has returned, the previous search may be cancelled
|
||||
* (and the corresponding result_callback never called)
|
||||
*/
|
||||
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 = [];
|
||||
var stored_categories = this._get_categories();
|
||||
var stored_products = this._get_products();
|
||||
var product_ids = stored_categories[category_id];
|
||||
var list = [];
|
||||
var count = 0;
|
||||
|
||||
query = query.toString().toLowerCase();
|
||||
|
||||
query = query.toString().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{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(field.toLowerCase().indexOf(query) != -1){
|
||||
list.push(products[i]);
|
||||
break;
|
||||
}
|
||||
if(!(fields instanceof Array)){
|
||||
fields = [fields];
|
||||
}
|
||||
for(var i = 0, len = product_ids.length; i < len && count < this.limit; i++){
|
||||
var product = stored_products[product_ids[i]];
|
||||
for(var j = 0, jlen = fields.length; j < jlen; j++){
|
||||
var field = product[fields[j]];
|
||||
if(field === null || field === undefined){
|
||||
continue;
|
||||
}
|
||||
field = field.toString().toLowerCase();
|
||||
if(field.indexOf(query) != -1){
|
||||
list.push(product);
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result_callback(list);
|
||||
});
|
||||
}
|
||||
result_callback(list);
|
||||
},
|
||||
// TODO move the order storage from the crappy DAO in pos_models.js
|
||||
add_order: function(order,done_callback){
|
||||
},
|
||||
remove_order: function(order_id, done_callback){
|
||||
},
|
||||
get_orders: function(result_callback){
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
window.PosLS = module.PosLS;
|
||||
|
|
Loading…
Reference in New Issue