Skip to content

Commit

Permalink
[IMP] l10n_eu_service: OSS - Automatic Tax and Fiscal Position Mappin…
Browse files Browse the repository at this point in the history
…g for EU Countries

Due to EU e-commerce 'One-Stop Shop' which becomes available on 1 July 2021, EU companies involved in distance sales are able to file their taxes using the new OSS process. Adopting OSS is now simplified in Odoo.

On installation of the module, all companies having a fiscal country in the EU will be processed.
For all existing domestic taxes in the company, an associated foreign tax (standard rate, reduced rate, etc) is found in the `EU_TAX_MAP`. This mapping will be created in a fiscal position that is automatically detected based on the customers' country.

All that is required from the user, is to review the tax mappings according to the products and services sold by the company.

A refresh button is also available in the odoo settings to redo/update the fiscal positions. This might be useful after adding a new tax.

Note: The tax mapping herein is not intended to cover all possible tax mappings between EU countries, but rather, the most commonly used ones. It is advised that users with special tax cases update the created Fiscal Positions according to their requirements.

Closes [Task 2579615]

closes #72771

Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com>
  • Loading branch information
h4818 committed Jun 30, 2021
1 parent aab38f9 commit d347eae
Show file tree
Hide file tree
Showing 11 changed files with 2,199 additions and 43 deletions.
2 changes: 1 addition & 1 deletion addons/account/models/res_config_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class ResConfigSettings(models.TransientModel):
module_currency_rate_live = fields.Boolean(string="Automatic Currency Rates")
module_account_intrastat = fields.Boolean(string='Intrastat')
module_product_margin = fields.Boolean(string="Allow Product Margin")
module_l10n_eu_service = fields.Boolean(string="EU Digital Goods VAT")
module_l10n_eu_service = fields.Boolean(string="EU Intra-community Distance Selling")
module_account_taxcloud = fields.Boolean(string="Account TaxCloud")
module_account_invoice_extract = fields.Boolean(string="Bill Digitalization")
module_snailmail_account = fields.Boolean(string="Snailmail")
Expand Down
5 changes: 3 additions & 2 deletions addons/account/views/res_config_settings_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,15 @@
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="eu_service" title="If you're selling digital goods to customers in the EU, you must charge VAT based on your customers' locations. This rule applies regardless of you are located. Digital goods are defined in the legislation as broadcasting, telecommunications, and services that are electronically supplied instead of shipped. Gift cards sent online are not included in the definition.">
<div class="col-12 col-lg-6 o_setting_box" id="eu_service" title="If you sell goods and services to customers in a foreign EU country, you must charge VAT based on the delivery address. This rule applies regardless of where you are located.">
<div class="o_setting_left_pane">
<field name="module_l10n_eu_service"/>
</div>
<div class="o_setting_right_pane" name="l10n_eu_service_right_pane">
<label for="module_l10n_eu_service"/>
<a href="https://www.odoo.com/documentation/14.0/applications/finance/accounting/taxation/taxes/eu_distance_selling.html" title="Documentation" class="o_doc_link" target="_blank"></a>
<div class="text-muted">
Apply right VAT rates for digital products sold in EU
Apply VAT of the EU country to which goods and services are delivered.
</div>
</div>
</div>
Expand Down
8 changes: 8 additions & 0 deletions addons/l10n_eu_service/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,11 @@

from . import wizard
from . import models
from odoo import api, SUPERUSER_ID

def l10n_eu_service_post_init(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
env['res.company']._map_all_eu_companies_taxes()

def l10n_eu_service_uninstall(cr, registry):
cr.execute("DELETE FROM ir_model_data WHERE module = 'l10n_eu_service' and model in ('account.tax.group', 'account.account');")
47 changes: 12 additions & 35 deletions addons/l10n_eu_service/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,32 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

{
'name': 'EU Mini One Stop Shop (MOSS)',
'name': 'EU One Stop Shop (OSS)',
'category': 'Accounting/Localizations',
'description': """
EU Mini One Stop Shop (MOSS) VAT for telecommunications, broadcasting and electronic services
=============================================================================================
EU One Stop Shop (OSS) VAT
==========================
As of January 1rst, 2015, telecommunications, broadcasting
and electronic services sold within the European Union
have to be always taxed in the country where the customer
belongs. In order to simplify the application of this EU
directive, the Mini One Stop Shop (MOSS) registration scheme
allows businesses to make a unique tax declaration.
From July 1st 2021, EU businesses that are selling goods within the EU above EUR 10 000 to buyers located in another EU Member State need to register and pay VAT in the buyers’ Member State.
Below this new EU-wide threshold you can continue to apply the domestic rules for VAT on your cross-border sales. In order to simplify the application of this EU directive, the One Stop Shop (OSS) registration scheme allows businesses to make a unique tax declaration.
This module makes it possible by helping with the creation
of the required EU fiscal positions and taxes in order to
automatically apply and record the required taxes.
This module makes it possible by helping with the creation of the required EU fiscal positions and taxes in order to automatically apply and record the required taxes.
This module installs a wizard to help setup fiscal positions
and taxes for selling electronic services inside EU.
The wizard lets you select:
- the EU countries to which you are selling these
services
- your national VAT tax for services, to be mapped
to the target country's tax
- optionally: a template fiscal position, in order
to copy the account mapping. Should be your
existing B2C Intra-EU fiscal position. (defaults
to no account mapping)
- optionally: an account to use for collecting the
tax amounts (defaults to the account used by your
national VAT tax for services)
It creates the corresponding fiscal positions and taxes,
automatically applicable for EU sales with a customer
in the selected countries.
The wizard can be run again for adding more countries.
All you have to do is check that the proposed mapping is suitable for the products and services you sell.
References
++++++++++
- Directive 2008/8/EC
- Council Implementing Regulation (EU) No 1042/2013
Council Directive (EU) 2017/2455 Council Directive (EU) 2019/1995
Council Implementing Regulation (EU) 2019/2026
""",
'depends': ['account'],
'data': [
'security/ir.model.access.csv',
'wizard/wizard.xml',
'data/l10n_eu_service.service_tax_rate.csv',
'views/res_config_settings_views.xml'
'views/res_config_settings_views.xml',
],
'post_init_hook': 'l10n_eu_service_post_init',
'uninstall_hook': 'l10n_eu_service_uninstall',
}
3 changes: 3 additions & 0 deletions addons/l10n_eu_service/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import chart_template
from . import eu_service_tax_rate
from . import eu_tax_map
from . import res_company
from . import res_config_settings
15 changes: 15 additions & 0 deletions addons/l10n_eu_service/models/chart_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, _

class AccountChartTemplate(models.Model):
_inherit = 'account.chart.template'

def _load(self, sale_tax_rate, purchase_tax_rate, company):
rslt = super()._load( sale_tax_rate, purchase_tax_rate, company)

if company.account_tax_fiscal_country_id in self.env.ref('base.europe').country_ids:
company._map_eu_taxes()

return rslt
Loading

0 comments on commit d347eae

Please sign in to comment.