From 58a481329eb1ec4074a08e12b89fdbd2aaa35343 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 16 Apr 2015 09:23:50 +0200 Subject: [PATCH] [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 --- addons/point_of_sale/static/src/js/models.js | 104 +++++++++++++------ 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index dc2557fa62d..13422c7f9e8 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -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,