[MERGE] point_of_sale: various fixes:
- taxes computation - currency rounding - paymentline keyboard focus - css corrections - invoice generation bzr revid: fva@openerp.com-20130129153750-ghb4hrrc289z6kga
This commit is contained in:
commit
e1cb1c660d
|
@ -853,8 +853,7 @@ class pos_order(osv.osv):
|
|||
inv_line['price_unit'] = line.price_unit
|
||||
inv_line['discount'] = line.discount
|
||||
inv_line['name'] = inv_name
|
||||
inv_line['invoice_line_tax_id'] = ('invoice_line_tax_id' in inv_line)\
|
||||
and [(6, 0, inv_line['invoice_line_tax_id'])] or []
|
||||
inv_line['invoice_line_tax_id'] = [(6, 0, [x.id for x in line.product_id.taxes_id] )]
|
||||
inv_line_ref.create(cr, uid, inv_line, context=context)
|
||||
inv_ref.button_reset_taxes(cr, uid, [inv_id], context=context)
|
||||
wf_service.trg_validate(uid, 'pos.order', order.id, 'invoice', cr)
|
||||
|
@ -1156,7 +1155,6 @@ class pos_order_line(osv.osv):
|
|||
|
||||
prod = self.pool.get('product.product').browse(cr, uid, product, context=context)
|
||||
|
||||
taxes = prod.taxes_id
|
||||
price = price_unit * (1 - (discount or 0.0) / 100.0)
|
||||
taxes = account_tax_obj.compute_all(cr, uid, prod.taxes_id, price, qty, product=prod, partner=False)
|
||||
|
||||
|
|
|
@ -233,7 +233,9 @@
|
|||
font-style: italic;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.point-of-sale .oe_pos_synch-notification.oe_inactive{
|
||||
cursor: default;
|
||||
}
|
||||
.point-of-sale .oe_pos_synch-notification .oe_status_red{
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
|
@ -542,7 +544,9 @@
|
|||
background: -webkit-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
|
||||
background: -moz-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
|
||||
background: -ms-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
|
||||
background: linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
|
||||
/* for some reason the -90deg orientation doesn't match the -webkit-linear-gradient. It should be 180deg here.
|
||||
* webkit also insists on rendering *both* gradients instead of only the native one. So it doesn't looks right. ugh.
|
||||
background: linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1)); */
|
||||
/*background:#FFF;*/
|
||||
padding: 3px;
|
||||
padding-top: 15px;
|
||||
|
@ -607,7 +611,9 @@
|
|||
background: -webkit-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
|
||||
background: -moz-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
|
||||
background: -ms-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
|
||||
/* troublesome in latest webkit
|
||||
background: linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
|
||||
*/
|
||||
/*background:#FFF;*/
|
||||
padding: 3px;
|
||||
padding-top:15px;
|
||||
|
@ -991,12 +997,20 @@
|
|||
margin-bottom:10px;
|
||||
}
|
||||
.point-of-sale .order .summary .line{
|
||||
float: right;
|
||||
margin-right:15px;
|
||||
margin-left: 15px;
|
||||
padding-top:5px;
|
||||
border-top: solid 2px;
|
||||
border-color:#777;
|
||||
}
|
||||
.point-of-sale .order .summary .line .subentry{
|
||||
font-size: 10px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
.point-of-sale .order .summary .line.empty{
|
||||
text-align: right;
|
||||
border-color:#BBB;
|
||||
color:#999;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ function openerp_pos_db(instance, module){
|
|||
//cache the data in memory to avoid roundtrips to the localstorage
|
||||
this.cache = {};
|
||||
|
||||
this.product_by_id = {};
|
||||
this.product_by_ean13 = {};
|
||||
this.product_by_category_id = {};
|
||||
|
||||
this.category_by_id = {};
|
||||
this.root_category_id = 0;
|
||||
this.category_products = {};
|
||||
|
@ -49,6 +53,7 @@ function openerp_pos_db(instance, module){
|
|||
this.category_search_string = {};
|
||||
this.packagings_by_id = {};
|
||||
this.packagings_by_product_id = {};
|
||||
this.packagings_by_ean13 = {};
|
||||
},
|
||||
/* returns the category object from its id. If you pass a list of id as parameters, you get
|
||||
* a list of category objects.
|
||||
|
@ -137,7 +142,6 @@ function openerp_pos_db(instance, module){
|
|||
/* saves a record store to the database */
|
||||
save: function(store,data){
|
||||
var str_data = JSON.stringify(data);
|
||||
console.log('Storing '+ Math.round(str_data.length/1024.0)+' KB of data to store: '+store);
|
||||
localStorage[this.name + '_' + store] = JSON.stringify(data);
|
||||
this.cache[store] = data;
|
||||
},
|
||||
|
@ -153,8 +157,7 @@ function openerp_pos_db(instance, module){
|
|||
return str + '\n';
|
||||
},
|
||||
add_products: function(products){
|
||||
var stored_products = this.load('products',{});
|
||||
var stored_categories = this.load('categories',{});
|
||||
var stored_categories = this.product_by_category_id;
|
||||
|
||||
if(!products instanceof Array){
|
||||
products = [products];
|
||||
|
@ -187,10 +190,11 @@ function openerp_pos_db(instance, module){
|
|||
}
|
||||
this.category_search_string[ancestor] += search_string;
|
||||
}
|
||||
stored_products[product.id] = product;
|
||||
this.product_by_id[product.id] = product;
|
||||
if(product.ean13){
|
||||
this.product_by_ean13[product.ean13] = product;
|
||||
}
|
||||
}
|
||||
this.save('products',stored_products);
|
||||
this.save('categories',stored_categories);
|
||||
},
|
||||
add_packagings: function(packagings){
|
||||
for(var i = 0, len = packagings.length; i < len; i++){
|
||||
|
@ -200,6 +204,9 @@ function openerp_pos_db(instance, module){
|
|||
this.packagings_by_product_id[pack.product_id[0]] = [];
|
||||
}
|
||||
this.packagings_by_product_id[pack.product_id[0]].push(pack);
|
||||
if(pack.ean13){
|
||||
this.packagings_by_ean13[pack.ean13] = pack;
|
||||
}
|
||||
}
|
||||
},
|
||||
/* removes all the data from the database. TODO : being able to selectively remove data */
|
||||
|
@ -219,31 +226,24 @@ function openerp_pos_db(instance, module){
|
|||
return count;
|
||||
},
|
||||
get_product_by_id: function(id){
|
||||
return this.load('products',{})[id];
|
||||
return this.product_by_id[id];
|
||||
},
|
||||
get_product_by_ean13: function(ean13){
|
||||
var products = this.load('products',{});
|
||||
for(var i in products){
|
||||
if( products[i] && products[i].ean13 === ean13){
|
||||
return products[i];
|
||||
}
|
||||
if(this.product_by_ean13[ean13]){
|
||||
return this.product_by_ean13[ean13];
|
||||
}
|
||||
for(var p in this.packagings_by_id){
|
||||
var pack = this.packagings_by_id[p];
|
||||
if( pack.ean === ean13){
|
||||
return products[pack.product_id[0]];
|
||||
}
|
||||
var pack = this.packagings_by_ean13[ean13];
|
||||
if(pack){
|
||||
return this.product_by_id[pack.product_id[0]];
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
get_product_by_category: function(category_id){
|
||||
var stored_categories = this.load('categories',{});
|
||||
var stored_products = this.load('products',{});
|
||||
var product_ids = stored_categories[category_id];
|
||||
var product_ids = this.product_by_category_id[category_id];
|
||||
var list = [];
|
||||
if (product_ids) {
|
||||
for (var i = 0, len = Math.min(product_ids.length, this.limit); i < len; i++) {
|
||||
list.push(stored_products[product_ids[i]]);
|
||||
list.push(this.product_by_id[product_ids[i]]);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
|
@ -275,12 +275,9 @@ function openerp_pos_db(instance, module){
|
|||
},
|
||||
remove_order: function(order_id){
|
||||
var orders = this.load('orders',[]);
|
||||
console.log('Remove order:',order_id);
|
||||
console.log('Order count:',orders.length);
|
||||
orders = _.filter(orders, function(order){
|
||||
return order.id !== order_id;
|
||||
});
|
||||
console.log('Order count:',orders.length);
|
||||
this.save('orders',orders);
|
||||
},
|
||||
get_orders: function(){
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
function openerp_pos_models(instance, module){ //module is instance.point_of_sale
|
||||
var QWeb = instance.web.qweb;
|
||||
|
||||
// rounds a value with a fixed number of decimals.
|
||||
// round(3.141492,2) -> 3.14
|
||||
function round(value,decimals){
|
||||
var mult = Math.pow(10,decimals || 0);
|
||||
return Math.round(value*mult)/mult;
|
||||
}
|
||||
window.round = round;
|
||||
|
||||
// rounds a value with decimal form precision
|
||||
// round(3.141592,0.025) ->3.125
|
||||
function round_pr(value,precision){
|
||||
if(!precision || precision < 0){
|
||||
throw new Error('round_pr(): needs a precision greater than zero, got '+precision+' instead');
|
||||
}
|
||||
return Math.round(value / precision) * precision;
|
||||
}
|
||||
window.round_pr = round_pr;
|
||||
|
||||
|
||||
// The PosModel contains the Point Of Sale's representation of the backend.
|
||||
// Since the PoS must work in standalone ( Without connection to the server )
|
||||
|
@ -24,8 +42,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
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
|
||||
this.db.clear('products','categories');
|
||||
this.debug = jQuery.deparam(jQuery.param.querystring()).debug !== undefined; //debug mode
|
||||
|
||||
this.debug = jQuery.deparam(jQuery.param.querystring()).debug !== undefined; //debug mode
|
||||
|
||||
// default attributes values. If null, it will be loaded below.
|
||||
this.set({
|
||||
|
@ -101,8 +118,9 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
}).then(function(company_partners){
|
||||
self.get('company').contact_address = company_partners[0].contact_address;
|
||||
|
||||
return self.fetch('res.currency',['symbol','position'],[['id','=',self.get('company').currency_id[0]]]);
|
||||
return self.fetch('res.currency',['symbol','position','rounding','accuracy'],[['id','=',self.get('company').currency_id[0]]]);
|
||||
}).then(function(currencies){
|
||||
console.log('Currency:',currencies[0]);
|
||||
self.set('currency',currencies[0]);
|
||||
|
||||
return self.fetch('product.uom', null, null);
|
||||
|
@ -117,7 +135,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
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);
|
||||
|
@ -211,7 +229,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
// logs the usefull posmodel data to the console for debug purposes
|
||||
log_loaded_data: function(){
|
||||
console.log('PosModel data has been loaded:');
|
||||
console.log('PosModel: categories:',this.get('categories'));
|
||||
console.log('PosModel: units:',this.get('units'));
|
||||
console.log('PosModel: bank_statements:',this.get('bank_statements'));
|
||||
console.log('PosModel: journals:',this.get('journals'));
|
||||
|
@ -339,19 +356,26 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
this.product = options.product;
|
||||
this.price = options.product.get('price');
|
||||
this.quantity = 1;
|
||||
this.quantityStr = '1';
|
||||
this.discount = 0;
|
||||
this.discountStr = '0';
|
||||
this.type = 'unit';
|
||||
this.selected = false;
|
||||
},
|
||||
// sets a discount [0,100]%
|
||||
set_discount: function(discount){
|
||||
this.discount = Math.max(0,Math.min(100,discount));
|
||||
var disc = Math.min(Math.max(parseFloat(discount) || 0, 0),100);
|
||||
this.discount = disc;
|
||||
this.discountStr = '' + disc;
|
||||
this.trigger('change');
|
||||
},
|
||||
// returns the discount [0,100]%
|
||||
get_discount: function(){
|
||||
return this.discount;
|
||||
},
|
||||
get_discount_str: function(){
|
||||
return this.discountStr;
|
||||
},
|
||||
get_product_type: function(){
|
||||
return this.type;
|
||||
},
|
||||
|
@ -359,13 +383,18 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
// product's unity of measure properties. Quantities greater than zero will not get
|
||||
// rounded to zero
|
||||
set_quantity: function(quantity){
|
||||
if(_.isNaN(quantity)){
|
||||
if(quantity === 'remove'){
|
||||
this.order.removeOrderline(this);
|
||||
}else if(quantity !== undefined){
|
||||
this.quantity = Math.max(0,quantity);
|
||||
return;
|
||||
}else{
|
||||
var quant = Math.max(parseFloat(quantity) || 0, 0);
|
||||
var unit = this.get_unit();
|
||||
if(unit && this.quantity > 0 ){
|
||||
this.quantity = Math.max(unit.rounding, Math.round(quantity / unit.rounding) * unit.rounding);
|
||||
if(unit){
|
||||
this.quantity = Math.max(unit.rounding, Math.round(quant / unit.rounding) * unit.rounding);
|
||||
this.quantityStr = this.quantity.toFixed(Math.max(0,Math.ceil(Math.log(1.0 / unit.rounding) / Math.log(10))));
|
||||
}else{
|
||||
this.quantity = quant;
|
||||
this.quantityStr = '' + this.quantity;
|
||||
}
|
||||
}
|
||||
this.trigger('change');
|
||||
|
@ -374,6 +403,17 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
get_quantity: function(){
|
||||
return this.quantity;
|
||||
},
|
||||
get_quantity_str: function(){
|
||||
return this.quantityStr;
|
||||
},
|
||||
get_quantity_str_with_unit: function(){
|
||||
var unit = this.get_unit();
|
||||
if(unit && unit.name !== 'Unit(s)'){
|
||||
return this.quantityStr + ' ' + unit.name;
|
||||
}else{
|
||||
return this.quantityStr;
|
||||
}
|
||||
},
|
||||
// return the unit of measure of the product
|
||||
get_unit: function(){
|
||||
var unit_id = (this.product.get('uos_id') || this.product.get('uom_id'));
|
||||
|
@ -390,15 +430,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
get_product: function(){
|
||||
return this.product;
|
||||
},
|
||||
// return the base price of this product (for this orderline)
|
||||
get_price: function(){
|
||||
return this.price;
|
||||
},
|
||||
// changes the base price of the product for this orderline
|
||||
set_price: function(price){
|
||||
this.price = price;
|
||||
this.trigger('change');
|
||||
},
|
||||
// selects or deselects this orderline
|
||||
set_selected: function(selected){
|
||||
this.selected = selected;
|
||||
|
@ -429,7 +460,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
export_as_JSON: function() {
|
||||
return {
|
||||
qty: this.get_quantity(),
|
||||
price_unit: this.get_price(),
|
||||
price_unit: this.get_unit_price(),
|
||||
discount: this.get_discount(),
|
||||
product_id: this.get_product().get('id'),
|
||||
};
|
||||
|
@ -439,9 +470,10 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
return {
|
||||
quantity: this.get_quantity(),
|
||||
unit_name: this.get_unit().name,
|
||||
price: this.get_price(),
|
||||
price: this.get_unit_price(),
|
||||
discount: this.get_discount(),
|
||||
product_name: this.get_product().get('name'),
|
||||
price_display : this.get_display_price(),
|
||||
price_with_tax : this.get_price_with_tax(),
|
||||
price_without_tax: this.get_price_without_tax(),
|
||||
tax: this.get_tax(),
|
||||
|
@ -449,6 +481,19 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
product_description_sale: this.get_product().get('description_sale'),
|
||||
};
|
||||
},
|
||||
// changes the base price of the product for this orderline
|
||||
set_unit_price: function(price){
|
||||
this.price = round(parseFloat(price) || 0, 2);
|
||||
this.trigger('change');
|
||||
},
|
||||
get_unit_price: function(){
|
||||
var rounding = this.pos.get('currency').rounding;
|
||||
return round_pr(this.price,rounding);
|
||||
},
|
||||
get_display_price: function(){
|
||||
var rounding = this.pos.get('currency').rounding;
|
||||
return round_pr(round_pr(this.get_unit_price() * this.get_quantity(),rounding) * (1- this.get_discount()/100.0),rounding);
|
||||
},
|
||||
get_price_without_tax: function(){
|
||||
return this.get_all_prices().priceWithoutTax;
|
||||
},
|
||||
|
@ -458,9 +503,10 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
get_tax: function(){
|
||||
return this.get_all_prices().tax;
|
||||
},
|
||||
get_all_prices: function() {
|
||||
get_all_prices: function(){
|
||||
var self = this;
|
||||
var base = this.get_quantity() * this.price * (1 - (this.get_discount() / 100));
|
||||
var currency_rounding = this.pos.get('currency').rounding;
|
||||
var base = round_pr(this.get_quantity() * this.get_unit_price() * (1.0 - (this.get_discount() / 100.0)), currency_rounding);
|
||||
var totalTax = base;
|
||||
var totalNoTax = base;
|
||||
|
||||
|
@ -474,12 +520,13 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
if (tax.price_include) {
|
||||
var tmp;
|
||||
if (tax.type === "percent") {
|
||||
tmp = base - (base / (1 + tax.amount));
|
||||
tmp = base - round_pr(base / (1 + tax.amount),currency_rounding);
|
||||
} else if (tax.type === "fixed") {
|
||||
tmp = tax.amount * self.get_quantity();
|
||||
tmp = round_pr(tax.amount * self.get_quantity(),currency_rounding);
|
||||
} else {
|
||||
throw "This type of tax is not supported by the point of sale: " + tax.type;
|
||||
}
|
||||
tmp = round_pr(tmp,currency_rounding);
|
||||
taxtotal += tmp;
|
||||
totalNoTax -= tmp;
|
||||
} else {
|
||||
|
@ -491,6 +538,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
} else {
|
||||
throw "This type of tax is not supported by the point of sale: " + tax.type;
|
||||
}
|
||||
tmp = round_pr(tmp,currency_rounding);
|
||||
taxtotal += tmp;
|
||||
totalTax += tmp;
|
||||
}
|
||||
|
@ -515,7 +563,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
},
|
||||
//sets the amount of money on this payment line
|
||||
set_amount: function(value){
|
||||
this.amount = value;
|
||||
this.amount = parseFloat(value) || 0;
|
||||
this.trigger('change');
|
||||
},
|
||||
// returns the amount of money on this paymentline
|
||||
|
@ -584,7 +632,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
line.set_quantity(options.quantity);
|
||||
}
|
||||
if(options.price !== undefined){
|
||||
line.set_price(options.price);
|
||||
line.set_unit_price(options.price);
|
||||
}
|
||||
|
||||
var last_orderline = this.getLastOrderline();
|
||||
|
@ -613,14 +661,19 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
getName: function() {
|
||||
return this.get('name');
|
||||
},
|
||||
getTotal: function() {
|
||||
getSubtotal : function(){
|
||||
return (this.get('orderLines')).reduce((function(sum, orderLine){
|
||||
return sum + orderLine.get_display_price();
|
||||
}), 0);
|
||||
},
|
||||
getTotalTaxIncluded: function() {
|
||||
return (this.get('orderLines')).reduce((function(sum, orderLine) {
|
||||
return sum + orderLine.get_price_with_tax();
|
||||
}), 0);
|
||||
},
|
||||
getDiscountTotal: function() {
|
||||
return (this.get('orderLines')).reduce((function(sum, orderLine) {
|
||||
return sum + (orderLine.get_price() * (orderLine.get_discount()/100) * orderLine.get_quantity());
|
||||
return sum + (orderLine.get_unit_price() * (orderLine.get_discount()/100) * orderLine.get_quantity());
|
||||
}), 0);
|
||||
},
|
||||
getTotalTaxExcluded: function() {
|
||||
|
@ -639,10 +692,10 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
}), 0);
|
||||
},
|
||||
getChange: function() {
|
||||
return this.getPaidTotal() - this.getTotal();
|
||||
return this.getPaidTotal() - this.getTotalTaxIncluded();
|
||||
},
|
||||
getDueLeft: function() {
|
||||
return this.getTotal() - this.getPaidTotal();
|
||||
return this.getTotalTaxIncluded() - this.getPaidTotal();
|
||||
},
|
||||
// sets the type of receipt 'receipt'(default) or 'invoice'
|
||||
set_receipt_type: function(type){
|
||||
|
@ -698,10 +751,12 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
return {
|
||||
orderlines: orderlines,
|
||||
paymentlines: paymentlines,
|
||||
total_with_tax: this.getTotal(),
|
||||
subtotal: this.getSubtotal(),
|
||||
total_with_tax: this.getTotalTaxIncluded(),
|
||||
total_without_tax: this.getTotalTaxExcluded(),
|
||||
total_tax: this.getTax(),
|
||||
total_paid: this.getPaidTotal(),
|
||||
total_discount: this.getDiscountTotal(),
|
||||
change: this.getChange(),
|
||||
name : this.getName(),
|
||||
client: client ? client.name : null ,
|
||||
|
@ -743,7 +798,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
return {
|
||||
name: this.getName(),
|
||||
amount_paid: this.getPaidTotal(),
|
||||
amount_total: this.getTotal(),
|
||||
amount_total: this.getTotalTaxIncluded(),
|
||||
amount_tax: this.getTax(),
|
||||
amount_return: this.getChange(),
|
||||
lines: orderLines,
|
||||
|
@ -800,20 +855,19 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
buffer: (this.get('buffer')) + newChar
|
||||
});
|
||||
}
|
||||
this.updateTarget();
|
||||
this.trigger('set_value',this.get('buffer'));
|
||||
},
|
||||
deleteLastChar: function() {
|
||||
var tempNewBuffer = this.get('buffer').slice(0, -1);
|
||||
|
||||
if(!tempNewBuffer){
|
||||
this.set({ buffer: "0" });
|
||||
this.killTarget();
|
||||
}else{
|
||||
if (isNaN(tempNewBuffer)) {
|
||||
tempNewBuffer = "0";
|
||||
if(this.get('buffer') === ""){
|
||||
if(this.get('mode') === 'quantity'){
|
||||
this.trigger('set_value','remove');
|
||||
}else{
|
||||
this.trigger('set_value',this.get('buffer'));
|
||||
}
|
||||
this.set({ buffer: tempNewBuffer });
|
||||
this.updateTarget();
|
||||
}else{
|
||||
var newBuffer = this.get('buffer').slice(0,-1) || "";
|
||||
this.set({ buffer: newBuffer });
|
||||
this.trigger('set_value',this.get('buffer'));
|
||||
}
|
||||
},
|
||||
switchSign: function() {
|
||||
|
@ -822,7 +876,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
this.set({
|
||||
buffer: oldBuffer[0] === '-' ? oldBuffer.substr(1) : "-" + oldBuffer
|
||||
});
|
||||
this.updateTarget();
|
||||
this.trigger('set_value',this.get('buffer'));
|
||||
},
|
||||
changeMode: function(newMode) {
|
||||
this.set({
|
||||
|
@ -836,15 +890,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
mode: "quantity"
|
||||
});
|
||||
},
|
||||
updateTarget: function() {
|
||||
var bufferContent, params;
|
||||
bufferContent = this.get('buffer');
|
||||
if (bufferContent && !isNaN(bufferContent)) {
|
||||
this.trigger('set_value', parseFloat(bufferContent));
|
||||
}
|
||||
},
|
||||
killTarget: function(){
|
||||
this.trigger('set_value',Number.NaN);
|
||||
resetValue: function(){
|
||||
this.set({buffer:'0'});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -368,7 +368,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
module.ChooseReceiptPopupWidget = module.PopUpWidget.extend({
|
||||
template:'ChooseReceiptPopupWidget',
|
||||
show: function(){
|
||||
console.log('show');
|
||||
this._super();
|
||||
this.renderElement();
|
||||
var self = this;
|
||||
|
@ -603,7 +602,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
// initiates the connection to the payment terminal and starts the update requests
|
||||
this.start = function(){
|
||||
var def = new $.Deferred();
|
||||
console.log("START");
|
||||
self.pos.proxy.payment_request(self.pos.get('selectedOrder').getDueLeft())
|
||||
.done(function(ack){
|
||||
if(ack === 'ok'){
|
||||
|
@ -613,7 +611,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
}else{
|
||||
console.error('unknown payment request return value:',ack);
|
||||
}
|
||||
console.log("START_END");
|
||||
def.resolve();
|
||||
});
|
||||
return def;
|
||||
|
@ -621,10 +618,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
// gets updated status from the payment terminal and performs the appropriate consequences
|
||||
this.update = function(){
|
||||
console.log("UPDATE");
|
||||
var def = new $.Deferred();
|
||||
if(self.canceled){
|
||||
console.log("UPDATE_END");
|
||||
return def.resolve();
|
||||
}
|
||||
self.pos.proxy.payment_status()
|
||||
|
@ -656,7 +651,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
}else{
|
||||
console.error('unknown status value:',status.status);
|
||||
}
|
||||
console.log("UPDATE_END");
|
||||
def.resolve();
|
||||
});
|
||||
return def;
|
||||
|
@ -664,14 +658,12 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
// cancels a payment.
|
||||
this.cancel = function(){
|
||||
console.log("CANCEL");
|
||||
if(!self.paid && !self.canceled){
|
||||
self.canceled = true;
|
||||
self.pos.proxy.payment_cancel();
|
||||
self.pos_widget.screen_selector.set_current_screen(self.previous_screen);
|
||||
self.queue.clear();
|
||||
}
|
||||
console.log("CANCEL_END");
|
||||
return (new $.Deferred()).resolve();
|
||||
}
|
||||
|
||||
|
@ -865,6 +857,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.bindPaymentLineEvents();
|
||||
this.bind_orderline_events();
|
||||
this.paymentlinewidgets = [];
|
||||
this.focusedLine = null;
|
||||
},
|
||||
show: function(){
|
||||
this._super();
|
||||
|
@ -894,6 +887,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
});
|
||||
|
||||
this.updatePaymentSummary();
|
||||
this.line_refocus();
|
||||
},
|
||||
close: function(){
|
||||
this._super();
|
||||
|
@ -931,17 +925,30 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.bind_orderline_events();
|
||||
this.renderElement();
|
||||
},
|
||||
line_refocus: function(lineWidget){
|
||||
if(lineWidget){
|
||||
if(this.focusedLine !== lineWidget){
|
||||
this.focusedLine = lineWidget;
|
||||
}
|
||||
}
|
||||
if(this.focusedLine){
|
||||
this.focusedLine.focus();
|
||||
}
|
||||
},
|
||||
addPaymentLine: function(newPaymentLine) {
|
||||
var self = this;
|
||||
var l = new module.PaymentlineWidget(null, {
|
||||
payment_line: newPaymentLine
|
||||
var l = new module.PaymentlineWidget(this, {
|
||||
payment_line: newPaymentLine,
|
||||
});
|
||||
l.on('delete_payment_line', self, function(r) {
|
||||
self.deleteLine(r);
|
||||
});
|
||||
l.appendTo(this.$('#paymentlines'));
|
||||
this.paymentlinewidgets.push(l);
|
||||
this.$('.paymentline-amount input:last').focus();
|
||||
if(this.numpadState){
|
||||
this.numpadState.resetValue();
|
||||
}
|
||||
this.line_refocus(l);
|
||||
},
|
||||
renderElement: function() {
|
||||
this._super();
|
||||
|
@ -958,25 +965,26 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
deleteLine: function(lineWidget) {
|
||||
this.currentPaymentLines.remove([lineWidget.payment_line]);
|
||||
lineWidget.destroy();
|
||||
},
|
||||
updatePaymentSummary: function() {
|
||||
var currentOrder = this.pos.get('selectedOrder');
|
||||
var paidTotal = currentOrder.getPaidTotal();
|
||||
var dueTotal = currentOrder.getTotal();
|
||||
var dueTotal = currentOrder.getTotalTaxIncluded();
|
||||
var remaining = dueTotal > paidTotal ? dueTotal - paidTotal : 0;
|
||||
var change = paidTotal > dueTotal ? paidTotal - dueTotal : 0;
|
||||
|
||||
this.$('#payment-due-total').html(dueTotal.toFixed(2));
|
||||
this.$('#payment-paid-total').html(paidTotal.toFixed(2));
|
||||
this.$('#payment-remaining').html(remaining.toFixed(2));
|
||||
this.$('#payment-change').html(change.toFixed(2));
|
||||
if((currentOrder.selected_orderline == undefined))
|
||||
remaining = 1
|
||||
this.$('#payment-due-total').html(this.format_currency(dueTotal));
|
||||
this.$('#payment-paid-total').html(this.format_currency(paidTotal));
|
||||
this.$('#payment-remaining').html(this.format_currency(remaining));
|
||||
this.$('#payment-change').html(this.format_currency(change));
|
||||
if(currentOrder.selected_orderline === undefined){
|
||||
remaining = 1; // What is this ?
|
||||
}
|
||||
|
||||
if(this.pos_widget.action_bar){
|
||||
this.pos_widget.action_bar.set_button_disabled('validation', remaining > 0);
|
||||
}
|
||||
this.$('.paymentline-amount input:last').focus();
|
||||
},
|
||||
set_numpad_state: function(numpadState) {
|
||||
if (this.numpadState) {
|
||||
|
@ -998,5 +1006,4 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.currentPaymentLines.last().set_amount(val);
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -22,14 +22,20 @@ function openerp_pos_basewidget(instance, module){ //module is instance.point_of
|
|||
if(this.pos && this.pos.get('currency')){
|
||||
this.currency = this.pos.get('currency');
|
||||
}else{
|
||||
this.currency = {symbol: '$', position: 'after'};
|
||||
this.currency = {symbol: '$', position: 'after', rounding: 0.01};
|
||||
}
|
||||
|
||||
var decimals = Math.max(0,Math.ceil(Math.log(1.0 / this.currency.rounding) / Math.log(10)));
|
||||
|
||||
this.format_currency = function(amount){
|
||||
if(typeof amount === 'number'){
|
||||
amount = Math.round(amount*100)/100;
|
||||
amount = amount.toFixed(decimals);
|
||||
}
|
||||
if(this.currency.position === 'after'){
|
||||
return Math.round(amount*100)/100 + ' ' + this.currency.symbol;
|
||||
return amount + ' ' + this.currency.symbol;
|
||||
}else{
|
||||
return this.currency.symbol + ' ' + Math.round(amount*100)/100;
|
||||
return this.currency.symbol + ' ' + amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
}else if( mode === 'discount'){
|
||||
order.getSelectedLine().set_discount(val);
|
||||
}else if( mode === 'price'){
|
||||
order.getSelectedLine().set_price(val);
|
||||
order.getSelectedLine().set_unit_price(val);
|
||||
}
|
||||
} else {
|
||||
this.pos.get('selectedOrder').destroy();
|
||||
|
@ -269,8 +269,10 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
update_summary: function(){
|
||||
var order = this.pos.get('selectedOrder');
|
||||
var total = order ? order.getTotal() : 0;
|
||||
this.$('.summary .value.total').html(this.format_currency(total));
|
||||
var total = order ? order.getTotalTaxIncluded() : 0;
|
||||
var taxes = order ? total - order.getTotalTaxExcluded() : 0;
|
||||
this.$('.summary .total > .value').html(this.format_currency(total));
|
||||
this.$('.summary .total .subentry .value').html(this.format_currency(taxes));
|
||||
},
|
||||
set_display_mode: function(mode){
|
||||
if(this.display_mode !== mode){
|
||||
|
@ -311,24 +313,34 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
},
|
||||
changeAmount: function(event) {
|
||||
var newAmount = event.currentTarget.value;
|
||||
if (newAmount && !isNaN(newAmount)) {
|
||||
this.amount = parseFloat(newAmount);
|
||||
this.payment_line.set_amount(this.amount);
|
||||
var amount = parseFloat(newAmount);
|
||||
if(!isNaN(amount)){
|
||||
this.amount = amount;
|
||||
this.payment_line.set_amount(amount);
|
||||
}
|
||||
},
|
||||
changedAmount: function() {
|
||||
if (this.amount !== this.payment_line.get_amount())
|
||||
if (this.amount !== this.payment_line.get_amount()){
|
||||
this.renderElement();
|
||||
}
|
||||
},
|
||||
renderElement: function() {
|
||||
var self = this;
|
||||
this.name = this.payment_line.get_cashregister().get('journal_id')[1];
|
||||
this._super();
|
||||
this.$('input').keyup(_.bind(this.changeAmount, this));
|
||||
this.$('input').keyup(function(event){
|
||||
self.changeAmount(event);
|
||||
});
|
||||
this.$('.delete-payment-line').click(function() {
|
||||
self.trigger('delete_payment_line', self);
|
||||
});
|
||||
},
|
||||
focus: function(){
|
||||
var val = this.$('input')[0].value;
|
||||
this.$('input')[0].focus();
|
||||
this.$('input')[0].value = val;
|
||||
this.$('input')[0].select();
|
||||
},
|
||||
});
|
||||
|
||||
module.OrderButtonWidget = module.PosBaseWidget.extend({
|
||||
|
@ -606,20 +618,15 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
if(this.scrollbar){
|
||||
this.scrollbar.destroy();
|
||||
}
|
||||
|
||||
this.pos.get('products')
|
||||
.chain()
|
||||
.map(function(product) {
|
||||
var product = new module.ProductWidget(self, {
|
||||
model: product,
|
||||
weight: self.weight,
|
||||
click_product_action: self.click_product_action,
|
||||
})
|
||||
self.productwidgets.push(product);
|
||||
return product;
|
||||
})
|
||||
.invoke('appendTo', this.$('.product-list'));
|
||||
|
||||
var products = this.pos.get('products').models || [];
|
||||
for(var i = 0, len = products.length; i < len; i++){
|
||||
var product = new module.ProductWidget(self, {
|
||||
model: products[i],
|
||||
click_product_action: this.click_product_action,
|
||||
});
|
||||
this.productwidgets.push(product);
|
||||
product.appendTo(this.$('.product-list'));
|
||||
}
|
||||
this.scrollbar = new module.ScrollbarWidget(this,{
|
||||
target_widget: this,
|
||||
target_selector: '.product-list-scroller',
|
||||
|
|
|
@ -48,11 +48,17 @@
|
|||
</t>
|
||||
|
||||
<t t-name="SynchNotificationWidget">
|
||||
<div class="oe_pos_synch-notification">
|
||||
<t t-if="widget.get_nbr_pending() > 0" t-esc="widget.get_nbr_pending()"/>
|
||||
<div t-if="widget.get_nbr_pending() > 0" class="oe_status_red"></div>
|
||||
<div t-if="widget.get_nbr_pending() === 0" class="oe_status_green"></div>
|
||||
</div>
|
||||
<t t-if="widget.get_nbr_pending() > 0">
|
||||
<div class="oe_pos_synch-notification">
|
||||
<t t-esc="widget.get_nbr_pending()"/>
|
||||
<div class="oe_status_red"></div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="widget.get_nbr_pending() === 0">
|
||||
<div class="oe_pos_synch-notification oe_inactive">
|
||||
<div class="oe_status_green"></div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="HeaderButtonWidget">
|
||||
|
@ -214,11 +220,7 @@
|
|||
<span class="left-block">
|
||||
Total:
|
||||
</span>
|
||||
<span class="right-block">
|
||||
<t t-if="widget.currency.position == 'before'" t-esc="widget.currency.symbol"/>
|
||||
<span id="payment-due-total"></span>
|
||||
<t t-if="widget.currency.position == 'after'" t-esc="widget.currency.symbol"/>
|
||||
</span>
|
||||
<span class='right-block' id="payment-due-total"></span>
|
||||
</div>
|
||||
<table id="paymentlines">
|
||||
</table>
|
||||
|
@ -227,31 +229,19 @@
|
|||
<span class='left-block'>
|
||||
Paid:
|
||||
</span>
|
||||
<span class='right-block'>
|
||||
<t t-if="widget.currency.position == 'before'" t-esc="widget.currency.symbol"/>
|
||||
<span id="payment-paid-total"></span>
|
||||
<t t-if="widget.currency.position == 'after'" t-esc="widget.currency.symbol"/>
|
||||
</span>
|
||||
<span class='right-block' id="payment-paid-total"></span>
|
||||
</div>
|
||||
<div class="infoline">
|
||||
<span class='left-block'>
|
||||
Remaining:
|
||||
</span>
|
||||
<span class='right-block'>
|
||||
<t t-if="widget.currency.position == 'before'" t-esc="widget.currency.symbol"/>
|
||||
<span id="payment-remaining"></span>
|
||||
<t t-if="widget.currency.position == 'after'" t-esc="widget.currency.symbol"/>
|
||||
</span>
|
||||
<span class='right-block' id="payment-remaining"></span>
|
||||
</div>
|
||||
<div class="infoline" >
|
||||
<span class='left-block'>
|
||||
Change:
|
||||
</span>
|
||||
<span class='right-block'>
|
||||
<t t-if="widget.currency.position == 'before'" t-esc="widget.currency.symbol"/>
|
||||
<span id="payment-change"></span>
|
||||
<t t-if="widget.currency.position == 'after'" t-esc="widget.currency.symbol"/>
|
||||
</span>
|
||||
<span class='right-block' id="payment-change"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -431,9 +421,13 @@
|
|||
|
||||
</ul>
|
||||
<div class="summary">
|
||||
<span t-attf-class="line #{widget.pos.get('selectedOrder').get('orderLines').length === 0 ? 'empty' : ''}">
|
||||
<span class="label total">Total:</span> <span class="value total">0.00 €</span>
|
||||
</span>
|
||||
<div t-attf-class="line #{widget.pos.get('selectedOrder').get('orderLines').length === 0 ? 'empty' : ''}">
|
||||
<div class='entry total'>
|
||||
<span class="label">Total: </span> <span class="value">0.00 €</span>
|
||||
<div class='subentry'>Taxes: <span class="value">0.00€</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clear'></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -500,26 +494,26 @@
|
|||
<t t-esc="widget.model.get_product().get('name')"/>
|
||||
</span>
|
||||
<span class="price">
|
||||
<t t-esc="widget.format_currency(widget.model.get_price_with_tax())"/>
|
||||
<t t-esc="widget.format_currency(widget.model.get_display_price())"/>
|
||||
</span>
|
||||
<ul class="info-list">
|
||||
<t t-if="widget.model.get_quantity() !== 1.0">
|
||||
<t t-if="widget.model.get_quantity_str() !== '1'">
|
||||
<li class="info">
|
||||
<em>
|
||||
<t t-esc="widget.model.get_quantity()" />
|
||||
<t t-esc="widget.model.get_quantity_str()" />
|
||||
</em>
|
||||
<t t-esc="widget.model.get_unit().name" />
|
||||
at
|
||||
<t t-esc="widget.format_currency(widget.model.get_price())" />
|
||||
<t t-esc="widget.format_currency(widget.model.get_unit_price())" />
|
||||
/
|
||||
<t t-esc="widget.model.get_unit().name" />
|
||||
</li>
|
||||
</t>
|
||||
<t t-if="widget.model.get_discount() > 0">
|
||||
<t t-if="widget.model.get_discount_str() !== '0'">
|
||||
<li class="info">
|
||||
With a
|
||||
<em>
|
||||
<t t-esc="widget.model.get_discount()" />%
|
||||
<t t-esc="widget.model.get_discount_str()" />%
|
||||
</em>
|
||||
discount
|
||||
</li>
|
||||
|
@ -571,33 +565,36 @@
|
|||
Shop: <t t-esc="widget.shop_obj.name"/><br />
|
||||
<br />
|
||||
<table>
|
||||
<tr t-foreach="widget.currentOrderLines.toArray()" t-as="order">
|
||||
<tr t-foreach="widget.currentOrderLines.toArray()" t-as="orderline">
|
||||
<td>
|
||||
<t t-esc="order.get_product().get('name')"/>
|
||||
<t t-if="order.get_discount() > 0">
|
||||
<t t-esc="orderline.get_product().get('name')"/>
|
||||
<t t-if="orderline.get_discount() > 0">
|
||||
<div class="pos-disc-font">
|
||||
With a <t t-esc="order.get_discount()"/>% discount
|
||||
With a <t t-esc="orderline.get_discount()"/>% discount
|
||||
</div>
|
||||
</t>
|
||||
</td>
|
||||
<td class="pos-right-align">
|
||||
<t t-esc="order.get_quantity().toFixed(0)"/>
|
||||
<t t-esc="orderline.get_quantity_str_with_unit()"/>
|
||||
</td>
|
||||
<td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(order.get_price() * (1 - order.get_discount()/100) * order.get_quantity().toFixed(2))"/>
|
||||
<t t-esc="widget.format_currency(orderline.get_display_price())"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<table>
|
||||
<tr><td>Subtotal:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getSubtotal())"/>
|
||||
</td></tr>
|
||||
<tr><td>Tax:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getTax().toFixed(2))"/>
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getTax())"/>
|
||||
</td></tr>
|
||||
<tr><td>Discount:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getDiscountTotal().toFixed(2))"/>
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getDiscountTotal())"/>
|
||||
</td></tr>
|
||||
<tr class="emph"><td>Total:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getTotal().toFixed(2))"/>
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getTotalTaxIncluded())"/>
|
||||
</td></tr>
|
||||
</table>
|
||||
<br />
|
||||
|
@ -607,14 +604,14 @@
|
|||
<t t-esc="pline.get_cashregister().get('journal_id')[1]"/>
|
||||
</td>
|
||||
<td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency((pline.get_amount()).toFixed(2))"/>
|
||||
<t t-esc="widget.format_currency(pline.get_amount())"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<table>
|
||||
<tr><td>Change:</td><td class="pos-right-align">
|
||||
<t t-esc="widget.format_currency((widget.currentOrder.getPaidTotal() - widget.currentOrder.getTotal()).toFixed(2))"/>
|
||||
<t t-esc="widget.format_currency(widget.currentOrder.getPaidTotal() - widget.currentOrder.getTotalTaxIncluded())"/>
|
||||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue