Skip to content

Commit

Permalink
[16][REF] split account_ecotax into account_ecotax and account_ecotax…
Browse files Browse the repository at this point in the history
…_tax

The goal is to be able to choose between the implementation with and without using the odoo tax mechanism.
The advantages of the implementation based on Odoo tax mechanims are :
- Possibility to choose if product price include or exclude the ecotax amounts
- Isolate the ecotax amounts into a specifc accounting account
The disadvantage is that it adds a small layer of complexity and you have to manage the tax configuration and see all those ecotax taxes on your invoices
And a major difference which can be good or not depending on your use cases, the ecotax amounts are not in the turnover when using Odoo tax mechanism
  • Loading branch information
florian-dacosta committed Dec 5, 2024
1 parent ff0cdc3 commit e2bb4b7
Show file tree
Hide file tree
Showing 31 changed files with 1,079 additions and 351 deletions.
63 changes: 24 additions & 39 deletions account_ecotax/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,24 @@ Ecotax Management

|badge1| |badge2| |badge3| |badge4| |badge5|

This module applies to companies based in France mainland. It doesn't apply to
companies based in the DOM-TOMs (Guadeloupe, Martinique, Guyane, Réunion,
Mayotte).
This module adds ecotax amount on invoice line.
furthermore, a total ecotax is added at the footer of each document.

It add Ecotaxe amount on invoice line.
furthermore, a total ecotaxe are added at the footer of each document.
To make easy ecotaxe management and to factor the data, ecotaxes are set on products via ECOTAXE classifications.
ECOTAXE classification can either be a fixed or weight based ecotax.

To make easy ecotaxe management and to factor the data, ecotaxe are set on products via ECOTAXE classifications.
ECOTAXE classification can either a fixed or weight based ecotaxe.
A product can have one or serveral ecotax classifications. For example, wooden window blinds equipped with electric motor can
have ecotax for wood and ecotax for electric motor.

A product can have one or serveral ecotaxe classifications. For exemple wooden window blinds equipped with electric motor can
have ecotaxe for wood and ecotaxe for electric motor.
This module has some limits :
- The ecotax amount is always included in the price of the product.
- The ecotax amount is not isolated in an specific accounting account but is included in the product income account.

This module version add the possibility to manage several ecotaxe classification by product.
If one of these limits is an issue, you could install the submodule account_ecotax_tax.
This second module lets you manage the ecotax as a tax, so you can configure if you want it to be included or excluded of product price and also configuring an accounting account to isolate it.
The main consequence of this approach is that the ecotax won't be considered in the turnover, since it is considered as a tax.

This module version add the possibility to manage several ecotax classifications by product.
A migration script is necessary to update from previous versions.

There is the main change to manage in migration script:
Expand All @@ -68,42 +72,19 @@ product.template ecotaxe_line_product_ids
Usage
=====

1. Create a tax group named **"Ecotaxes"**. The sequence must be lower than other tax groups.
- Set the **Preceding Subtotal** field to **"Without Ecotax"**.

2. Create two taxes named **"Fixed Ecotax"** and **"Weight-Based Ecotax"**.
- Check the **Ecotax** checkbox.
- Set the correct Python code:

- For the fixed ecotax:

.. code-block:: python
result = quantity and product.fixed_ecotax * quantity or 0.0
- For the weight-based ecotax:

.. code-block:: python
result = quantity and product.weight_based_ecotax * quantity or 0.0
- Check the **Included in Base Amount** option.
- The sequence for Ecotax must be lower than the VAT tax.

3. For VAT taxes, check the **Base Affected by Previous Taxes?** option.

4. Add an ecotax classification via the menu **Accounting > Configuration > Taxes > Ecotax Classification**.
1. Add an ecotax classification via the menu **Accounting > Configuration > Taxes > Ecotax Classification**.

