Skip to content

Commit 1bf77bf

Browse files
[FIX] ecotax classification restricted by country
computing the product ecotax passing partner country in context does not work well because sometimes we cant have the country passed. For example in account.move.line._compute_totals, sometimes we do not have the context and the tax is wrongly computed because of an empty ecotax amount. Refactore to set or not the ecotax tax on the sale/invoice line depending on the country. It is more limited because it means than a same product can only have classification for a same set of country, but it is more reliable.
1 parent 6fdcc99 commit 1bf77bf

File tree

9 files changed

+75
-107
lines changed

9 files changed

+75
-107
lines changed

account_ecotax/models/product_product.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def _get_ecotax_amounts_from_classification(self, classifications):
101101
return fixed_ecotax, weight_based_ecotax, amount_ecotax
102102

103103
def _get_country_eligible_classification(self, country):
104-
self.ensure_one()
104+
self and self.ensure_one()
105105
return self.all_ecotax_line_product_ids.filtered(
106106
lambda line: not line.country_ids
107107
or (country and country in line.country_ids)

account_ecotax_sale_tax/models/sale_order_line.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ class SaleOrderLine(models.Model):
1515

1616
def _get_ecotax_amounts(self):
1717
self.ensure_one()
18-
country = (
19-
self.order_id.partner_shipping_id.country_id
20-
or self.order_id.partner_id.country_id
21-
)
22-
self = self.with_context(country=country)
2318
# do not call super as we completly change the way to compute it
2419
ecotax_ids = self.tax_id.filtered(lambda tax: tax.is_ecotax)
2520
if (self.display_type and self.display_type != "product") or not ecotax_ids:
@@ -44,8 +39,6 @@ def _get_ecotax_amounts(self):
4439
"tax_id",
4540
"product_uom_qty",
4641
"product_id",
47-
"order_id.partner_id",
48-
"order_id.partner_shipping_id",
4942
)
5043
def _compute_ecotax_tax(self):
5144
return self._compute_ecotax()
@@ -61,7 +54,12 @@ def _get_new_vals_list(self):
6154
def _compute_ecotax_line_ids(self):
6255
return super()._compute_ecotax_line_ids()
6356

64-
@api.depends("product_id", "company_id")
57+
@api.depends(
58+
"product_id",
59+
"company_id",
60+
"order_id.partner_id",
61+
"order_id.partner_shipping_id",
62+
)
6563
def _compute_tax_id(self):
6664
res = super()._compute_tax_id()
6765
for line in self:
@@ -70,10 +68,15 @@ def _compute_tax_id(self):
7068

7169
def _get_computed_ecotaxes(self):
7270
self.ensure_one()
73-
sale_ecotaxes = self.product_id.all_ecotax_line_product_ids.mapped(
74-
"classification_id"
75-
).mapped("sale_ecotax_ids")
76-
ecotax_ids = sale_ecotaxes.filtered(
71+
country = (
72+
self.order_id.partner_shipping_id.country_id
73+
or self.order_id.partner_id.country_id
74+
)
75+
eligible_classifications = self.product_id._get_country_eligible_classification(
76+
country
77+
)
78+
sale_ecotaxs = eligible_classifications.classification_id.sale_ecotax_ids
79+
ecotax_ids = sale_ecotaxs.filtered(
7780
lambda tax: tax.company_id == self.order_id.company_id
7881
)
7982

@@ -90,12 +93,3 @@ def _prepare_invoice_line(self, **optional_values):
9093
if "ecotax_line_ids" in res and not res["ecotax_line_ids"]:
9194
res.pop("ecotax_line_ids")
9295
return res
93-
94-
def _convert_to_tax_base_line_dict(self):
95-
self.ensure_one()
96-
country = (
97-
self.order_id.partner_shipping_id.country_id
98-
or self.order_id.partner_id.country_id
99-
)
100-
self = self.with_context(country=country)
101-
return super()._convert_to_tax_base_line_dict()

account_ecotax_tax/README.rst

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
.. image:: https://odoo-community.org/readme-banner-image
2-
:target: https://odoo-community.org/get-involved?utm_source=readme
3-
:alt: Odoo Community Association
4-
51
=================================
62
Ecotax Management (with Odoo tax)
73
=================================
@@ -17,7 +13,7 @@ Ecotax Management (with Odoo tax)
1713
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
1814
:target: https://odoo-community.org/page/development-status
1915
:alt: Beta
20-
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
2117
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
2218
:alt: License: AGPL-3
2319
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--fiscal--rule-lightgray.png?logo=github
@@ -89,6 +85,8 @@ Known issues / Roadmap
8985
Since an update in Odoo https://github.com/odoo/odoo/commit/13e9833e0bc809a26843890363586f61a37d061c the case with ecotax as tax included and another tax included does not work anymore.
9086
The ecotax tax should only be used along with price excluded tax, or be configured as price excluded itself.
9187

88+
There is a limitation with the country restriction on ecotax classification when using the account_ecotax_tax and account_ecotax_sale_tax modules.OIt is currently not possible to have multiple classificaiton restricted to different countries for a same product.
89+
9290
Bug Tracker
9391
===========
9492

account_ecotax_tax/models/account_move_line.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ class AcountMoveLine(models.Model):
1818

1919
def _get_ecotax_amounts(self):
2020
self.ensure_one()
21-
country = (
22-
self.move_id.partner_shipping_id.country_id
23-
or self.move_id.partner_id.country_id
24-
)
25-
self = self.with_context(country=country)
2621
ecotax_ids = self.tax_ids.filtered(lambda tax: tax.is_ecotax)
2722

2823
if self.display_type == "tax" or not ecotax_ids:
@@ -57,8 +52,6 @@ def _get_ecotax_amounts(self):
5752
"tax_ids",
5853
"quantity",
5954
"product_id",
60-
"move_id.partner_id",
61-
"move_id.partner_shipping_id",
6255
)
6356
def _compute_ecotax_tax(self):
6457
return self._compute_ecotax()
@@ -74,23 +67,40 @@ def _get_new_vals_list(self):
7467
def _compute_ecotax_line_ids(self):
7568
return super()._compute_ecotax_line_ids()
7669

