Skip to content

Commit

Permalink
Merge PR #420 into 16.0
Browse files Browse the repository at this point in the history
Signed-off-by pedrobaeza
  • Loading branch information
OCA-git-bot committed Jul 8, 2024
2 parents c530cd2 + a1ce2dc commit 564dabf
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 83 deletions.
6 changes: 1 addition & 5 deletions l10n_eu_oss_oca/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ L10n EU OSS OCA
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:9f24da0b57196401086a0a54b7bb7e24024c260cc4c90d42308810512634a55c
!! source digest: sha256:b934fc4e54b9d6a5abf0c03b02e43a201fc94b132e10906c29b0f2f30037223b
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
Expand Down Expand Up @@ -72,10 +72,6 @@ Known issues / Roadmap
#. This module doesn't take into account if one or more products
have different type of taxes in the destination contry.

#. There are some countries (for example Spain) that have different taxes
depending on the region (Canary islands).
These use cases haven't been considered.

#. There are some countries (for example Cyprus) that have
uncommon reduced taxes, depending on the typology of the sold product.
In Cyprus, it happens with *Supply of goods and services
Expand Down
58 changes: 30 additions & 28 deletions l10n_eu_oss_oca/data/oss.tax.rate.csv
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
id,oss_country_id:id,general_rate,reduced_rate,superreduced_rate,second_superreduced_rate
oss_eu_rate_at,base.at,20,13,10,0
oss_eu_rate_be,base.be,21,12,6,0
oss_eu_rate_bg,base.bg,20,9,0,0
oss_eu_rate_hr,base.hr,25,13,5,0
oss_eu_rate_cy,base.cy,19,9,5,0
oss_eu_rate_cz,base.cz,21,15,10,0
oss_eu_rate_dk,base.dk,25,0,0,0
oss_eu_rate_ee,base.ee,20,9,0,0
oss_eu_rate_fi,base.fi,24,14,10,0
oss_eu_rate_fr,base.fr,20,10,5.5,2.1
oss_eu_rate_de,base.de,19,7,0,0
oss_eu_rate_gr,base.gr,24,13,6,0
oss_eu_rate_hu,base.hu,27,18,5,0
oss_eu_rate_ie,base.ie,23,13.5,9,4.8
oss_eu_rate_it,base.it,22,10,5,4
oss_eu_rate_lv,base.lv,21,12,5,0
oss_eu_rate_lt,base.lt,21,9,5,0
oss_eu_rate_lu,base.lu,17,14,8,3
oss_eu_rate_mt,base.mt,18,7,5,0
oss_eu_rate_nl,base.nl,21,9,0,0
oss_eu_rate_pl,base.pl,23,8,5,0
oss_eu_rate_pt,base.pt,23,13,6,0
oss_eu_rate_ro,base.ro,19,9,5,0
oss_eu_rate_sk,base.sk,20,10,0,0
oss_eu_rate_si,base.si,22,9.5,5,0
oss_eu_rate_es,base.es,21,10,4,0
oss_eu_rate_se,base.se,25,12,6,0
id,oss_country_id:id,oss_state_ids:id,general_rate,reduced_rate,superreduced_rate,second_superreduced_rate
oss_eu_rate_at,base.at,,20,13,10,0
oss_eu_rate_be,base.be,,21,12,6,0
oss_eu_rate_bg,base.bg,,20,9,0,0
oss_eu_rate_hr,base.hr,,25,13,5,0
oss_eu_rate_cy,base.cy,,19,9,5,0
oss_eu_rate_cz,base.cz,,21,15,10,0
oss_eu_rate_dk,base.dk,,25,0,0,0
oss_eu_rate_ee,base.ee,,20,9,0,0
oss_eu_rate_fi,base.fi,,24,14,10,0
oss_eu_rate_fr,base.fr,,20,10,5.5,2.1
oss_eu_rate_de,base.de,,19,7,0,0
oss_eu_rate_gr,base.gr,,24,13,6,0
oss_eu_rate_hu,base.hu,,27,18,5,0
oss_eu_rate_ie,base.ie,,23,13.5,9,4.8
oss_eu_rate_it,base.it,,22,10,5,4
oss_eu_rate_lv,base.lv,,21,12,5,0
oss_eu_rate_lt,base.lt,,21,9,5,0
oss_eu_rate_lu,base.lu,,17,14,8,3
oss_eu_rate_mt,base.mt,,18,7,5,0
oss_eu_rate_nl,base.nl,,21,9,0,0
oss_eu_rate_pl,base.pl,,23,8,5,0
oss_eu_rate_pt,base.pt,,23,13,6,0
oss_eu_rate_pt_az,base.pt,base.state_pt_pt-20,16,9,4,0
oss_eu_rate_pt_ma,base.pt,base.state_pt_pt-30,22,12,5,0
oss_eu_rate_ro,base.ro,,19,9,5,0
oss_eu_rate_sk,base.sk,,20,10,0,0
oss_eu_rate_si,base.si,,22,9.5,5,0
oss_eu_rate_es,base.es,,21,10,4,0
oss_eu_rate_se,base.se,,25,12,6,0
6 changes: 5 additions & 1 deletion l10n_eu_oss_oca/models/oss_tax_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class OssTaxRate(models.Model):
comodel_name="res.country",
string="Country",
)
oss_state_ids = fields.Many2many(
comodel_name="res.country.state",
string="States",
)
general_rate = fields.Float(digits=(16, 4))
reduced_rate = fields.Float(digits=(16, 4))
superreduced_rate = fields.Float(string="Super Reduced Rate", digits=(16, 4))
Expand All @@ -30,7 +34,7 @@ def get_rates_list(self):
_sql_constraints = [
(
"oss_country_id_uniq",
"unique(oss_country_id)",
"unique(oss_country_id, general_rate)",
"The Country must be unique !",
),
]
4 changes: 0 additions & 4 deletions l10n_eu_oss_oca/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#. This module doesn't take into account if one or more products
have different type of taxes in the destination contry.

