2012-08-07 16:18:44 +00:00
|
|
|
function openerp_pos_db(instance, module){
|
|
|
|
|
2013-12-16 14:35:59 +00:00
|
|
|
/* The PosDB holds reference to data that is either
|
|
|
|
* - static: does not change between pos reloads
|
|
|
|
* - persistent : must stay between reloads ( orders )
|
2013-01-11 14:41:08 +00:00
|
|
|
*/
|
|
|
|
|
2013-12-16 14:35:59 +00:00
|
|
|
module.PosDB = instance.web.Class.extend({
|
|
|
|
name: 'openerp_pos_db', //the prefix of the localstorage data
|
2012-08-10 13:58:32 +00:00
|
|
|
limit: 100, // the maximum number of results returned by a search
|
2012-08-07 16:18:44 +00:00
|
|
|
init: function(options){
|
|
|
|
options = options || {};
|
|
|
|
this.name = options.name || this.name;
|
|
|
|
this.limit = options.limit || this.limit;
|
2012-08-09 17:21:13 +00:00
|
|
|
|
2012-08-14 11:56:30 +00:00
|
|
|
//cache the data in memory to avoid roundtrips to the localstorage
|
|
|
|
this.cache = {};
|
2012-08-10 13:58:32 +00:00
|
|
|
|
2013-01-15 16:51:37 +00:00
|
|
|
this.product_by_id = {};
|
|
|
|
this.product_by_ean13 = {};
|
|
|
|
this.product_by_category_id = {};
|
2013-09-23 14:51:39 +00:00
|
|
|
this.product_by_reference = {};
|
2013-01-15 16:51:37 +00:00
|
|
|
|
2012-08-09 17:21:13 +00:00
|
|
|
this.category_by_id = {};
|
|
|
|
this.root_category_id = 0;
|
|
|
|
this.category_products = {};
|
|
|
|
this.category_ancestors = {};
|
|
|
|
this.category_childs = {};
|
|
|
|
this.category_parent = {};
|
2012-08-16 15:02:13 +00:00
|
|
|
this.category_search_string = {};
|
2012-09-13 14:03:10 +00:00
|
|
|
this.packagings_by_id = {};
|
2014-06-03 09:53:41 +00:00
|
|
|
this.packagings_by_product_tmpl_id = {};
|
2013-01-15 16:51:37 +00:00
|
|
|
this.packagings_by_ean13 = {};
|
2012-08-09 17:21:13 +00:00
|
|
|
},
|
2012-08-16 15:02:13 +00:00
|
|
|
/* returns the category object from its id. If you pass a list of id as parameters, you get
|
|
|
|
* a list of category objects.
|
|
|
|
*/
|
2012-08-09 17:21:13 +00:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
},
|
2012-08-10 13:58:32 +00:00
|
|
|
/* returns a list of the category's child categories ids, or an empty list
|
|
|
|
* if a category has no childs */
|
2012-08-09 17:21:13 +00:00
|
|
|
get_category_childs_ids: function(categ_id){
|
|
|
|
return this.category_childs[categ_id] || [];
|
|
|
|
},
|
2012-08-10 13:58:32 +00:00
|
|
|
/* returns a list of all ancestors (parent, grand-parent, etc) categories ids
|
|
|
|
* starting from the root category to the direct parent */
|
2012-08-09 17:21:13 +00:00
|
|
|
get_category_ancestors_ids: function(categ_id){
|
|
|
|
return this.category_ancestors[categ_id] || [];
|
|
|
|
},
|
2012-08-10 13:58:32 +00:00
|
|
|
/* returns the parent category's id of a category, or the root_category_id if no parent.
|
|
|
|
* the root category is parent of itself. */
|
2012-08-09 17:21:13 +00:00
|
|
|
get_category_parent_id: function(categ_id){
|
|
|
|
return this.category_parent[categ_id] || this.root_category_id;
|
|
|
|
},
|
2012-08-10 13:58:32 +00:00
|
|
|
/* 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 */
|
2012-08-09 17:21:13 +00:00
|
|
|
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++){
|
|
|
|
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;
|
|
|
|
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, []);
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2012-08-14 11:56:30 +00:00
|
|
|
/* loads a record store from the database. returns default if nothing is found */
|
|
|
|
load: function(store,deft){
|
|
|
|
if(this.cache[store] !== undefined){
|
|
|
|
return this.cache[store];
|
2012-08-10 13:58:32 +00:00
|
|
|
}
|
2012-08-14 11:56:30 +00:00
|
|
|
var data = localStorage[this.name + '_' + store];
|
2013-12-16 14:35:59 +00:00
|
|
|
if(data !== undefined && data !== ""){
|
2012-08-14 11:56:30 +00:00
|
|
|
data = JSON.parse(data);
|
|
|
|
this.cache[store] = data;
|
|
|
|
return data;
|
2012-08-07 16:18:44 +00:00
|
|
|
}else{
|
2012-08-14 11:56:30 +00:00
|
|
|
return deft;
|
2012-08-07 16:18:44 +00:00
|
|
|
}
|
|
|
|
},
|
2012-08-14 11:56:30 +00:00
|
|
|
/* saves a record store to the database */
|
|
|
|
save: function(store,data){
|
2013-01-11 14:41:08 +00:00
|
|
|
var str_data = JSON.stringify(data);
|
2012-08-14 11:56:30 +00:00
|
|
|
localStorage[this.name + '_' + store] = JSON.stringify(data);
|
|
|
|
this.cache[store] = data;
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2012-08-16 15:02:13 +00:00
|
|
|
_product_search_string: function(product){
|
|
|
|
var str = '' + product.id + ':' + product.name;
|
|
|
|
if(product.ean13){
|
|
|
|
str += '|' + product.ean13;
|
|
|
|
}
|
2013-09-12 14:12:08 +00:00
|
|
|
if(product.default_code){
|
|
|
|
str += '|' + product.default_code;
|
|
|
|
}
|
2014-06-03 09:53:41 +00:00
|
|
|
var packagings = this.packagings_by_product_tmpl_id[product.product_tmpl_id] || [];
|
2012-09-13 14:03:10 +00:00
|
|
|
for(var i = 0; i < packagings.length; i++){
|
|
|
|
str += '|' + packagings[i].ean;
|
|
|
|
}
|
2012-08-16 15:02:13 +00:00
|
|
|
return str + '\n';
|
|
|
|
},
|
2012-08-09 19:55:55 +00:00
|
|
|
add_products: function(products){
|
2013-01-15 16:51:37 +00:00
|
|
|
var stored_categories = this.product_by_category_id;
|
2012-08-07 16:18:44 +00:00
|
|
|
|
|
|
|
if(!products instanceof Array){
|
|
|
|
products = [products];
|
|
|
|
}
|
|
|
|
for(var i = 0, len = products.length; i < len; i++){
|
|
|
|
var product = products[i];
|
2012-08-16 15:02:13 +00:00
|
|
|
var search_string = this._product_search_string(product);
|
2014-05-27 08:36:08 +00:00
|
|
|
var categ_id = product.pos_categ_id ? product.pos_categ_id[0] : this.root_category_id;
|
2014-05-16 12:06:17 +00:00
|
|
|
if (product.variants){
|
|
|
|
product.name = product.name+" ("+product.variants+")";
|
|
|
|
}
|
2014-06-03 09:53:41 +00:00
|
|
|
product.product_tmpl_id = product.product_tmpl_id[0];
|
2012-08-09 17:21:13 +00:00
|
|
|
if(!stored_categories[categ_id]){
|
|
|
|
stored_categories[categ_id] = [];
|
|
|
|
}
|
|
|
|
stored_categories[categ_id].push(product.id);
|
2012-08-16 15:02:13 +00:00
|
|
|
|
|
|
|
if(this.category_search_string[categ_id] === undefined){
|
|
|
|
this.category_search_string[categ_id] = '';
|
|
|
|
}
|
|
|
|
this.category_search_string[categ_id] += search_string;
|
|
|
|
|
2012-08-09 17:21:13 +00:00
|
|
|
var ancestors = this.get_category_ancestors_ids(categ_id) || [];
|
|
|
|
|
2013-03-12 15:06:38 +00:00
|
|
|
for(var j = 0, jlen = ancestors.length; j < jlen; j++){
|
2012-08-16 15:02:13 +00:00
|
|
|
var ancestor = ancestors[j];
|
|
|
|
if(! stored_categories[ancestor]){
|
|
|
|
stored_categories[ancestor] = [];
|
2012-08-09 17:21:13 +00:00
|
|
|
}
|
2012-08-16 15:02:13 +00:00
|
|
|
stored_categories[ancestor].push(product.id);
|
|
|
|
|
|
|
|
if( this.category_search_string[ancestor] === undefined){
|
|
|
|
this.category_search_string[ancestor] = '';
|
|
|
|
}
|
|
|
|
this.category_search_string[ancestor] += search_string;
|
2012-08-07 16:18:44 +00:00
|
|
|
}
|
2013-01-15 16:51:37 +00:00
|
|
|
this.product_by_id[product.id] = product;
|
|
|
|
if(product.ean13){
|
|
|
|
this.product_by_ean13[product.ean13] = product;
|
|
|
|
}
|
2013-09-23 14:51:39 +00:00
|
|
|
if(product.default_code){
|
|
|
|
this.product_by_reference[product.default_code] = product;
|
|
|
|
}
|
2012-08-07 16:18:44 +00:00
|
|
|
}
|
|
|
|
},
|
2012-09-13 10:46:21 +00:00
|
|
|
add_packagings: function(packagings){
|
|
|
|
for(var i = 0, len = packagings.length; i < len; i++){
|
|
|
|
var pack = packagings[i];
|
2012-09-13 14:03:10 +00:00
|
|
|
this.packagings_by_id[pack.id] = pack;
|
2014-06-03 09:53:41 +00:00
|
|
|
if(!this.packagings_by_product_tmpl_id[pack.product_tmpl_id[0]]){
|
|
|
|
this.packagings_by_product_tmpl_id[pack.product_tmpl_id[0]] = [];
|
2012-09-13 14:03:10 +00:00
|
|
|
}
|
2014-06-03 09:53:41 +00:00
|
|
|
this.packagings_by_product_tmpl_id[pack.product_tmpl_id[0]].push(pack);
|
2013-05-21 09:09:42 +00:00
|
|
|
if(pack.ean){
|
|
|
|
this.packagings_by_ean13[pack.ean] = pack;
|
2013-01-15 16:51:37 +00:00
|
|
|
}
|
2012-09-13 10:46:21 +00:00
|
|
|
}
|
|
|
|
},
|
2012-08-10 13:58:32 +00:00
|
|
|
/* removes all the data from the database. TODO : being able to selectively remove data */
|
2012-08-14 15:21:12 +00:00
|
|
|
clear: function(stores){
|
|
|
|
for(var i = 0, len = arguments.length; i < len; i++){
|
|
|
|
localStorage.removeItem(this.name + '_' + arguments[i]);
|
|
|
|
}
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2012-08-10 13:58:32 +00:00
|
|
|
/* this internal methods returns the count of properties in an object. */
|
2012-08-07 16:18:44 +00:00
|
|
|
_count_props : function(obj){
|
2012-08-10 13:58:32 +00:00
|
|
|
var count = 0;
|
|
|
|
for(var prop in obj){
|
|
|
|
if(obj.hasOwnProperty(prop)){
|
|
|
|
count++;
|
2012-08-07 16:18:44 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-10 13:58:32 +00:00
|
|
|
return count;
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2012-08-13 16:00:26 +00:00
|
|
|
get_product_by_id: function(id){
|
2013-01-15 16:51:37 +00:00
|
|
|
return this.product_by_id[id];
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2012-08-13 16:00:26 +00:00
|
|
|
get_product_by_ean13: function(ean13){
|
2013-01-15 16:51:37 +00:00
|
|
|
if(this.product_by_ean13[ean13]){
|
2013-01-15 17:25:25 +00:00
|
|
|
return this.product_by_ean13[ean13];
|
2012-08-07 16:18:44 +00:00
|
|
|
}
|
2013-01-15 16:51:37 +00:00
|
|
|
var pack = this.packagings_by_ean13[ean13];
|
|
|
|
if(pack){
|
|
|
|
return this.product_by_id[pack.product_id[0]];
|
2012-09-13 14:03:10 +00:00
|
|
|
}
|
2012-08-13 16:00:26 +00:00
|
|
|
return undefined;
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2013-09-23 14:51:39 +00:00
|
|
|
get_product_by_reference: function(ref){
|
|
|
|
return this.product_by_reference[ref];
|
|
|
|
},
|
2012-08-13 16:00:26 +00:00
|
|
|
get_product_by_category: function(category_id){
|
2013-01-15 16:51:37 +00:00
|
|
|
var product_ids = this.product_by_category_id[category_id];
|
2012-08-07 16:18:44 +00:00
|
|
|
var list = [];
|
2012-11-28 06:29:26 +00:00
|
|
|
if (product_ids) {
|
|
|
|
for (var i = 0, len = Math.min(product_ids.length, this.limit); i < len; i++) {
|
2013-01-15 16:51:37 +00:00
|
|
|
list.push(this.product_by_id[product_ids[i]]);
|
2012-11-28 06:29:26 +00:00
|
|
|
}
|
2012-08-07 16:18:44 +00:00
|
|
|
}
|
2012-08-13 16:00:26 +00:00
|
|
|
return list;
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2012-08-16 15:02:13 +00:00
|
|
|
/* returns a list of products with :
|
2012-08-10 13:58:32 +00:00
|
|
|
* - a category that is or is a child of category_id,
|
2012-08-16 15:02:13 +00:00
|
|
|
* - a name, package or ean13 containing the query (case insensitive)
|
2012-08-10 13:58:32 +00:00
|
|
|
*/
|
2012-08-16 15:02:13 +00:00
|
|
|
search_product_in_category: function(category_id, query){
|
|
|
|
var re = RegExp("([0-9]+):.*?"+query,"gi");
|
|
|
|
var results = [];
|
|
|
|
for(var i = 0; i < this.limit; i++){
|
|
|
|
r = re.exec(this.category_search_string[category_id]);
|
|
|
|
if(r){
|
|
|
|
var id = Number(r[1]);
|
|
|
|
results.push(this.get_product_by_id(id));
|
|
|
|
}else{
|
|
|
|
break;
|
2012-08-07 16:18:44 +00:00
|
|
|
}
|
2012-08-10 13:58:32 +00:00
|
|
|
}
|
2012-08-16 15:02:13 +00:00
|
|
|
return results;
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2012-08-13 16:00:26 +00:00
|
|
|
add_order: function(order){
|
2013-04-11 12:07:19 +00:00
|
|
|
var order_id = order.uid;
|
2012-08-14 11:56:30 +00:00
|
|
|
var orders = this.load('orders',[]);
|
2013-04-11 12:07:19 +00:00
|
|
|
|
|
|
|
// if the order was already stored, we overwrite its data
|
|
|
|
for(var i = 0, len = orders.length; i < len; i++){
|
|
|
|
if(orders[i].id === order_id){
|
|
|
|
orders[i].data = order;
|
|
|
|
this.save('orders',orders);
|
|
|
|
return order_id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-28 15:07:18 +00:00
|
|
|
orders.push({id: order_id, data: order});
|
2012-08-14 11:56:30 +00:00
|
|
|
this.save('orders',orders);
|
2013-03-28 15:07:18 +00:00
|
|
|
return order_id;
|
2012-08-09 17:21:13 +00:00
|
|
|
},
|
2012-08-13 16:00:26 +00:00
|
|
|
remove_order: function(order_id){
|
2012-08-14 11:56:30 +00:00
|
|
|
var orders = this.load('orders',[]);
|
|
|
|
orders = _.filter(orders, function(order){
|
|
|
|
return order.id !== order_id;
|
|
|
|
});
|
|
|
|
this.save('orders',orders);
|
2012-08-07 16:18:44 +00:00
|
|
|
},
|
2012-08-13 16:00:26 +00:00
|
|
|
get_orders: function(){
|
2012-08-14 11:56:30 +00:00
|
|
|
return this.load('orders',[]);
|
|
|
|
},
|
2013-03-28 15:07:18 +00:00
|
|
|
get_order: function(order_id){
|
|
|
|
var orders = this.get_orders();
|
|
|
|
for(var i = 0, len = orders.length; i < len; i++){
|
|
|
|
if(orders[i].id === order_id){
|
|
|
|
return orders[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return undefined;
|
|
|
|
},
|
2012-08-14 11:56:30 +00:00
|
|
|
});
|
2012-08-07 16:18:44 +00:00
|
|
|
}
|