[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#66522 X-original-commit: e711f359fef7ed4c37cb26d3946744e140bf00e0 Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 TransactionCase, 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(TransactionCase):
|
||||
@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
|
||||
|
||||
Reference in New Issue
Block a user