[FIX] base_vat, website_sale: Verification of vat number in EU country
We have problems when trying to validate our EU VAT report because some vat number are wrongly encoded in Odoo.
There are 2 problems:
1) We use vatnumber library to check the validity of the VAT number entered by the user on website.
That library removes the following characters '.' and '-' in order to perform the check and
thus can return True for a number like 123.123.123.13 or -123-3454-34
And those VAT number are then saved in our database but are rejected by the state
as VAT number should only contains alphanumeric character
-> Solution: prevent entering vat number with other characters than alphanumeric for users that are located in EUROPE!
2) Usually VAT is prefixed by country code, however some people in europe managed to bypass the system
by prefixing their VAT number with CC instead of their country code, CC is consider valid in odoo
(it means Country Code) but is not a valid European country code in general, which means that those
people that should have pay some tax have not. Which is a huge problem.
-> Solution: prevent the use of CC as country code by the user when entering a vatnumber only if the user country is in EUROPE!
source: https://en.wikipedia.org/wiki/VAT_identification_number
opw:772621
This commit is contained in:
@@ -14,10 +14,17 @@ except ImportError:
|
||||
"Install it to support more countries, for example with `easy_install vatnumber`.")
|
||||
vatnumber = None
|
||||
|
||||
from openerp import api
|
||||
from openerp.osv import osv
|
||||
from openerp.tools.misc import ustr
|
||||
from openerp.tools.translate import _
|
||||
|
||||
_eu_country_vat = {
|
||||
'GR': 'EL'
|
||||
}
|
||||
|
||||
_eu_country_vat_inverse = {v: k for k, v in _eu_country_vat.items()}
|
||||
|
||||
_ref_vat = {
|
||||
'at': 'ATU12345675',
|
||||
'be': 'BE0477472701',
|
||||
@@ -79,6 +86,7 @@ class res_partner(osv.osv):
|
||||
# may have a VATIN starting with "EU" instead of a country code.
|
||||
return True
|
||||
res_country = self.pool.get('res.country')
|
||||
country_code = _eu_country_vat_inverse.get(country_code, country_code)
|
||||
return bool(res_country.search(cr, uid, [('code', '=ilike', country_code)], context=context))
|
||||
return check_func(vat_number)
|
||||
|
||||
@@ -95,6 +103,20 @@ class res_partner(osv.osv):
|
||||
# country code or empty VAT number), so we fall back to the simple check.
|
||||
return self.simple_vat_check(cr, uid, country_code, vat_number, context=context)
|
||||
|
||||
@api.model
|
||||
def fix_eu_vat_number(self, country_id, vat):
|
||||
in_europe = False
|
||||
europe = self.env.ref('base.europe')
|
||||
country = self.env["res.country"].browse(country_id)
|
||||
if not europe:
|
||||
europe = self.env["res.country.group"].search([('name', '=', 'Europe')], limit=1)
|
||||
if europe and country and country.id in europe.country_ids.ids:
|
||||
vat = re.sub('[^A-Za-z0-9]', '', vat).upper()
|
||||
country_code = _eu_country_vat.get(country.code, country.code).upper()
|
||||
if vat[:2] != country_code:
|
||||
vat = country_code + vat
|
||||
return vat
|
||||
|
||||
def check_vat(self, cr, uid, ids, context=None):
|
||||
user_company = self.pool.get('res.users').browse(cr, uid, uid).company_id
|
||||
if user_company.vat_check_vies:
|
||||
|
||||
@@ -569,6 +569,8 @@ class website_sale(http.Controller):
|
||||
|
||||
# vat validation
|
||||
if data.get("vat") and hasattr(registry["res.partner"], "check_vat"):
|
||||
if data.get("country_id"):
|
||||
data["vat"] = registry["res.partner"].fix_eu_vat_number(cr, uid, data.get("country_id"), data.get("vat"), context)
|
||||
if request.website.company_id.vat_check_vies:
|
||||
# force full VIES online check
|
||||
check_func = registry["res.partner"].vies_vat_check
|
||||
|
||||
Reference in New Issue
Block a user