diff --git a/addons/account/models/account_tax.py b/addons/account/models/account_tax.py
index c85143e863b..a2982d8f7fc 100644
--- a/addons/account/models/account_tax.py
+++ b/addons/account/models/account_tax.py
@@ -73,7 +73,11 @@ class AccountTax(models.Model):
price_include = fields.Boolean(string='Included in Price', default=False,
help="Check this if the price you use on the product and invoices includes this tax.")
include_base_amount = fields.Boolean(string='Affect Base of Subsequent Taxes', default=False,
- help="If set, taxes which are computed after this one will be computed based on the price tax included.")
+ help="If set, taxes with a higher sequence than this one will be affected by it, provided they accept it.")
+ is_base_affected = fields.Boolean(
+ string="Base Affected by Previous Taxes",
+ default=True,
+ help="If set, taxes with a lower sequence might affect this one, provided they try to do it.")
analytic = fields.Boolean(string="Include in Analytic Cost", help="If set, the amount computed by this tax will be assigned to the same analytic account as the invoice line (if any)")
tax_group_id = fields.Many2one('account.tax.group', string="Tax Group", default=_default_tax_group, required=True)
# Technical field to make the 'tax_exigibility' field invisible if the same named field is set to false in 'res.company' model
@@ -373,6 +377,7 @@ class AccountTax(models.Model):
# 3) Deal with the rounding methods
if not currency:
currency = company.currency_id
+
# By default, for each tax, tax amount will first be computed
# and rounded at the 'Account' decimal precision for each
# PO/SO/invoice line and then these rounded amounts will be
@@ -510,11 +515,16 @@ class AccountTax(models.Model):
i = 0
cumulated_tax_included_amount = 0
for tax in taxes:
+ price_include = self._context.get('force_price_include', tax.price_include)
+
+ if price_include or tax.is_base_affected:
+ tax_base_amount = base
+ else:
+ tax_base_amount = total_excluded
+
tax_repartition_lines = (is_refund and tax.refund_repartition_line_ids or tax.invoice_repartition_line_ids).filtered(lambda x: x.repartition_type == 'tax')
sum_repartition_factor = sum(tax_repartition_lines.mapped('factor'))
- price_include = self._context.get('force_price_include', tax.price_include)
-
#compute the tax_amount
if price_include and total_included_checkpoints.get(i):
# We know the total to reach for that tax, so we make a substraction to avoid any rounding issues
@@ -522,7 +532,7 @@ class AccountTax(models.Model):
cumulated_tax_included_amount = 0
else:
tax_amount = tax.with_context(force_price_include=False)._compute_amount(
- base, sign * price_unit, quantity, product, partner)
+ tax_base_amount, sign * price_unit, quantity, product, partner)
# Round the tax_amount multiplied by the computed repartition lines factor.
tax_amount = round(tax_amount, precision_rounding=prec)
@@ -563,7 +573,7 @@ class AccountTax(models.Model):
'id': tax.id,
'name': partner and tax.with_context(lang=partner.lang).name or tax.name,
'amount': sign * line_amount,
- 'base': round(sign * base, precision_rounding=prec),
+ 'base': round(sign * tax_base_amount, precision_rounding=prec),
'sequence': tax.sequence,
'account_id': tax.cash_basis_transition_account_id.id if tax.tax_exigibility == 'on_payment' else repartition_line.account_id.id,
'analytic': tax.analytic,
diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py
index 4364223f4ed..c2072ca7f33 100644
--- a/addons/account/models/chart_template.py
+++ b/addons/account/models/chart_template.py
@@ -914,7 +914,11 @@ class AccountTaxTemplate(models.Model):
price_include = fields.Boolean(string='Included in Price', default=False,
help="Check this if the price you use on the product and invoices includes this tax.")
include_base_amount = fields.Boolean(string='Affect Subsequent Taxes', default=False,
- help="If set, taxes which are computed after this one will be computed based on the price tax included.")
+ help="If set, taxes with a higher sequence than this one will be affected by it, provided they accept it.")
+ is_base_affected = fields.Boolean(
+ string="Base Affected by Previous Taxes",
+ default=True,
+ help="If set, taxes with a lower sequence might affect this one, provided they try to do it.")
analytic = fields.Boolean(string="Analytic Cost", help="If set, the amount computed by this tax will be assigned to the same analytic account as the invoice line (if any)")
invoice_repartition_line_ids = fields.One2many(string="Repartition for Invoices", comodel_name="account.tax.repartition.line.template", inverse_name="invoice_tax_id", copy=True, help="Repartition when the tax is used on an invoice")
refund_repartition_line_ids = fields.One2many(string="Repartition for Refund Invoices", comodel_name="account.tax.repartition.line.template", inverse_name="refund_tax_id", copy=True, help="Repartition when the tax is used on a refund")
@@ -964,6 +968,7 @@ class AccountTaxTemplate(models.Model):
'description': self.description,
'price_include': self.price_include,
'include_base_amount': self.include_base_amount,
+ 'is_base_affected': self.is_base_affected,
'analytic': self.analytic,
'children_tax_ids': [(6, 0, children_ids)],
'tax_exigibility': self.tax_exigibility,
diff --git a/addons/account/tests/test_tax.py b/addons/account/tests/test_tax.py
index 532ca7eb0c3..0e937444c95 100644
--- a/addons/account/tests/test_tax.py
+++ b/addons/account/tests/test_tax.py
@@ -1045,3 +1045,31 @@ class TestTax(TestTaxCommon):
],
res3
)
+
+ def test_is_base_affected(self):
+ taxes = self.env['account.tax'].create([{
+ 'name': 'test_is_base_affected%s' % i,
+ 'amount_type': 'percent',
+ 'amount': amount,
+ 'include_base_amount': include_base_amount,
+ 'is_base_affected': is_base_affected,
+ 'sequence': i,
+ } for i, amount, include_base_amount, is_base_affected in [
+ (0, 6, True, True),
+ (1, 6, True, False),
+ (2, 10, False, True),
+ ]])
+
+ self._check_compute_all_results(
+ 123.2, # 'total_included'
+ 100.0, # 'total_excluded'
+ [
+ # base, amount
+ # -------------------------
+ (100.0, 6.0),
+ (100.0, 6.0),
+ (112.0, 11.2),
+ # -------------------------
+ ],
+ taxes.compute_all(100.0),
+ )
diff --git a/addons/account/views/account_chart_template_views.xml b/addons/account/views/account_chart_template_views.xml
index f42f53ecdc7..6aa16900233 100644
--- a/addons/account/views/account_chart_template_views.xml
+++ b/addons/account/views/account_chart_template_views.xml
@@ -172,6 +172,8 @@
+
diff --git a/addons/account/views/account_tax_views.xml b/addons/account/views/account_tax_views.xml
index 26862d825bd..d70f6932459 100644
--- a/addons/account/views/account_tax_views.xml
+++ b/addons/account/views/account_tax_views.xml
@@ -164,6 +164,8 @@
+
diff --git a/addons/l10n_in/views/account_tax_views.xml b/addons/l10n_in/views/account_tax_views.xml
index a108bda381e..116fc2ee976 100644
--- a/addons/l10n_in/views/account_tax_views.xml
+++ b/addons/l10n_in/views/account_tax_views.xml
@@ -5,7 +5,7 @@
account.tax
-
+
diff --git a/addons/point_of_sale/models/account_tax.py b/addons/point_of_sale/models/account_tax.py
index a8ad419a0e5..6e8dfae8b5e 100644
--- a/addons/point_of_sale/models/account_tax.py
+++ b/addons/point_of_sale/models/account_tax.py
@@ -10,7 +10,7 @@ class AccountTax(models.Model):
def write(self, vals):
forbidden_fields = set([
'amount_type', 'amount', 'type_tax_use', 'tax_group_id', 'price_include',
- 'include_base_amount'
+ 'include_base_amount', 'is_base_affected',
])
if forbidden_fields & set(vals.keys()):
tax_ids = self.env['pos.order.line'].sudo().search([
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index fd37a782d87..52ae9e50981 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -245,7 +245,7 @@ exports.PosModel = Backbone.Model.extend({
},
},{
model: 'account.tax',
- fields: ['name','amount', 'price_include', 'include_base_amount', 'amount_type', 'children_tax_ids'],
+ fields: ['name','amount', 'price_include', 'include_base_amount', 'is_base_affected', 'amount_type', 'children_tax_ids'],
domain: function(self) {return [['company_id', '=', self.company && self.company.id || false]]},
loaded: function(self, taxes){
self.taxes = taxes;
@@ -2218,11 +2218,16 @@ exports.Orderline = Backbone.Model.extend({
i = 0;
var cumulated_tax_included_amount = 0;
_(taxes.reverse()).each(function(tax){
+ if(tax.price_include || tax.is_base_affected)
+ var tax_base_amount = base;
+ else
+ var tax_base_amount = total_excluded;
+
if(tax.price_include && total_included_checkpoints[i] !== undefined){
var tax_amount = total_included_checkpoints[i] - (base + cumulated_tax_included_amount);
cumulated_tax_included_amount = 0;
}else
- var tax_amount = self._compute_all(tax, base, quantity, true);
+ var tax_amount = self._compute_all(tax, tax_base_amount, quantity, true);
tax_amount = round_pr(tax_amount, currency_rounding);
@@ -2233,7 +2238,7 @@ exports.Orderline = Backbone.Model.extend({
'id': tax.id,
'name': tax.name,
'amount': sign * tax_amount,
- 'base': sign * round_pr(base, currency_rounding),
+ 'base': sign * round_pr(tax_base_amount, currency_rounding),
});
if(tax.include_base_amount)