- The ecotax classification can be either a fixed ecotax or a weight-based ecotax.
- Ecotax classification information can be used for legal declarations.
- For the fixed ecotax, the ecotax amount is used as a default value, which can be overridden on the product.
- For the weight-based ecotax, define one ecotax by a coefficient applied to the weight (depending on the product's materials).
- Set the appropriate tax in the **Sale Ecotax** field.

5. Assign one or more ecotax classifications to a product.
2. Assign one or more ecotax classifications to a product.

- The ecotax amount can also be manually overridden on the product.

3. Create an invoice with this product

Bug Tracker
===========

Expand All @@ -126,6 +107,7 @@ Contributors
~~~~~~~~~~~~

* Mourad EL HADJ MIMOUNE <[email protected]>
* Florian da Costa <[email protected]>

Maintainers
~~~~~~~~~~~
Expand All @@ -143,10 +125,13 @@ promote its widespread use.
.. |maintainer-mourad-ehm| image:: https://github.com/mourad-ehm.png?size=40px
:target: https://github.com/mourad-ehm
:alt: mourad-ehm
.. |maintainer-florian-dacosta| image:: https://github.com/florian-dacosta.png?size=40px
:target: https://github.com/florian-dacosta
:alt: florian-dacosta

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-mourad-ehm|
|maintainer-mourad-ehm| |maintainer-florian-dacosta|

This module is part of the `OCA/account-fiscal-rule <https://github.com/OCA/account-fiscal-rule/tree/16.0/account_ecotax>`_ project on GitHub.

Expand Down
4 changes: 1 addition & 3 deletions account_ecotax/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
"website": "https://github.com/OCA/account-fiscal-rule",
"category": "Localization/Account Taxes",
"license": "AGPL-3",
"maintainers": ["mourad-ehm"],
"maintainers": ["mourad-ehm", "florian-dacosta"],
"depends": [
"account",
"account_tax_python",
],
"data": [
"data/decimal_precision.xml",
Expand All @@ -26,7 +25,6 @@
"views/account_move_view.xml",
"views/product_template_view.xml",
"views/product_view.xml",
"views/account_tax_view.xml",
],
"installable": True,
}
1 change: 0 additions & 1 deletion account_ecotax/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@
from . import product_product
from . import ecotax_sector
from . import ecotax_collector
from . import account_tax
16 changes: 0 additions & 16 deletions account_ecotax/models/account_ecotax_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,6 @@ class AccountEcotaxClassification(models.Model):
)
intrastat_code = fields.Char()
scale_code = fields.Char()
sale_ecotax_ids = fields.Many2many(
"account.tax",
"ecotax_classif_taxes_rel",
"ecotax_classif_id",
"tax_id",
string="Sale EcoTax",
domain=[("is_ecotax", "=", True), ("type_tax_use", "=", "sale")],
)
purchase_ecotax_ids = fields.Many2many(
"account.tax",
"ecotax_classif_purchase_taxes_rel",
"ecotax_classif_id",
"tax_id",
string="Purchase EcoTax",
domain=[("is_ecotax", "=", True), ("type_tax_use", "=", "purchase")],
)

@api.depends("ecotax_type")
def _compute_ecotax_vals(self):
Expand Down
71 changes: 11 additions & 60 deletions account_ecotax/models/account_move_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,22 @@ class AcountMoveLine(models.Model):
compute="_compute_ecotax",
)

def _get_ecotax_amounts(self):
self.ensure_one()
amount_unit = sum(self.ecotax_line_ids.mapped("amount_unit"))
subtotal_ecotax = sum(self.ecotax_line_ids.mapped("amount_total"))
return amount_unit, subtotal_ecotax

@api.depends(
"currency_id",
"tax_ids",
"quantity",
"product_id",
"ecotax_line_ids.amount_unit",
"ecotax_line_ids.amount_total",
)
def _compute_ecotax(self):
for line in self:
ecotax_ids = line.tax_ids.filtered(lambda tax: tax.is_ecotax)

if line.display_type == "tax" or not ecotax_ids:
continue
if line.display_type == "product" and line.move_id.is_invoice(True):
amount_currency = line.price_unit * (1 - line.discount / 100)
handle_price_include = True
quantity = line.quantity
else:
amount_currency = line.amount_currency
handle_price_include = False
quantity = 1
compute_all_currency = ecotax_ids.compute_all(
amount_currency,
currency=line.currency_id,
quantity=quantity,
product=line.product_id,
partner=line.move_id.partner_id or line.partner_id,
is_refund=line.is_refund,
handle_price_include=handle_price_include,
include_caba_tags=line.move_id.always_tax_exigible,
)
subtotal_ecotax = 0.0
for tax in compute_all_currency["taxes"]:
subtotal_ecotax += tax["amount"]

unit = subtotal_ecotax / quantity if quantity else subtotal_ecotax
line.ecotax_amount_unit = unit
line.subtotal_ecotax = subtotal_ecotax
amount_unit, amount_total = line._get_ecotax_amounts()
line.ecotax_amount_unit = amount_unit
line.subtotal_ecotax = amount_total

@api.onchange("product_id")
def _onchange_product_ecotax_line(self):
Expand Down Expand Up @@ -89,31 +68,3 @@ def edit_ecotax_lines(self):
"res_id": self.id,
}
return view

def _get_computed_taxes(self):
tax_ids = super()._get_computed_taxes()
ecotax_ids = self.env["account.tax"]
if self.move_id.is_sale_document(include_receipts=True):
# Out invoice.
sale_ecotaxs = self.product_id.all_ecotax_line_product_ids.mapped(
"classification_id"
).mapped("sale_ecotax_ids")
ecotax_ids = sale_ecotaxs.filtered(
lambda tax: tax.company_id == self.move_id.company_id
)

elif self.move_id.is_purchase_document(include_receipts=True):
# In invoice.
purchase_ecotaxs = self.product_id.all_ecotax_line_product_ids.mapped(
"classification_id"
).mapped("purchase_ecotax_ids")
ecotax_ids = purchase_ecotaxs.filtered(
lambda tax: tax.company_id == self.move_id.company_id
)

if ecotax_ids and self.move_id.fiscal_position_id:
ecotax_ids = self.move_id.fiscal_position_id.map_tax(ecotax_ids)
if ecotax_ids:
tax_ids |= ecotax_ids

return tax_ids
10 changes: 6 additions & 4 deletions account_ecotax/models/ecotax_line_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ def _compute_ecotax(self):

