summaryrefslogtreecommitdiff
path: root/addons/base_vat
diff options
context:
space:
mode:
authorwan <wan@odoo.com>2021-02-09 08:49:24 +0000
committerwan <wan@odoo.com>2021-02-10 12:22:42 +0000
commit9a46cc7ad89544a5669b4e5a7ae8b6c31d52eab3 (patch)
tree8091dcce037f8f9e4a198fb9c5a67dfdfb65219f /addons/base_vat
parent696819972d5a51f826fb675f0cb712f819c2cdf4 (diff)
[FIX] base_vat: not called at all
The function was wrongly imported and used, and it was hidden by a generic catching of all exceptions. The return value and some legit exceptions were also badly handled: * The return value was always thruthy as it returns an object containing information about the check. * Exceptions can be raised if the format is not correct. In that case, we don't want to go to the simple vat check. Fixes #64897 opw-2451951 closes odoo/odoo#65771 Signed-off-by: William André (wan) <wan@odoo.com>
Diffstat (limited to 'addons/base_vat')
-rw-r--r--addons/base_vat/models/res_partner.py29
-rw-r--r--addons/base_vat/tests/test_validate_ruc.py36
2 files changed, 46 insertions, 19 deletions
diff --git a/addons/base_vat/models/res_partner.py b/addons/base_vat/models/res_partner.py
index 1bcc7dc5d01..dcb863d68a3 100644
--- a/addons/base_vat/models/res_partner.py
+++ b/addons/base_vat/models/res_partner.py
@@ -5,11 +5,17 @@ import datetime
import string
import re
import stdnum
+from stdnum.eu.vat import check_vies
+from stdnum.exceptions import InvalidComponent
+import logging
from odoo import api, models, tools, _
from odoo.tools.misc import ustr
from odoo.exceptions import ValidationError
+
+_logger = logging.getLogger(__name__)
+
_eu_country_vat = {
'GR': 'EL'
}
@@ -99,20 +105,24 @@ class ResPartner(models.Model):
def _check_vies(self, vat):
# Store the VIES result in the cache. In case an exception is raised during the request
# (e.g. service unavailable), the fallback on simple_vat_check is not kept in cache.
- return stdnum.eu.vat.check_vies(vat)
+ return check_vies(vat)
@api.model
def vies_vat_check(self, country_code, vat_number):
try:
# Validate against VAT Information Exchange System (VIES)
# see also http://ec.europa.eu/taxation_customs/vies/
- return self._check_vies(country_code.upper() + vat_number)
+ vies_result = self._check_vies(country_code.upper() + vat_number)
+ return vies_result['valid']
+ except InvalidComponent:
+ return False
except Exception:
# see http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
# Fault code may contain INVALID_INPUT, SERVICE_UNAVAILABLE, MS_UNAVAILABLE,
# TIMEOUT or SERVER_BUSY. There is no way we can validate the input
# with VIES if any of these arise, including the first one (it means invalid
# country code or empty VAT number), so we fall back to the simple check.
+ _logger.exception("Failed VIES VAT check.")
return self.simple_vat_check(country_code, vat_number)
@api.model
@@ -134,17 +144,18 @@ class ResPartner(models.Model):
company = self.env['res.company'].browse(self.env.context['company_id'])
else:
company = self.env.company
- if company.vat_check_vies:
- # force full VIES online check
- check_func = self.vies_vat_check
- else:
- # quick and partial off-line checksum validation
- check_func = self.simple_vat_check
+ eu_countries = self.env.ref('base.europe').country_ids
for partner in self:
if not partner.vat:
continue
#check with country code as prefix of the TIN
vat_country, vat_number = self._split_vat(partner.vat)
+ if company.vat_check_vies and partner.commercial_partner_id.country_id in eu_countries:
+ # force full VIES online check
+ check_func = self.vies_vat_check
+ else:
+ # quick and partial off-line checksum validation
+ check_func = self.simple_vat_check
if not check_func(vat_country, vat_number):
#if fails, check with country code from country
country_code = partner.commercial_partner_id.country_id.code
@@ -183,7 +194,7 @@ class ResPartner(models.Model):
'''
# A new VAT number format in Switzerland has been introduced between 2011 and 2013
# https://www.estv.admin.ch/estv/fr/home/mehrwertsteuer/fachinformationen/steuerpflicht/unternehmens-identifikationsnummer--uid-.html
- # The old format "TVA 123456" is not valid since 2014
+ # The old format "TVA 123456" is not valid since 2014
# Accepted format are: (spaces are ignored)
# CHE#########MWST
# CHE#########TVA
diff --git a/addons/base_vat/tests/test_validate_ruc.py b/addons/base_vat/tests/test_validate_ruc.py
index 9f65d5aab37..c51433da8ed 100644
--- a/addons/base_vat/tests/test_validate_ruc.py
+++ b/addons/base_vat/tests/test_validate_ruc.py
@@ -1,11 +1,20 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo.tests import common
+from odoo.tests.common import SavepointCase, tagged
from odoo.exceptions import ValidationError
from unittest.mock import patch
-from stdnum.eu import vat
+import stdnum.eu.vat
-class TestStructure(common.TransactionCase):
+
+class TestStructure(SavepointCase):
+ @classmethod
+ def setUpClass(cls):
+ def check_vies(vat_number):
+ return {'valid': vat_number == 'BE0477472701'}
+
+ super().setUpClass()
+ cls.env.user.company_id.vat_check_vies = False
+ cls._vies_check_func = check_vies
def test_peru_ruc_format(self):
"""Only values that has the length of 11 will be checked as RUC, that's what we are proving. The second part
@@ -29,7 +38,7 @@ class TestStructure(common.TransactionCase):
def test_parent_validation(self):
"""Test the validation with company and contact"""
- # disable the verification to set an invalid vat number
+ # set an invalid vat number
self.env.user.company_id.vat_check_vies = False
company = self.env["res.partner"].create({
"name": "World Company",
@@ -43,11 +52,18 @@ class TestStructure(common.TransactionCase):
"company_type": "person",
})
- def mock_check_vies(vat_number):
- """ Fake vatnumber method that will only allow one number """
- return vat_number == 'BE0987654321'
-
# reactivate it and correct the vat number
- with patch.object(vat, 'check_vies', mock_check_vies):
+ with patch('odoo.addons.base_vat.models.res_partner.check_vies', type(self)._vies_check_func):
self.env.user.company_id.vat_check_vies = True
- company.vat = "BE0987654321"
+ with self.assertRaises(ValidationError), self.env.cr.savepoint():
+ company.vat = "BE0987654321" # VIES refused, don't fallback on other check
+ company.vat = "BE0477472701"
+
+
+@tagged('-standard', 'external')
+class TestStructureVIES(TestStructure):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.env.user.company_id.vat_check_vies = True
+ cls._vies_check_func = stdnum.eu.vat.check_vies