70+
@api.depends(
71+
"product_id",
72+
"product_uom_id",
73+
"move_id.partner_id",
74+
"move_id.partner_shipping_id",
75+
)
76+
def _compute_tax_ids(self):
77+
return super()._compute_tax_ids()
78+
7779
def _get_computed_taxes(self):
7880
tax_ids = super()._get_computed_taxes()
7981
ecotax_ids = self.env["account.tax"]
82+
country = (
83+
self.move_id.partner_shipping_id.country_id
84+
or self.move_id.partner_id.country_id
85+
)
8086
if self.move_id.is_sale_document(include_receipts=True):
8187
# Out invoice.
82-
sale_ecotaxs = self.product_id.all_ecotax_line_product_ids.mapped(
83-
"classification_id"
84-
).mapped("sale_ecotax_ids")
88+
eligible_classifications = (
89+
self.product_id._get_country_eligible_classification(country)
90+
)
91+
sale_ecotaxs = eligible_classifications.classification_id.sale_ecotax_ids
8592
ecotax_ids = sale_ecotaxs.filtered(
8693
lambda tax: tax.company_id == self.move_id.company_id
8794
)
8895

8996
elif self.move_id.is_purchase_document(include_receipts=True):
9097
# In invoice.
91-
purchase_ecotaxs = self.product_id.all_ecotax_line_product_ids.mapped(
92-
"classification_id"
93-
).mapped("purchase_ecotax_ids")
98+
eligible_classifications = (
99+
self.product_id._get_country_eligible_classification(country)
100+
)
101+
purchase_ecotaxs = (
102+
eligible_classifications.classification_id.purchase_ecotax_ids
103+
)
94104
ecotax_ids = purchase_ecotaxs.filtered(
95105
lambda tax: tax.company_id == self.move_id.company_id
96106
)
@@ -101,12 +111,3 @@ def _get_computed_taxes(self):
101111
tax_ids |= ecotax_ids
102112

103113
return tax_ids
104-
105-
def _convert_to_tax_base_line_dict(self):
106-
self.ensure_one()
107-
country = (
108-
self.move_id.partner_shipping_id.country_id
109-
or self.move_id.partner_id.country_id
110-
)
111-
self = self.with_context(country=country)
112-
return super()._convert_to_tax_base_line_dict()

