-
-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[11.0][ADD] l10n_nl_tax_statement_icp
- Loading branch information
Showing
18 changed files
with
669 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png | ||
:target: https://www.gnu.org/licenses/agpl | ||
:alt: License: AGPL-3 | ||
|
||
========================= | ||
Netherlands ICP Statement | ||
========================= | ||
|
||
This module extends the *Netherlands BTW Statement* module (BTW aangifte report), by adding the statement for the *Intra-Community transactions declaration* (ICP declaration). | ||
|
||
The ICP declaration report is based on line *3b - Leveringen naar landen binnen de EU (omzet)* of the BTW aangifte report. | ||
The period is also the same as the one selected in the BTW aangifte report. | ||
|
||
This ICP declaration report includes: | ||
|
||
* the VAT identification numbers of your customers; | ||
* the total amount of intra-Community supplies from the Netherlands for every customer during the selected period. | ||
|
||
Installation | ||
============ | ||
|
||
To install this module, you need to: | ||
|
||
#. Install module *l10n_nl_tax_statement* version >= *11.0.2.0.0*. | ||
|
||
Configuration | ||
============= | ||
|
||
To configure this module, you need to: | ||
|
||
#. Follow the configuration steps as described in *l10n_nl_tax_statement* and set the tag *3b omzet* needed for this report. | ||
|
||
Usage | ||
===== | ||
|
||
To use this module, you need to: | ||
|
||
#. Create a BTW Statement. | ||
#. Post the BTW Statement: a new tab *ICP Statement* will be displayed; the tab contains the lines of the ICP declaration report. | ||
#. In tab *ICP Statement* press the Update button in order to recompute the ICP statement lines. | ||
|
||
Printing a PDF report: | ||
|
||
#. If you need to print the report in PDF, open a statement form and click: `Print -> NL ICP Statement` | ||
|
||
|
||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas | ||
:alt: Try me on Runbot | ||
:target: https://runbot.odoo-community.org/runbot/176/11.0 | ||
|
||
|
||
Known issues / Roadmap | ||
====================== | ||
|
||
* Add checks to avoid errors in the report, e.g. no country, wrong country, no VAT code, tax-code not matching fiscal position, etc.. | ||
* Add unit tests | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues | ||
<https://github.com/OCA/l10n-netherlands/issues>`_. In case of trouble, please | ||
check there if your issue has already been reported. If you spotted it first, | ||
help us smash it by providing detailed and welcomed feedback. | ||
|
||
Credits | ||
======= | ||
|
||
Contributors | ||
------------ | ||
|
||
* Andrea Stirpe <a.stirpe@onestein.nl> | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Maintainer | ||
---------- | ||
|
||
.. image:: https://odoo-community.org/logo.png | ||
:alt: Odoo Community Association | ||
:target: https://odoo-community.org | ||
|
||
This module is maintained by the OCA. | ||
|
||
OCA, or the Odoo Community Association, is a nonprofit organization whose | ||
mission is to support the collaborative development of Odoo features and | ||
promote its widespread use. | ||
|
||
To contribute to this module, please visit https://odoo-community.org. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Copyright 2018 Onestein (<http://www.onestein.eu>) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
{ | ||
'name': 'Netherlands ICP Statement', | ||
'version': '11.0.1.0.0', | ||
'category': 'Localization', | ||
'license': 'AGPL-3', | ||
'author': 'Onestein, Odoo Community Association (OCA)', | ||
'website': 'https://github.com/OCA/l10n-netherlands', | ||
'depends': [ | ||
'l10n_nl_tax_statement', | ||
], | ||
'data': [ | ||
'security/ir.model.access.csv', | ||
'views/l10n_nl_vat_statement_view.xml', | ||
'views/report_tax_statement.xml', | ||
'report/report_tax_statement.xml', | ||
], | ||
'installable': True, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import l10n_nl_vat_statement | ||
from . import l10n_nl_vat_statement_icp_line |
201 changes: 201 additions & 0 deletions
201
l10n_nl_tax_statement_icp/models/l10n_nl_vat_statement.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
# Copyright 2018 Onestein (<http://www.onestein.eu>) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from odoo import api, fields, models, _ | ||
from odoo.exceptions import UserError | ||
|
||
|
||
class VatStatement(models.Model): | ||
_inherit = 'l10n.nl.vat.statement' | ||
|
||
tag_3b_omzet = fields.Many2one( | ||
'account.account.tag', | ||
compute='_compute_tag_3b_omzet' | ||
) | ||
tag_3b_omzet_d = fields.Many2one( | ||
'account.account.tag', | ||
compute='_compute_tag_3b_omzet' | ||
) | ||
icp_line_ids = fields.One2many( | ||
'l10n.nl.vat.statement.icp.line', | ||
'statement_id', | ||
string='ICP Lines', | ||
readonly=True | ||
) | ||
icp_total = fields.Monetary( | ||
string='Total ICP amount', | ||
readonly=True, | ||
help='Total amount in currency of the statement.' | ||
) | ||
|
||
@api.depends('company_id') | ||
def _compute_tag_3b_omzet(self): | ||
''' Computes Tag 3b omzet''' | ||
for statement in self: | ||
config = self.env['l10n.nl.vat.statement.config'].search([ | ||
('company_id', '=', statement.company_id.id) | ||
], limit=1) | ||
statement.tag_3b_omzet = config.tag_3b_omzet | ||
statement.tag_3b_omzet_d = config.tag_3b_omzet_d | ||
|
||
@api.multi | ||
def _compute_icp_lines(self): | ||
''' Computes ICP lines for the report''' | ||
IcpLine = self.env['l10n.nl.vat.statement.icp.line'] | ||
for statement in self: | ||
statement.icp_line_ids.unlink() | ||
statement.icp_total = 0.0 | ||
amounts_map = statement._get_partner_amounts_map() | ||
for partner_id in amounts_map: | ||
icp_values = self._prepare_icp_line(amounts_map[partner_id]) | ||
icp_values['partner_id'] = partner_id | ||
icp_values['statement_id'] = statement.id | ||
newline = IcpLine.create(icp_values) | ||
statement.icp_line_ids += newline | ||
icp_total = newline.amount_products + newline.amount_services | ||
statement.icp_total += icp_total | ||
|
||
@api.model | ||
def _prepare_icp_line(self, partner_amounts): | ||
''' Prepares an internal data structure representing the ICP line''' | ||
return { | ||
'country_code': partner_amounts['country_code'], | ||
'vat': partner_amounts['vat'], | ||
'amount_products': partner_amounts['amount_products'], | ||
'amount_services': partner_amounts['amount_services'], | ||
'currency_id': partner_amounts['currency_id'], | ||
} | ||
|
||
@api.multi | ||
def _is_3b_omzet_line(self, line): | ||
self.ensure_one() | ||
|
||
tag_3b_omzet = self.tag_3b_omzet | ||
for tax in line.tax_ids: | ||
if tax.tag_ids.filtered( | ||
lambda r: r == tag_3b_omzet): | ||
return True | ||
return False | ||
|
||
@api.multi | ||
def _is_3b_omzet_diensten_line(self, line): | ||
self.ensure_one() | ||
|
||
tag_3b_omzet_d = self.tag_3b_omzet_d | ||
for tax in line.tax_ids: | ||
if tax.tag_ids.filtered( | ||
lambda r: r == tag_3b_omzet_d): | ||
return True | ||
return False | ||
|
||
@api.multi | ||
def _get_partner_amounts_map(self): | ||
''' Generate an internal data structure representing the ICP line''' | ||
self.ensure_one() | ||
|
||
partner_amounts_map = {} | ||
for line in self.move_line_ids: | ||
is_3b_omzet = self._is_3b_omzet_line(line) | ||
is_3b_omzet_diensten = self._is_3b_omzet_diensten_line(line) | ||
if is_3b_omzet or is_3b_omzet_diensten: | ||
vals = self._prepare_icp_line_from_move_line(line) | ||
if vals['partner_id'] not in partner_amounts_map: | ||
self._init_partner_amounts_map(partner_amounts_map, vals) | ||
self._update_partner_amounts_map(partner_amounts_map, vals) | ||
return partner_amounts_map | ||
|
||
@api.multi | ||
def _check_config_tag_3b_omzet(self): | ||
''' Checks the tag 3b Omzet, as configured for the BTW statement''' | ||
if self.env.context.get('skip_check_config_tag_3b_omzet'): | ||
return | ||
for statement in self: | ||
if not statement.tag_3b_omzet or not statement.tag_3b_omzet_d: | ||
raise UserError( | ||
_('Tag 3b omzet not configured for this Company! ' | ||
'Check the NL BTW Tags Configuration.')) | ||
|
||
@classmethod | ||
def _update_partner_amounts_map(cls, partner_amounts_map, vals): | ||
''' Update amounts of the internal ICP lines data structure''' | ||
map_data = partner_amounts_map[vals['partner_id']] | ||
map_data['amount_products'] += vals['amount_products'] | ||
map_data['amount_services'] += vals['amount_services'] | ||
|
||
@classmethod | ||
def _init_partner_amounts_map(cls, partner_amounts_map, vals): | ||
''' Initialize the internal ICP lines data structure''' | ||
partner_amounts_map[vals['partner_id']] = { | ||
'country_code': vals['country_code'], | ||
'vat': vals['vat'], | ||
'currency_id': vals['currency_id'], | ||
'amount_products': 0.0, | ||
'amount_services': 0.0, | ||
} | ||
|
||
@api.multi | ||
def _prepare_icp_line_from_move_line(self, line): | ||
''' Gets move line details and prepares ICP report line data''' | ||
self.ensure_one() | ||
|
||
balance = line.balance | ||
if line.company_currency_id != self.currency_id: | ||
balance = line.company_currency_id.with_context( | ||
date=line.date | ||
).compute(balance, self.currency_id, round=True) | ||
amount_products = balance | ||
amount_services = 0.0 | ||
if self._is_3b_omzet_diensten_line(line): | ||
amount_products = 0.0 | ||
amount_services = balance | ||
|
||
return { | ||
'partner_id': line.partner_id.id, | ||
'country_code': line.partner_id.country_id.code, | ||
'vat': line.partner_id.vat, | ||
'amount_products': amount_products, | ||
'amount_services': amount_services, | ||
'currency_id': self.currency_id.id, | ||
} | ||
|
||
@api.multi | ||
def reset(self): | ||
''' Removes ICP lines if reset to draft''' | ||
for statement in self: | ||
statement.icp_line_ids.unlink() | ||
return super(VatStatement, self).reset() | ||
|
||
@api.multi | ||
def post(self): | ||
''' Checks configuration when validating the statement''' | ||
self.ensure_one() | ||
self._check_config_tag_3b_omzet() | ||
res = super(VatStatement, self).post() | ||
self._compute_icp_lines() | ||
return res | ||
|
||
@api.model | ||
def _modifiable_values_when_posted(self): | ||
''' Returns the modifiable fields even when the statement is posted''' | ||
res = super(VatStatement, self)._modifiable_values_when_posted() | ||
res.append('icp_line_ids') | ||
res.append('icp_total') | ||
return res | ||
|
||
@api.multi | ||
def icp_update(self): | ||
''' Update button''' | ||
self.ensure_one() | ||
|
||
if self.state in ['final']: | ||
raise UserError( | ||
_('You cannot modify a final statement!')) | ||
|
||
# clean old lines | ||
self.icp_line_ids.unlink() | ||
|
||
# check config | ||
self._check_config_tag_3b_omzet() | ||
|
||
# create lines | ||
self._compute_icp_lines() |
63 changes: 63 additions & 0 deletions
63
l10n_nl_tax_statement_icp/models/l10n_nl_vat_statement_icp_line.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Copyright 2018 Onestein (<http://www.onestein.eu>) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from odoo import _, api, fields, models | ||
from odoo.tools.misc import formatLang | ||
from odoo.exceptions import ValidationError | ||
|
||
|
||
class VatStatementIcpLine(models.Model): | ||
_name = 'l10n.nl.vat.statement.icp.line' | ||
_description = 'Intra-Community transactions (ICP) line' | ||
_order = 'partner_id, country_code' | ||
|
||
statement_id = fields.Many2one( | ||
'l10n.nl.vat.statement', | ||
'Statement', | ||
ondelete='cascade' | ||
) | ||
partner_id = fields.Many2one( | ||
'res.partner', | ||
string='Partner', | ||
readonly=True, | ||
required=True, | ||
) | ||
vat = fields.Char( | ||
string='VAT', | ||
readonly=True, | ||
) | ||
country_code = fields.Char( | ||
readonly=True, | ||
) | ||
currency_id = fields.Many2one( | ||
'res.currency', | ||
string='Currency', | ||
readonly=True | ||
) | ||
amount_products = fields.Monetary(readonly=True) | ||
format_amount_products = fields.Char(compute='_compute_icp_amount_format') | ||
amount_services = fields.Monetary(readonly=True) | ||
format_amount_services = fields.Char(compute='_compute_icp_amount_format') | ||
|
||
@api.depends('amount_products', 'amount_services') | ||
def _compute_icp_amount_format(self): | ||
for line in self: | ||
amount_products = formatLang( | ||
self.env, line.amount_products, monetary=True) | ||
amount_services = formatLang( | ||
self.env, line.amount_services, monetary=True) | ||
line.format_amount_products = amount_products | ||
line.format_amount_services = amount_services | ||
|
||
@api.constrains('country_code') | ||
def _check_country_code(self): | ||
country_codes = self.mapped('country_code') | ||
if self.env.ref('base.nl').code in country_codes: | ||
raise ValidationError(_( | ||
'Wrong country code (NL) for ICP report.')) | ||
europe_codes = self.env.ref('base.europe').country_ids.mapped('code') | ||
for code in country_codes: | ||
if code not in europe_codes: | ||
raise ValidationError(_( | ||
'Wrong country code (%s) for ICP report. ' | ||
'Please check your configuration.') % code) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
To configure this module, you need to: | ||
|
||
#. Follow the configuration steps as described in *l10n_nl_tax_statement* and set the tag *3b omzet* needed for this report. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* Andrea Stirpe <a.stirpe@onestein.nl> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
This module extends the *Netherlands BTW Statement* module (BTW aangifte report), by adding the statement for the *Intra-Community transactions declaration* (ICP declaration). | ||
|
||
The ICP declaration report is based on line *3b - Leveringen naar landen binnen de EU (omzet)* of the BTW aangifte report. | ||
The period is also the same as the one selected in the BTW aangifte report. | ||
|
||
This ICP declaration report includes: | ||
|
||
* the VAT identification numbers of your customers; | ||
* the total amount of intra-Community supplies from the Netherlands for every customer during the selected period. |
Oops, something went wrong.