#. There are some countries (for example Spain) that have different taxes
depending on the region (Canary islands).
These use cases haven't been considered.

#. There are some countries (for example Cyprus) that have
uncommon reduced taxes, depending on the typology of the sold product.
In Cyprus, it happens with *Supply of goods and services
Expand Down
6 changes: 2 additions & 4 deletions l10n_eu_oss_oca/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
Expand Down Expand Up @@ -366,7 +367,7 @@ <h1 class="title">L10n EU OSS OCA</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:9f24da0b57196401086a0a54b7bb7e24024c260cc4c90d42308810512634a55c
!! source digest: sha256:b934fc4e54b9d6a5abf0c03b02e43a201fc94b132e10906c29b0f2f30037223b
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.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/l10n_eu_oss_oca"><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-l10n_eu_oss_oca"><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>
<p>This module has been created to help with the tax mapping according to the EU One-Stop-Shop law, that concerns many companies that carry out distance sales.</p>
Expand Down Expand Up @@ -419,9 +420,6 @@ <h1><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h1>
<ol class="arabic simple">
<li>This module doesn’t take into account if one or more products
have different type of taxes in the destination contry.</li>
<li>There are some countries (for example Spain) that have different taxes
depending on the region (Canary islands).
These use cases haven’t been considered.</li>
<li>There are some countries (for example Cyprus) that have
uncommon reduced taxes, depending on the typology of the sold product.
In Cyprus, it happens with <em>Supply of goods and services
Expand Down
35 changes: 35 additions & 0 deletions l10n_eu_oss_oca/tests/test_l10n_eu_oss.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def setUpClass(cls):
cls.oss_tax_rate_fr = cls.env.ref("l10n_eu_oss_oca.oss_eu_rate_fr")
# Country
cls.country_fr = cls.env.ref("base.fr")
cls.country_pt = cls.env.ref("base.pt")
# Sale Taxes
tax_vals = {
"name": "general tax",
Expand Down Expand Up @@ -139,3 +140,37 @@ def test_02(self):
]
)
self.assertEqual(move.tax_country_id, move.company_id.account_fiscal_country_id)

def test_03_states(self):
wizard_vals = {
"company_id": self.company_main.id,
"general_tax": self.general_tax.id,
}
wizard = self._oss_wizard_create(wizard_vals)
wizard.todo_country_ids = [(6, 0, self.country_pt.ids)]
wizard.generate_eu_oss_taxes()
positions = self._fpos_search(self.country_pt.id)
self.assertEqual(len(positions), 3)
for fpos, data in zip(
positions,
[
{
"src_rate": 20,
"dest_rate": 23,
"state_ids": self.env["res.country.state"],
},
{
"src_rate": 20,
"dest_rate": 16,
"state_ids": self.env.ref("base.state_pt_pt-20"),
},
{
"src_rate": 20,
"dest_rate": 22,
"state_ids": self.env.ref("base.state_pt_pt-30"),
},
],
):
self.assertEqual(fpos.tax_ids[0].tax_src_id.amount, data["src_rate"])
self.assertEqual(fpos.tax_ids[0].tax_dest_id.amount, data["dest_rate"])
self.assertEqual(fpos.state_ids, data["state_ids"])
99 changes: 58 additions & 41 deletions l10n_eu_oss_oca/wizard/l10n_eu_oss_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,13 @@ def generate_dict_taxes(self, selected_taxes, oss_rate_id):
]
return dict_taxes