if ecotaxline.force_amount_unit:
# force ecotax amount
amt = ecotaxline.force_amount_unit
amount = ecotaxline.force_amount_unit
elif ecotax_classif.ecotax_type == "weight_based":
amt = ecotax_classif.ecotax_coef * (ecotaxline.product_id.weight or 0.0)
amount = ecotax_classif.ecotax_coef * (
ecotaxline.product_id.weight or 0.0
)
else:
amt = ecotax_classif.default_fixed_ecotax
amount = ecotax_classif.default_fixed_ecotax

ecotaxline.amount_unit = amt
ecotaxline.amount_unit = amount
ecotaxline.amount_total = ecotaxline.amount_unit * ecotaxline.quantity
8 changes: 4 additions & 4 deletions account_ecotax/models/ecotax_line_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,17 @@ def _compute_ecotax(self):
ecotax_cls = ecotaxline.classification_id

if ecotax_cls.ecotax_type == "weight_based":
amt = ecotax_cls.ecotax_coef * (
amount = ecotax_cls.ecotax_coef * (
ecotaxline.product_tmpl_id.weight
or ecotaxline.product_id.weight
or 0.0
)
else:
amt = ecotax_cls.default_fixed_ecotax
amount = ecotax_cls.default_fixed_ecotax
# force ecotax amount
if ecotaxline.force_amount:
amt = ecotaxline.force_amount
ecotaxline.amount = amt
amount = ecotaxline.force_amount
ecotaxline.amount = amount

_sql_constraints = [
(
Expand Down
1 change: 1 addition & 0 deletions account_ecotax/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
* Mourad EL HADJ MIMOUNE <[email protected]>
* Florian da Costa <[email protected]>
24 changes: 14 additions & 10 deletions account_ecotax/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
This module applies to companies based in France mainland. It doesn't apply to
companies based in the DOM-TOMs (Guadeloupe, Martinique, Guyane, Réunion,
Mayotte).
This module adds ecotax amount on invoice line.
furthermore, a total ecotax is added at the footer of each document.

It add Ecotaxe amount on invoice line.
furthermore, a total ecotaxe are added at the footer of each document.
To make easy ecotaxe management and to factor the data, ecotaxes are set on products via ECOTAXE classifications.
ECOTAXE classification can either be a fixed or weight based ecotax.

To make easy ecotaxe management and to factor the data, ecotaxe are set on products via ECOTAXE classifications.
ECOTAXE classification can either a fixed or weight based ecotaxe.
A product can have one or serveral ecotax classifications. For example, wooden window blinds equipped with electric motor can
have ecotax for wood and ecotax for electric motor.

A product can have one or serveral ecotaxe classifications. For exemple wooden window blinds equipped with electric motor can
have ecotaxe for wood and ecotaxe for electric motor.
This module has some limits :
- The ecotax amount is always included in the price of the product.
- The ecotax amount is not isolated in an specific accounting account but is included in the product income account.

This module version add the possibility to manage several ecotaxe classification by product.
If one of these limits is an issue, you could install the submodule account_ecotax_tax.
This second module lets you manage the ecotax as a tax, so you can configure if you want it to be included or excluded of product price and also configuring an accounting account to isolate it.
The main consequence of this approach is that the ecotax won't be considered in the turnover, since it is considered as a tax.

This module version add the possibility to manage several ecotax classifications by product.
A migration script is necessary to update from previous versions.

There is the main change to manage in migration script:
Expand Down
31 changes: 4 additions & 27 deletions account_ecotax/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
1. Create a tax group named **"Ecotaxes"**. The sequence must be lower than other tax groups.
- Set the **Preceding Subtotal** field to **"Without Ecotax"**.

2. Create two taxes named **"Fixed Ecotax"** and **"Weight-Based Ecotax"**.
- Check the **Ecotax** checkbox.
- Set the correct Python code:

- For the fixed ecotax:

.. code-block:: python
result = quantity and product.fixed_ecotax * quantity or 0.0
- For the weight-based ecotax:

.. code-block:: python
result = quantity and product.weight_based_ecotax * quantity or 0.0
- Check the **Included in Base Amount** option.
- The sequence for Ecotax must be lower than the VAT tax.

3. For VAT taxes, check the **Base Affected by Previous Taxes?** option.

4. Add an ecotax classification via the menu **Accounting > Configuration > Taxes > Ecotax Classification**.
1. Add an ecotax classification via the menu **Accounting > Configuration > Taxes > Ecotax Classification**.

- The ecotax classification can be either a fixed ecotax or a weight-based ecotax.
- Ecotax classification information can be used for legal declarations.
- For the fixed ecotax, the ecotax amount is used as a default value, which can be overridden on the product.
- For the weight-based ecotax, define one ecotax by a coefficient applied to the weight (depending on the product's materials).
- Set the appropriate tax in the **Sale Ecotax** field.

5. Assign one or more ecotax classifications to a product.
2. Assign one or more ecotax classifications to a product.

- The ecotax amount can also be manually overridden on the product.

3. Create an invoice with this product
Loading

0 comments on commit e2bb4b7

Please sign in to comment.