summaryrefslogtreecommitdiff
path: root/addons/l10n_eu_service/wizard/wizard.py
blob: 01487dab82178d3a9896a353f64500b061f0e39d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models, _
from odoo.exceptions import UserError, Warning


class l10n_eu_service(models.TransientModel):
    """Create fiscal positions for EU Service VAT"""
    _name = "l10n_eu_service.wizard"
    _description = __doc__

    def _get_eu_res_country_group(self):
        eu_group = self.env.ref("base.europe", raise_if_not_found=False)
        if not eu_group:
            raise Warning(_('The Europe country group cannot be found. '
                            'Please update the base module.'))
        return eu_group

    def _get_default_company_id(self):
        return self.env.company.id

    def _default_fiscal_position_id(self):
        user = self.env.user
        eu_id = self._get_eu_res_country_group()
        return self.env['account.fiscal.position'].search(
            [('company_id', '=', user.company_id.id), ('vat_required', '=', True),
             ('country_group_id.id', '=', eu_id.id)], limit=1)

    def _default_tax_id(self):
        user = self.env.user
        return self.env['account.tax'].search(
            [('company_id', '=', user.company_id.id), ('type_tax_use', '=', 'sale'),
             ('amount_type', '=', 'percent')], limit=1, order='amount desc')

    def _default_done_country_ids(self):
        user = self.env.user
        eu_country_group = self._get_eu_res_country_group()
        return eu_country_group.country_ids - self._default_todo_country_ids() - user.company_id.country_id

    def _default_todo_country_ids(self):
        user = self.env.user
        eu_country_group = self._get_eu_res_country_group()
        eu_fiscal = self.env['account.fiscal.position'].search(
            [('country_id', 'in', eu_country_group.country_ids.ids),
             ('vat_required', '=', False), ('auto_apply', '=', True),
             ('company_id', '=', user.company_id.id)])
        return eu_country_group.country_ids - eu_fiscal.mapped('country_id') - user.company_id.country_id

    company_id = fields.Many2one(
        'res.company', string='Company', required=True, default=_get_default_company_id)
    fiscal_position_id = fields.Many2one(
        'account.fiscal.position', string='Fiscal Position', default=_default_fiscal_position_id,
        help="Optional fiscal position to use as template for general account mapping. "
             "Should usually be your current Intra-EU B2B fiscal position. "
             "If not set, no general account mapping will be configured for EU fiscal positions.")
    tax_id = fields.Many2one(
        'account.tax', string='Service VAT', required=True, default=_default_tax_id,
        help="Select your current VAT tax for services. This is the tax that will be mapped "
             "to the corresponding VAT tax in each EU country selected below.")
    account_collected_id = fields.Many2one(
        "account.account", string="Tax Collection Account",
        help="Optional account to use for collecting tax amounts when selling services in "
             "each EU country selected below. If not set, the current collecting account of "
             "your Service VAT will be used.")
    done_country_ids = fields.Many2many(
        'res.country', 'l10n_eu_service_country_rel_done', default=_default_done_country_ids,
        string='Already Supported')
    todo_country_ids = fields.Many2many(
        'res.country', 'l10n_eu_service_country_rel_todo', default=_default_todo_country_ids,
        string='EU Customers From', required=True)

    @api.model
    def load_views(self, views, options=None):
        # This wizard is outdated; it shouldn't be used anymore. Users might still be able to open it using the
        # link in the settings if they didn't update the module. If they try, we tell them.
        raise UserError(_("Starting July 1st 2021, OSS regulation has replaced MOSS. Please first upgrade 'l10n_eu_service' module in the Apps menu, then go back to this setting and click on 'Refresh tax mapping'."))

    def _get_repartition_line_copy_values(self, original_rep_lines):
        return [(0, 0, {
            'factor_percent': line.factor_percent,
            'repartition_type': line.repartition_type,
            'account_id': line.repartition_type == 'tax' and (self.account_collected_id.id or line.account_id.id) or None,
            'company_id': line.company_id.id,
            'sequence': line.sequence,
        }) for line in original_rep_lines]

    def generate_eu_service(self):
        tax_rate = self.env["l10n_eu_service.service_tax_rate"]
        account_tax = self.env['account.tax']
        fpos = self.env['account.fiscal.position']
        for country in self.todo_country_ids:
            format_params = {'country_name': country.name}
            tax_name = _("VAT for EU Services to %(country_name)s") % format_params
            #create a new tax based on the selected service tax
            data_tax = {
                'name': tax_name,
                'amount': tax_rate.search([('country_id', '=', country.id)]).rate,
                'invoice_repartition_line_ids': self._get_repartition_line_copy_values(self.tax_id.invoice_repartition_line_ids),
                'refund_repartition_line_ids': self._get_repartition_line_copy_values(self.tax_id.refund_repartition_line_ids),
                'type_tax_use': 'sale',
                'description': "EU-VAT-%s-S" % country.code,
                'sequence': 1000,
            }
            tax = account_tax.create(data_tax)
            if self.fiscal_position_id:
                account_ids = [(6, 0, self.fiscal_position_id.account_ids.ids)]
            else:
                account_ids = False
            #create a fiscal position for the country
            fiscal_pos_name = _("Intra-EU B2C in %(country_name)s") % {'country_name': country.name}
            fiscal_pos_name += " (EU-VAT-%s)" % country.code
            data_fiscal = {
                'name': fiscal_pos_name,
                'company_id': self.company_id.id,
                'vat_required': False,
                'auto_apply': True,
                'country_id': country.id,
                'account_ids': account_ids,
                'tax_ids': [(0, 0, {'tax_src_id': self.tax_id.id, 'tax_dest_id': tax.id})],
            }
            fpos.create(data_fiscal)

        return {'type': 'ir.actions.act_window_close'}