def _prepare_fiscal_position_vals(self, country, taxes_data):
def _prepare_fiscal_position_vals(self, country, taxes_data, oss_states):
fiscal_pos_name = _("Intra-EU B2C in %(country_name)s") % {
"country_name": country.name
}
fiscal_pos_name += " (EU-OSS-%s)" % country.code
if oss_states:
fiscal_pos_name += f" ({', '.join(oss_states.mapped('name'))})"
return {
"name": fiscal_pos_name,
"company_id": self.company_id.id,
Expand All @@ -157,6 +159,7 @@ def _prepare_fiscal_position_vals(self, country, taxes_data):
"fiscal_position_type": "b2c",
"tax_ids": [(0, 0, tax_data) for tax_data in taxes_data],
"oss_oca": True,
"state_ids": [(6, 0, oss_states.ids)],
}

def update_fpos(self, fpos_id, taxes_data):
Expand All @@ -181,54 +184,68 @@ def generate_eu_oss_taxes(self):
if self.second_superreduced_tax:
selected_taxes.append(self.second_superreduced_tax)
for country in self.todo_country_ids:
oss_rate_id = oss_rate.search([("oss_country_id", "=", country.id)])
taxes_data = []
# Create taxes dict to create
dict_taxes = self.generate_dict_taxes(
selected_taxes, oss_rate_id.get_rates_list()
)
# Create and search taxes
last_rate = None
tax_dest_id = None
for tax, rate in dict_taxes.items():
if last_rate != rate:
tax_dest_id = self.env["account.tax"].search(
[
("amount", "=", rate),
("type_tax_use", "=", "sale"),
("oss_country_id", "=", country.id),
("company_id", "=", self.company_id.id),
],
limit=1,
)
if not tax_dest_id:
tax_group = account_tax_group.search(
[("name", "=", self._prepare_tax_group_vals(rate)["name"])],
oss_rates = oss_rate.search([("oss_country_id", "=", country.id)])
for oss_rate in oss_rates:
taxes_data = []
# Create taxes dict to create
dict_taxes = self.generate_dict_taxes(
selected_taxes, oss_rate.get_rates_list()
)
# Create and search taxes
last_rate = None
tax_dest_id = None
for tax, rate in dict_taxes.items():
if last_rate != rate:
tax_dest_id = self.env["account.tax"].search(
[
("amount", "=", rate),
("type_tax_use", "=", "sale"),
("oss_country_id", "=", country.id),
("company_id", "=", self.company_id.id),
],
limit=1,
)
if not tax_group:
tax_group = account_tax_group.create(
self._prepare_tax_group_vals(rate)
if not tax_dest_id:
tax_group = account_tax_group.search(
[
(
"name",
"=",
self._prepare_tax_group_vals(rate)["name"],
)
],
limit=1,
)
tax_dest_id = account_tax.create(
self._prepare_tax_vals(country, tax, rate, tax_group)
)
taxes_data.append({"tax_src_id": tax.id, "tax_dest_id": tax_dest_id.id})
last_rate = rate
# Create a fiscal position for the country
fpos = self.env["account.fiscal.position"].search(
[
if not tax_group:
tax_group = account_tax_group.create(
self._prepare_tax_group_vals(rate)
)
tax_dest_id = account_tax.create(
self._prepare_tax_vals(country, tax, rate, tax_group)
)
taxes_data.append(
{"tax_src_id": tax.id, "tax_dest_id": tax_dest_id.id}
)
last_rate = rate
# Create a fiscal position for the country
domain = [
("country_id", "=", country.id),
("vat_required", "=", False),
("auto_apply", "=", True),
("company_id", "=", self.company_id.id),
("fiscal_position_type", "=", "b2c"),
("oss_oca", "=", True),
]
)
if not fpos:
data_fiscal = self._prepare_fiscal_position_vals(country, taxes_data)
fpos_obj.create(data_fiscal)
else:
self.update_fpos(fpos, taxes_data)
if oss_rate.oss_state_ids:
domain.append(("state_ids", "in", oss_rate.oss_state_ids.ids))
else:
domain.append(("state_ids", "=", False))
fpos = self.env["account.fiscal.position"].search(domain)
if not fpos:
data_fiscal = self._prepare_fiscal_position_vals(
country, taxes_data, oss_rate.oss_state_ids
)
fpos_obj.create(data_fiscal)
else:
self.update_fpos(fpos, taxes_data)
return {"type": "ir.actions.act_window_close"}

0 comments on commit 564dabf

Please sign in to comment.