-function openerp_pos_models(instance, module){ //module is instance.point_of_sale
+openerp.point_of_sale.load_models = function load_models(instance, module){ //module is instance.point_of_sale
"use strict";
var QWeb = instance.web.qweb;
var _t = instance.web._t;
+ var barcode_parser_module = instance.barcodes;
var round_di = instance.web.round_decimals;
var round_pr = instance.web.round_precision
this.pos_widget = attributes.pos_widget;
this.proxy = new module.ProxyDevice(this); // used to communicate to the hardware devices via a local proxy
- this.barcode_reader = new module.BarcodeReader({'pos': this, proxy:this.proxy, patterns: {}}); // used to read barcodes
+ this.barcode_reader = new module.BarcodeReader({'pos': this, proxy:this.proxy});
+
this.proxy_queue = new module.JobQueue(); // used to prevent parallels communications to the proxy
this.db = new module.PosDB(); // a local database used to search trough products and categories & store pending orders
this.debug = jQuery.deparam(jQuery.param.querystring()).debug !== undefined; //debug mode
this.partners = [];
this.cashier = null;
this.cashregisters = [];
- this.bankstatements = [];
this.taxes = [];
this.pos_session = null;
this.config = null;
if(self.config.use_proxy){
return self.connect_to_proxy();
}
- });
-
+ }); // used to read barcodes);
},
// releases ressources holds by the model at the end of life of the posmodel
self.units_by_id = units_by_id;
}
},{
- model: 'res.users',
- fields: ['name','ean13'],
- domain: null,
- loaded: function(self,users){ self.users = users; },
- },{
model: 'res.partner',
- fields: ['name','street','city','state_id','country_id','vat','phone','zip','mobile','email','ean13','write_date'],
- domain: null,
+ fields: ['name','street','city','state_id','country_id','vat','phone','zip','mobile','email','barcode','write_date'],
+ domain: [['customer','=',true]],
loaded: function(self,partners){
self.partners = partners;
self.db.add_partners(partners);
model: 'account.tax',
fields: ['name','amount', 'price_include', 'type'],
domain: null,
- loaded: function(self,taxes){ self.taxes = taxes; },
+ loaded: function(self,taxes){
+ self.taxes = taxes;
+ self.taxes_by_id = {};
+
+ for (var i = 0; i < taxes.length; i++) {
+ self.taxes_by_id[taxes[i].id] = taxes[i];
+ }
+ },
},{
model: 'pos.session',
fields: ['id', 'journal_ids','name','user_id','config_id','start_at','stop_at','sequence_number','login_number'],
self.config.iface_print_via_proxy ||
self.config.iface_scan_via_proxy ||
self.config.iface_cashdrawer;
-
- self.barcode_reader.add_barcode_patterns({
- 'product': self.config.barcode_product,
- 'cashier': self.config.barcode_cashier,
- 'client': self.config.barcode_customer,
- 'weight': self.config.barcode_weight,
- 'discount': self.config.barcode_discount,
- 'price': self.config.barcode_price,
- });
-
if (self.config.company_id[0] !== self.user.company_id[0]) {
throw new Error(_t("Error: The Point of Sale User must belong to the same company as the Point of Sale. You are probably trying to load the point of sale as an administrator in a multi-company setup, with the administrator account set to the wrong company."));
for (var i = 0; i < orders.length; i++) {
self.pos_session.sequence_number = Math.max(self.pos_session.sequence_number, orders[i].data.sequence_number+1);
}
+ },
+ },{
+ model: 'res.users',
+ fields: ['name','pos_security_pin','groups_id','barcode'],
+ domain: function(self){ return [['company_id','=',self.user.company_id[0]],'|', ['groups_id','=', self.config.group_pos_manager_id[0]],['groups_id','=', self.config.group_pos_user_id[0]]]; },
+ loaded: function(self,users){
+ // we attribute a role to the user, 'cashier' or 'manager', depending
+ // on the group the user belongs.
+ var pos_users = [];
+ for (var i = 0; i < users.length; i++) {
+ var user = users[i];
+ for (var j = 0; j < user.groups_id.length; j++) {
+ var group_id = user.groups_id[j];
+ if (group_id === self.config.group_pos_manager_id[0]) {
+ user.role = 'manager';
+ break;
+ } else if (group_id === self.config.group_pos_user_id[0]) {
+ user.role = 'cashier';
+ }
+ }
+ if (user.role) {
+ pos_users.push(user);
+ }
+ // replace the current user with its updated version
+ if (user.id === self.user.id) {
+ self.user = user;
+ }
+ }
+ self.users = pos_users;
},
},{
model: 'stock.location',
},
},{
model: 'product.packaging',
- fields: ['ean','product_tmpl_id'],
+ fields: ['barcode','product_tmpl_id'],
domain: null,
loaded: function(self, packagings){
self.db.add_packagings(packagings);
},
},{
model: 'product.product',
- fields: ['display_name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code',
+ fields: ['display_name', 'list_price','price','pos_categ_id', 'taxes_id', 'barcode', 'default_code',
'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description',
'product_tmpl_id'],
- domain: function(self){ return [['sale_ok','=',true],['available_in_pos','=',true]]; },
+ order: ['sequence','name'],
+ domain: [['sale_ok','=',true],['available_in_pos','=',true]],
context: function(self){ return { pricelist: self.pricelist.id, display_default_code: false }; },
loaded: function(self, products){
self.db.add_products(products);
model: 'account.bank.statement',
fields: ['account_id','currency','journal_id','state','name','user_id','pos_session_id'],
domain: function(self){ return [['state', '=', 'open'],['pos_session_id', '=', self.pos_session.id]]; },
- loaded: function(self, bankstatements, tmp){
- self.bankstatements = bankstatements;
+ loaded: function(self, cashregisters, tmp){
+ self.cashregisters = cashregisters;
tmp.journals = [];
- _.each(bankstatements,function(statement){
+ _.each(cashregisters,function(statement){
tmp.journals.push(statement.journal_id[0]);
});
},
self.journals = journals;
// associate the bank statements with their journals.
- var bankstatements = self.bankstatements;
- for(var i = 0, ilen = bankstatements.length; i < ilen; i++){
+ var cashregisters = self.cashregisters;
+ for(var i = 0, ilen = cashregisters.length; i < ilen; i++){
for(var j = 0, jlen = journals.length; j < jlen; j++){
- if(bankstatements[i].journal_id[0] === journals[j].id){
- bankstatements[i].journal = journals[j];
+ if(cashregisters[i].journal_id[0] === journals[j].id){
+ cashregisters[i].journal = journals[j];
}
}
}
- self.cashregisters = bankstatements;
+
self.cashregisters_by_id = {};
for (var i = 0; i < self.cashregisters.length; i++) {
self.cashregisters_by_id[self.cashregisters[i].id] = self.cashregisters[i];
}
+
+ self.cashregisters = self.cashregisters.sort(function(a,b){
+ return a.journal.sequence - b.journal.sequence;
+ });
+
},
- },{
+ }, {
label: 'fonts',
loaded: function(self){
var fonts_loaded = new $.Deferred();
return logo_loaded;
},
- },
+ }, {
+ label: 'barcodes',
+ loaded: function(self) {
+ var barcode_parser = new barcode_parser_module.BarcodeParser({'nomenclature_id': self.config.barcode_nomenclature_id});
+ self.barcode_reader.set_barcode_parser(barcode_parser);
+ return barcode_parser.is_loaded();
+ },
+ }
],
// loads all the needed data on the sever. returns a deferred indicating when all the data has loaded.
var domain = typeof model.domain === 'function' ? model.domain(self,tmp) : model.domain;
var context = typeof model.context === 'function' ? model.context(self,tmp) : model.context;
var ids = typeof model.ids === 'function' ? model.ids(self,tmp) : model.ids;
+ var order = typeof model.order === 'function' ? model.order(self,tmp): model.order;
progress += progress_step;
if (model.ids) {
var records = new instance.web.Model(model.model).call('read',[ids,fields],context);
} else {
- var records = new instance.web.Model(model.model).query(fields).filter(domain).context(context).all()
+ var records = new instance.web.Model(model.model).query(fields).filter(domain).order_by(order).context(context).all()
}
records.then(function(result){
try{ // catching exceptions in model.loaded(...)
} else {
def.reject();
}
- }, function(){ def.reject(); });
+ }, function(err,event){ event.preventDefault(); def.reject(); });
return def;
},
}
},
+ // returns the user who is currently the cashier for this point of sale
+ get_cashier: function(){
+ return this.cashier || this.user;
+ },
+ // changes the current cashier
+ set_cashier: function(user){
+ this.cashier = user;
+ },
//creates a new empty order and sets it as the current order
add_new_order: function(){
var order = new module.Order({},{pos:this});
scan_product: function(parsed_code){
var self = this;
- var selectedOrder = this.get_order();
- if(parsed_code.encoding === 'ean13'){
- var product = this.db.get_product_by_ean13(parsed_code.base_code);
- }else if(parsed_code.encoding === 'reference'){
- var product = this.db.get_product_by_reference(parsed_code.code);
- }
+ var selectedOrder = this.get_order();
+ var product = this.db.get_product_by_barcode(parsed_code.base_code);
if(!product){
return false;
get_tax_details: function(){
return this.get_all_prices().taxDetails;
},
+ get_taxes: function(){
+ var taxes_ids = this.get_product().taxes_id;
+ var taxes = [];
+ for (var i = 0; i < taxes_ids.length; i++) {
+ taxes.push(this.pos.taxes_by_id[taxes_ids[i]]);
+ }
+ return taxes;
+ },
get_all_prices: function(){
var self = this;
var currency_rounding = this.pos.currency.rounding;
return fulldetails;
},
+ // Returns a total only for the orderlines with products belonging to the category
+ get_total_for_category_with_tax: function(categ_id){
+ var total = 0;
+ var self = this;
+
+ if (categ_id instanceof Array) {
+ for (var i = 0; i < categ_id.length; i++) {
+ total += this.get_total_for_category_with_tax(categ_id[i]);
+ }
+ return total;
+ }
+
+ this.orderlines.each(function(line){
+ if ( self.pos.db.category_contains(categ_id,line.product.id) ) {
+ total += line.get_price_with_tax();
+ }
+ });
+
+ return total;
+ },
+ get_total_for_taxes: function(tax_id){
+ var total = 0;
+ var self = this;
+
+ if (!(tax_id instanceof Array)) {
+ tax_id = [tax_id];
+ }
+
+ var tax_set = {};
+
+ for (var i = 0; i < tax_id.length; i++) {
+ tax_set[tax_id[i]] = true;
+ }
+
+ this.orderlines.each(function(line){
+ var taxes_ids = line.get_product().taxes_id;
+ for (var i = 0; i < taxes_ids.length; i++) {
+ if (tax_set[taxes_ids[i]]) {
+ total += line.get_price_with_tax();
+ return;
+ }
+ }
+ });
+
+ return total;
+ },
get_change: function(paymentline) {
if (!paymentline) {
var change = this.get_total_paid() - this.get_total_with_tax();