[FIX] point_of_sale: child taxes computation

The box "Tax on children" was ignored in the pos, leading to 100% taxes for these
taxes (as amount is 1.0 on these taxes).

Add child tax fields when loading the pos to be able to correctly compute
recusively the tax amount on children.

Courtesy of Jean-Nicolas Brunet
Fixes #1515, lp:1231574, opw 622143
This commit is contained in:
Martin Trigaux 2015-04-16 09:23:50 +02:00
parent a6ef1a7c72
commit 58a481329e
1 changed files with 71 additions and 33 deletions

View File

@ -188,14 +188,20 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
},
},{
model: 'account.tax',
fields: ['name','amount', 'price_include', 'include_base_amount', 'type'],
fields: ['name','amount', 'price_include', 'include_base_amount', 'type', 'child_ids', 'child_depend', 'include_base_amount'],
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];
}
_.each(taxes, function(tax){
self.taxes_by_id[tax.id] = tax;
});
_.each(self.taxes_by_id, function(tax) {
tax.child_taxes = {};
_.each(tax.child_ids, function(child_tax_id) {
tax.child_taxes[child_tax_id] = self.taxes_by_id[child_tax_id];
});
});
},
},{
model: 'pos.session',
@ -851,52 +857,84 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
get_tax_details: function(){
return this.get_all_prices().taxDetails;
},
get_all_prices: function(){
compute_all: function(taxes, price_unit) {
var self = this;
var res = [];
var currency_rounding = this.pos.currency.rounding;
var base = this.get_base_price();
var totalTax = base;
var totalNoTax = base;
var product = this.get_product();
var taxes = this.get_applicable_taxes();
var taxtotal = 0;
var taxdetail = {};
_.each(taxes, function(tax) {
var base = price_unit;
_(taxes).each(function(tax) {
if (tax.price_include) {
var tmp;
if (tax.type === "percent") {
tmp = base - round_pr(base / (1 + tax.amount),currency_rounding);
tmp = round_pr(base - round_pr(base / (1 + tax.amount),currency_rounding),currency_rounding);
data = {amount:tmp, price_include:true, id: tax.id};
res.push(data);
} else if (tax.type === "fixed") {
tmp = round_pr(tax.amount * self.get_quantity(),currency_rounding);
data = {amount:tmp, price_include:true, id: tax.id};
res.push(data);
} 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;
taxdetail[tax.id] = tmp;
} else {
var tmp;
if (tax.type === "percent") {
tmp = tax.amount * base;
tmp = round_pr(tax.amount * base, currency_rounding);
data = {amount:tmp, price_include:false, id: tax.id};
res.push(data);
} else if (tax.type === "fixed") {
tmp = tax.amount * self.get_quantity();
tmp = round_pr(tax.amount * self.get_quantity(), currency_rounding);
data = {amount:tmp, price_include:false, id: tax.id};
res.push(data);
} else {
throw "This type of tax is not supported by the point of sale: " + tax.type;
}
tmp = round_pr(tmp,currency_rounding);
if (tax.include_base_amount) {
base += tmp;
var base_amount = data.amount;
var child_amount = 0.0;
if (tax.child_depend) {
res.pop(); // do not use parent tax
child_tax = self.compute_all(tax.child_taxes, base_amount);
res.push(child_tax);
_(child_tax).each(function(child) {
child_amount += child.amount;
});
}
if (tax.include_base_amount) {
base += base_amount + child_amount;
}
taxtotal += tmp;
totalTax += tmp;
taxdetail[tax.id] = tmp;
}
});
return res;
},
get_all_prices: function(){
var base = round_pr(this.get_quantity() * this.get_unit_price() * (1.0 - (this.get_discount() / 100.0)), this.pos.currency.rounding);
var totalTax = base;
var totalNoTax = base;
var taxtotal = 0;
var product = this.get_product();
var taxes_ids = product.taxes_id;
var taxes = this.pos.taxes;
var taxdetail = {};
var product_taxes = [];
_(taxes_ids).each(function(el){
product_taxes.push(_.detect(taxes, function(t){
return t.id === el;
}));
});
var all_taxes = _(this.compute_all(product_taxes, base)).flatten();
_(all_taxes).each(function(tax) {
if (tax.price_include) {
totalNoTax -= tax.amount;
} else {
totalTax += tax.amount;
}
taxtotal += tax.amount;
taxdetail[tax.id] = tax.amount;
});
return {
"priceWithTax": totalTax,
"priceWithoutTax": totalNoTax,