account_ecotax_tax/models/account_tax.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,10 @@ def onchange_is_ecotax(self):
2626
# price_unit
2727
# product: product.product object or None
2828
# partner: res.partner object or None
29-
30-
# Previously we needed to have 1 tax for weight ecotax configured this way
29+
# for weight based ecotax
3130
# result = quantity and product.weight_based_ecotax * quantity or 0.0
32-
# and 1 tax for fixed ecotax configured this way
31+
# for fix ecotax
3332
# result = quantity and product.fixed_ecotax * quantity or 0.0
34-
# we now are able to have one generic tax. You have to use ecotax_amount_context
35-
# to have ecotax working depending on the delivery addresses
36-
result = quantity and product.ecotax_amount_context * quantity or 0.0
33+
# to manage both weight and fix with only one ecotax tax
34+
result = quantity and product.ecotax_amount * quantity or 0.0
3735
"""
Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,22 @@
1-
# Copyright 2021 Camptocamp
2-
# @author Silvio Gregorini <[email protected]>
3-
# Copyright 2023 Akretion (http://www.akretion.com)
4-
# # @author Mourad EL HADJ MIMOUNE <[email protected]>
51
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
62

7-
from odoo import api, fields, models
3+
from odoo import _, api, exceptions, models
4+
from odoo.fields import first
85

96

107
class ProductProduct(models.Model):
118
_inherit = "product.product"
129

13-
ecotax_amount_context = fields.Float(
14-
digits="Ecotax",
15-
compute="_compute_product_ecotax_context",
16-
help="Ecotax Amount computed form all ecotax line classification, but depending"
17-
" of the context (delivery country)",
18-
)
19-
20-
@api.depends(
21-
"all_ecotax_line_product_ids",
22-
"all_ecotax_line_product_ids.classification_id",
23-
"all_ecotax_line_product_ids.classification_id.ecotax_type",
24-
"all_ecotax_line_product_ids.classification_id.ecotax_coef",
25-
"all_ecotax_line_product_ids.force_amount",
26-
"weight",
27-
)
28-
@api.depends_context("country")
29-
def _compute_product_ecotax_context(self):
10+
@api.constrains("additional_ecotax_line_product_ids", "ecotax_line_product_ids")
11+
def check_ecotax_line_country(self):
3012
for product in self:
31-
country = self.env.context.get("country", False)
32-
eligible_classifications = product._get_country_eligible_classification(
33-
country
34-
)
35-
(
36-
_fixed_ecotax,
37-
_weight_based_ecotax,
38-
amount_ecotax,
39-
) = product._get_ecotax_amounts_from_classification(
40-
eligible_classifications
41-
)
42-
product.ecotax_amount_context = amount_ecotax
13+
countries = first(product.all_ecotax_line_product_ids).country_ids
14+
for ecotax_line in product.all_ecotax_line_product_ids:
15+
if ecotax_line.country_ids != countries:
16+
raise exceptions.UserError(
17+
_(
18+
"All ecotax classification for a product should have the same "
19+
"countries allowed. This is a restriction of the "
20+
"account_ecotax_tax module."
21+
)
22+
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
Since an update in Odoo https://github.com/odoo/odoo/commit/13e9833e0bc809a26843890363586f61a37d061c the case with ecotax as tax included and another tax included does not work anymore.
22
The ecotax tax should only be used along with price excluded tax, or be configured as price excluded itself.
3+
4+
There is a limitation with the country restriction on ecotax classification when using the account_ecotax_tax and account_ecotax_sale_tax modules.OIt is currently not possible to have multiple classificaiton restricted to different countries for a same product.

account_ecotax_tax/static/description/index.html

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
55
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
6-
<title>README.rst</title>
6+
<title>Ecotax Management (with Odoo tax)</title>
77
<style type="text/css">
88

99
/*
@@ -360,21 +360,16 @@
360360
</style>
361361
</head>
362362
<body>
363-
<div class="document">
363+
<div class="document" id="ecotax-management-with-odoo-tax">
364+
<h1 class="title">Ecotax Management (with Odoo tax)</h1>
364365

365-
366-
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
367-
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
368-
</a>
369-
<div class="section" id="ecotax-management-with-odoo-tax">
370-
<h1>Ecotax Management (with Odoo tax)</h1>
371366
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
372367
!! This file is generated by oca-gen-addon-readme !!
373368
!! changes will be overwritten. !!
374369
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375370
!! source digest: sha256:325b4d53ac93f3760030128a6c45ca9e12cef59c1998fc54a3044f230150da9a
376371
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377-
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-fiscal-rule/tree/16.0/account_ecotax_tax"><img alt="OCA/account-fiscal-rule" src="https://img.shields.io/badge/github-OCA%2Faccount--fiscal--rule-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-fiscal-rule-16-0/account-fiscal-rule-16-0-account_ecotax_tax"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-fiscal-rule&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
372+
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-fiscal-rule/tree/16.0/account_ecotax_tax"><img alt="OCA/account-fiscal-rule" src="https://img.shields.io/badge/github-OCA%2Faccount--fiscal--rule-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-fiscal-rule-16-0/account-fiscal-rule-16-0-account_ecotax_tax"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-fiscal-rule&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378373
<p>This module allows to compute the ecotax amounts from Odoo tax mechanism.
379374
The advantages compared to the base account_ecotax module is that it allows to :
380375
- Manage ecotax amount as included or excluded from the price of the product
@@ -395,7 +390,7 @@ <h1>Ecotax Management (with Odoo tax)</h1>
395390
</ul>
396391
</div>
397392
<div class="section" id="usage">
398-
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
393+
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
399394
<ol class="arabic">
400395
<li><p class="first">Create a tax group named <strong>“Ecotaxes”</strong>. The sequence must be lower than other tax groups.
401396
- Set the <strong>Preceding Subtotal</strong> field to <strong>“Without Ecotax”</strong>.</p>
@@ -441,35 +436,36 @@ <h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
441436
</ol>
442437
</div>
443438
<div class="section" id="known-issues-roadmap">
444-
<h2><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h2>
439+
<h1><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h1>
445440
<p>Since an update in Odoo <a class="reference external" href="https://github.com/odoo/odoo/commit/13e9833e0bc809a26843890363586f61a37d061c">https://github.com/odoo/odoo/commit/13e9833e0bc809a26843890363586f61a37d061c</a> the case with ecotax as tax included and another tax included does not work anymore.
446441
The ecotax tax should only be used along with price excluded tax, or be configured as price excluded itself.</p>
442+
<p>There is a limitation with the country restriction on ecotax classification when using the account_ecotax_tax and account_ecotax_sale_tax modules.OIt is currently not possible to have multiple classificaiton restricted to different countries for a same product.</p>
447443
</div>
448444
<div class="section" id="bug-tracker">
449-
<h2><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h2>
445+
<h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1>
450446
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-fiscal-rule/issues">GitHub Issues</a>.
451447
In case of trouble, please check there if your issue has already been reported.
452448
If you spotted it first, help us to smash it by providing a detailed and welcomed
453449
<a class="reference external" href="https://github.com/OCA/account-fiscal-rule/issues/new?body=module:%20account_ecotax_tax%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
454450
<p>Do not contact contributors directly about support or help with technical issues.</p>
455451
</div>
456452
<div class="section" id="credits">
457-
<h2><a class="toc-backref" href="#toc-entry-4">Credits</a></h2>
453+
<h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1>
458454
<div class="section" id="authors">
459-
<h3><a class="toc-backref" href="#toc-entry-5">Authors</a></h3>
455+
<h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2>
460456
<ul class="simple">
461457
<li>Akretion</li>
462458
</ul>
463459
</div>
464460
<div class="section" id="contributors">
465-
<h3><a class="toc-backref" href="#toc-entry-6">Contributors</a></h3>
461+
<h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
466462
<ul class="simple">
467463
<li>Mourad EL HADJ MIMOUNE &lt;<a class="reference external" href="mailto:mourad.elhadj.mimoune&#64;akretion.com">mourad.elhadj.mimoune&#64;akretion.com</a>&gt;</li>
468464
<li>Florian da Costa &lt;<a class="reference external" href="mailto:florian.dacosta&#64;akretion.com">florian.dacosta&#64;akretion.com</a>&gt;</li>
469465
</ul>
470466
</div>
471467
<div class="section" id="maintainers">
472-
<h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
468+
<h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
473469
<p>This module is maintained by the OCA.</p>
474470
<a class="reference external image-reference" href="https://odoo-community.org">
475471
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
@@ -484,6 +480,5 @@ <h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
484480
</div>
485481
</div>
486482
</div>
487-
</div>
488483
</body>
489484
</html>

account_ecotax_tax/tests/test_ecotax.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def setUpClass(cls):
3535
"sequence": 0,
3636
"is_ecotax": True,
3737
"python_compute": "result = (quantity and"
38-
" product.ecotax_amount_context * quantity or 0.0)",
38+
" product.ecotax_amount * quantity or 0.0)",
3939
"tax_exigibility": "on_invoice",
4040
"invoice_repartition_line_ids": [
4141
(

0 commit comments

Comments
 (0)