Markus Schneider
10 years ago
3 changed files with 288 additions and 0 deletions
-
21pos_localstorage/__init__.py
-
43pos_localstorage/__openerp__.py
-
224pos_localstorage/static/src/js/models.js
@ -0,0 +1,21 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# OpenERP, Open Source Management Solution |
|||
# Copyright (C) 2010-2013 OpenERP s.a. (<http://openerp.com>). |
|||
# Copyright (C) 2013 initOS GmbH & Co. KG (<http://www.initos.com>). |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
@ -0,0 +1,43 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2015 initOS GmbH & Co. KG (<http://www.initos.com>). |
|||
# Author Thomas Rehn <thomas.rehn at initos.com> |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
{ |
|||
'name': 'POS Local Storage Product Cache', |
|||
'version': '0.1', |
|||
'category': 'Point Of Sale', |
|||
'author': 'initOS GmbH & Co. KG, ' |
|||
'Odoo Community Association (OCA)', |
|||
'description': """ |
|||
Local Storage Cache for Point of Sale |
|||
===================================== |
|||
|
|||
Stores product data in localStorage to improve booting time. |
|||
""", |
|||
'depends': ["point_of_sale", |
|||
], |
|||
'data': [ |
|||
], |
|||
'js': [ |
|||
'static/src/js/models.js', |
|||
], |
|||
'installable': True, |
|||
'application': False, |
|||
'auto_install': False, |
|||
} |
@ -0,0 +1,224 @@ |
|||
openerp.pos_localstorage = function(instance){ |
|||
var module = instance.point_of_sale; |
|||
|
|||
var UpdateProducts = { |
|||
runOnce: function(pos) { |
|||
var self = this; |
|||
// We subtract the following period from the last update time
|
|||
// to make sure that we get all changes (including those that happened
|
|||
// during the last update phase).
|
|||
var _searchGracePeriod = 30 * 60 * 1000; // 30 minutes
|
|||
// List of product attributes that the POS uses.
|
|||
var productAttributeList = ['name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code', 'variants', |
|||
'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description']; |
|||
|
|||
var lastUpdate = pos.db.load('last_product_update'); |
|||
if (!lastUpdate) |
|||
lastUpdate = '1970-01-01T00:00:00Z'; |
|||
|
|||
// Fetch all products that we sell and that have not been changed since
|
|||
// we updated for the last time.
|
|||
return pos.fetch( |
|||
'product.product', |
|||
['id'], |
|||
[['sale_ok', '=', true], ['available_in_pos', '=', true], ['write_date', '<', lastUpdate]] |
|||
).then(function(products){ |
|||
var products_to_add = []; |
|||
var products_to_fetch = []; |
|||
for (var i in products) { |
|||
// Try to get product information from localStorage.
|
|||
// If this fails, we load the information from the server.
|
|||
var product = pos.db.load('product_' + products[i].id); |
|||
if (product) { |
|||
products_to_add.push(product); |
|||
} else { |
|||
products_to_fetch.push(products[i].id); |
|||
} |
|||
} |
|||
// Add products that we have in localStorage
|
|||
pos.db.add_products(products_to_add); |
|||
|
|||
// Fetch all products that we don't have the data
|
|||
// because they were not in localStorage or they are new
|
|||
return pos.fetch('product.product', |
|||
productAttributeList, |
|||
['|', ['id', 'in', products_to_fetch], |
|||
'&', '&', ['sale_ok', '=', true], ['available_in_pos', '=', true], ['write_date', '>=', lastUpdate]], |
|||
{pricelist: pos.get('shop').pricelist_id[0]} // context for price
|
|||
); |
|||
}).then(function(products){ |
|||
pos.db.add_products(products); |
|||
|
|||
lastUpdate = new Date(Date.now() - _searchGracePeriod).toISOString(); |
|||
pos.db.save('last_product_update', lastUpdate); |
|||
}); |
|||
}, |
|||
}; |
|||
|
|||
|
|||
var _old_initialize = module.PosModel.prototype.initialize; |
|||
module.PosModel.prototype.initialize = function(session, attributes) { |
|||
var ret = _old_initialize.call(this, session, attributes); |
|||
// HACK to make localStorage abstraction dependent of the database
|
|||
this.db.name = session.db; |
|||
// clear database again after setting the name;
|
|||
this.db.clear('products','categories'); |
|||
return ret; |
|||
}; |
|||
|
|||
// Overwrite method to additionally save product data in localStorage
|
|||
var _old_add_products = module.PosLS.prototype.add_products; |
|||
module.PosLS.prototype.add_products = function(products) { |
|||
_old_add_products.call(this, products); |
|||
try { |
|||
for (var i in products) { |
|||
var product = products[i]; |
|||
this.save('product_' + product.id, product); |
|||
} |
|||
} catch(e) { |
|||
if (console) { |
|||
console.log("Could not store all products into LocalStorage"); |
|||
console.log(e); |
|||
} |
|||
// We delete the last ~100 products to free up space.
|
|||
// If localStorage is full, some other features may crash.
|
|||
var length = localStorage.length; |
|||
for (var i = 1; i <= 100; ++i) { |
|||
var key = localStorage.key(length - i); |
|||
if (/product_\d+$/.exec(key)) { |
|||
localStorage.removeItem(key); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
// overwrite method in order to replace product loading
|
|||
module.PosModel.prototype.load_server_data = function(){ |
|||
var self = this; |
|||
|
|||
var loaded = self.fetch('res.users',['name','company_id'],[['id','=',this.session.uid]]) |
|||
.then(function(users){ |
|||
self.set('user',users[0]); |
|||
|
|||
return self.fetch('res.company', |
|||
[ |
|||
'currency_id', |
|||
'email', |
|||
'website', |
|||
'company_registry', |
|||
'vat', |
|||
'name', |
|||
'phone', |
|||
'partner_id', |
|||
], |
|||
[['id','=',users[0].company_id[0]]]); |
|||
}).then(function(companies){ |
|||
self.set('company',companies[0]); |
|||
|
|||
return self.fetch('res.partner',['contact_address'],[['id','=',companies[0].partner_id[0]]]); |
|||
}).then(function(company_partners){ |
|||
self.get('company').contact_address = company_partners[0].contact_address; |
|||
|
|||
return self.fetch('product.uom', null, null); |
|||
}).then(function(units){ |
|||
self.set('units',units); |
|||
var units_by_id = {}; |
|||
for(var i = 0, len = units.length; i < len; i++){ |
|||
units_by_id[units[i].id] = units[i]; |
|||
} |
|||
self.set('units_by_id',units_by_id); |
|||
|
|||
return self.fetch('product.packaging', null, null); |
|||
}).then(function(packagings){ |
|||
self.set('product.packaging',packagings); |
|||
|
|||
return self.fetch('res.users', ['name','ean13'], [['ean13', '!=', false]]); |
|||
}).then(function(users){ |
|||
self.set('user_list',users); |
|||
|
|||
return self.fetch('res.partner', ['name','ean13'], [['ean13', '!=', false]]); |
|||
}).then(function(partners){ |
|||
self.set('partner_list',partners); |
|||
|
|||
return self.fetch('account.tax', ['amount', 'price_include', 'type']); |
|||
}).then(function(taxes){ |
|||
self.set('taxes', taxes); |
|||
|
|||
return self.fetch( |
|||
'pos.session', |
|||
['id', 'journal_ids','name','user_id','config_id','start_at','stop_at'], |
|||
[['state', '=', 'opened'], ['user_id', '=', self.session.uid]] |
|||
); |
|||
}).then(function(sessions){ |
|||
self.set('pos_session', sessions[0]); |
|||
|
|||
return self.fetch( |
|||
'pos.config', |
|||
['name','journal_ids','shop_id','journal_id', |
|||
'iface_self_checkout', 'iface_led', 'iface_cashdrawer', |
|||
'iface_payment_terminal', 'iface_electronic_scale', 'iface_barscan', 'iface_vkeyboard', |
|||
'iface_print_via_proxy','iface_cashdrawer','state','sequence_id','session_ids'], |
|||
[['id','=', self.get('pos_session').config_id[0]]] |
|||
); |
|||
}).then(function(configs){ |
|||
var pos_config = configs[0]; |
|||
self.set('pos_config', pos_config); |
|||
self.iface_electronic_scale = !!pos_config.iface_electronic_scale; |
|||
self.iface_print_via_proxy = !!pos_config.iface_print_via_proxy; |
|||
self.iface_vkeyboard = !!pos_config.iface_vkeyboard; |
|||
self.iface_self_checkout = !!pos_config.iface_self_checkout; |
|||
self.iface_cashdrawer = !!pos_config.iface_cashdrawer; |
|||
|
|||
return self.fetch('sale.shop',[],[['id','=',pos_config.shop_id[0]]]); |
|||
}).then(function(shops){ |
|||
self.set('shop',shops[0]); |
|||
|
|||
return self.fetch('product.pricelist',['currency_id'],[['id','=',self.get('shop').pricelist_id[0]]]); |
|||
}).then(function(pricelists){ |
|||
self.set('pricelist',pricelists[0]); |
|||
|
|||
return self.fetch('res.currency',['symbol','position','rounding','accuracy'],[['id','=',self.get('pricelist').currency_id[0]]]); |
|||
}).then(function(currencies){ |
|||
self.set('currency',currencies[0]); |
|||
|
|||
return self.fetch('product.packaging',['ean','product_id']); |
|||
}).then(function(packagings){ |
|||
self.db.add_packagings(packagings); |
|||
|
|||
return self.fetch('pos.category', ['id','name','parent_id','child_id','image']) |
|||
}).then(function(categories){ |
|||
self.db.add_categories(categories); |
|||
|
|||
return UpdateProducts.runOnce(self); |
|||
}).then(function(products){ |
|||
return self.fetch( |
|||
'account.bank.statement', |
|||
['account_id','currency','journal_id','state','name','user_id','pos_session_id'], |
|||
[['state','=','open'],['pos_session_id', '=', self.get('pos_session').id]] |
|||
); |
|||
}).then(function(bank_statements){ |
|||
var journals = new Array(); |
|||
_.each(bank_statements,function(statement) { |
|||
journals.push(statement.journal_id[0]) |
|||
}); |
|||
self.set('bank_statements', bank_statements); |
|||
return self.fetch('account.journal', undefined, [['id','in', journals]]); |
|||
}).then(function(journals){ |
|||
self.set('journals',journals); |
|||
|
|||
// associate the bank statements with their journals.
|
|||
var bank_statements = self.get('bank_statements'); |
|||
for(var i = 0, ilen = bank_statements.length; i < ilen; i++){ |
|||
for(var j = 0, jlen = journals.length; j < jlen; j++){ |
|||
if(bank_statements[i].journal_id[0] === journals[j].id){ |
|||
bank_statements[i].journal = journals[j]; |
|||
bank_statements[i].self_checkout_payment_method = journals[j].self_checkout_payment_method; |
|||
} |
|||
} |
|||
} |
|||
self.set({'cashRegisters' : new module.CashRegisterCollection(self.get('bank_statements'))}); |
|||
}); |
|||
|
|||
return loaded; |
|||
}; |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue