From a13827eb221bbe04d76fd23fb0fe66987be1fe20 Mon Sep 17 00:00:00 2001 From: moylop260 Date: Wed, 20 Apr 2011 15:05:54 +0300 Subject: [PATCH 1/4] base_vat: Fix wrong validation for MX [Bug 749958] I tested the last patch https://launchpadlibrarian.net/68224790/base_vat.py.withregexp.patch With 242,665 Mexican valids RFC (cherry picked from commit 7ecb9aebfef4f2f131df4cd76372c455c06a8762) bzr revid: p_christ@hol.gr-20110420120554-itxrqntpgc05hksw --- addons/base_vat/base_vat.py | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py index 102619e876d..2fea37ddf0f 100644 --- a/addons/base_vat/base_vat.py +++ b/addons/base_vat/base_vat.py @@ -39,7 +39,7 @@ _ref_vat = { 'pt': 'PT123456789', 'ro': 'RO1234567897', 'se': 'SE123456789701', 'si': 'SI12345679', 'sk': 'SK0012345675', 'el': 'EL12345670', - 'mx': 'MXABC123456T1B' + 'mx': 'MXABCD831230T1B', } @@ -1066,17 +1066,39 @@ class res_partner(osv.osv): return False return True - def check_vat_mx(self, vat): + def check_vat_mx(vat): ''' - Verificar RFC méxico + Verificar RFC México ''' - if not 12 <= len(vat) <= 13: + #[IMP] base_vat: check_vat_mx by moylop260@hotmail.com, tested with 242,665 real RFC's + import time + import re + map_initials = "[A-Z|&]"*4 + map_date = "[0-9][0-9][0-1][1-9][0-3][0-9]" + map_code = "[A-Z|&|0-9]"*3 + mapping = map_initials + map_date + map_code + + vat = vat.upper().replace('ñ', 'Ñ').replace('\xd1', 'Ñ').replace('\xf1', 'Ñ')#upper ascii + vat = vat.replace('Ñ', 'X')#Replace ascii valid char, these is problems with match in regexp + vat = vat.replace(' ', '').replace('-', '')#Replace some char valid, but no required + if len(vat)==12: + vat = "X" + vat#Add a valid char, for pass validation with case with cad of len = 12 + if len(vat) <> 13: return False - elif len(vat)==12 and not vat[:3].isalpha() | vat[3:9].isdigit() | vat[-3:].isalnum(): + regex = re.compile(mapping) + if not regex.match(vat): + #No valid format return False - elif len(vat)==13 and not vat[:4].isalpha() | vat[4:10].isdigit() | vat[-3:].isalnum(): + date_match = re.search(map_date, vat) + date_format = '%y%m%d' + try: + time.strptime(date_match.group(), date_format) + except: + #Valid format, but date wrong return False + #Valid format and valid date return True + res_partner() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From 3432fe6d651b569db5dc0c4c88586942fac1ae2e Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Wed, 20 Apr 2011 15:06:58 +0300 Subject: [PATCH 2/4] base_vat: cleaner version of Mexico validator bzr revid: p_christ@hol.gr-20110420120658-u5ycapiy20uxx5wn --- addons/base_vat/base_vat.py | 38 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py index 2fea37ddf0f..190541bbcfb 100644 --- a/addons/base_vat/base_vat.py +++ b/addons/base_vat/base_vat.py @@ -23,6 +23,8 @@ import string from osv import osv, fields from tools.translate import _ +import re +import datetime _ref_vat = { 'be': 'BE0477472701', 'at': 'ATU12345675', @@ -1066,36 +1068,26 @@ class res_partner(osv.osv): return False return True + __check_vat_mx_re = re.compile(r"(?P[A-Z&ñÑ]{3,4})" \ + r"[ \-_]?" \ + r"(?P[0-9]{2})(?P[01][1-9])(?P[0-3][0-9])" \ + r"[ \-_]?" \ + r"(?P[A-Z0-9&ñÑ\xd1\xf1]{3})$") + def check_vat_mx(vat): - ''' + ''' Mexican VAT verification + Verificar RFC México ''' - #[IMP] base_vat: check_vat_mx by moylop260@hotmail.com, tested with 242,665 real RFC's - import time - import re - map_initials = "[A-Z|&]"*4 - map_date = "[0-9][0-9][0-1][1-9][0-3][0-9]" - map_code = "[A-Z|&|0-9]"*3 - mapping = map_initials + map_date + map_code - - vat = vat.upper().replace('ñ', 'Ñ').replace('\xd1', 'Ñ').replace('\xf1', 'Ñ')#upper ascii - vat = vat.replace('Ñ', 'X')#Replace ascii valid char, these is problems with match in regexp - vat = vat.replace(' ', '').replace('-', '')#Replace some char valid, but no required - if len(vat)==12: - vat = "X" + vat#Add a valid char, for pass validation with case with cad of len = 12 - if len(vat) <> 13: - return False - regex = re.compile(mapping) - if not regex.match(vat): + m = self.__check_vat_mx_re.match(vat) + if not m: #No valid format return False - date_match = re.search(map_date, vat) - date_format = '%y%m%d' try: - time.strptime(date_match.group(), date_format) - except: - #Valid format, but date wrong + datetime.date(int(m.group('ano')), int(m.group('mes')), int(m.group('dia'))) + except ValueError: return False + #Valid format and valid date return True From 8d984744debb9c538b3d549ea627b82b95086252 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Fri, 29 Apr 2011 11:35:46 +0300 Subject: [PATCH 3/4] base_vat: fix the silly regression that broke check_vat_mx bzr revid: p_christ@hol.gr-20110429083546-vm5t0t1g5bibs8vh --- addons/base_vat/base_vat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py index 190541bbcfb..bcfbfec3436 100644 --- a/addons/base_vat/base_vat.py +++ b/addons/base_vat/base_vat.py @@ -1074,7 +1074,7 @@ class res_partner(osv.osv): r"[ \-_]?" \ r"(?P[A-Z0-9&ñÑ\xd1\xf1]{3})$") - def check_vat_mx(vat): + def check_vat_mx(self, vat): ''' Mexican VAT verification Verificar RFC México From b6dce5a11b4c5e0bf5d7c50dca7d6f2f14392d3a Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Fri, 29 Apr 2011 11:36:25 +0300 Subject: [PATCH 4/4] base_vat: fix check_vat_mx, wrt. encoding, small letters and year range As of this commit, tests pass all the 242662 numbers provided by moylop260 bzr revid: p_christ@hol.gr-20110429083625-80dd16bs4dlbvt1w --- addons/base_vat/base_vat.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py index bcfbfec3436..7d0f61df82c 100644 --- a/addons/base_vat/base_vat.py +++ b/addons/base_vat/base_vat.py @@ -23,6 +23,7 @@ import string from osv import osv, fields from tools.translate import _ +from tools.misc import ustr import re import datetime @@ -1068,23 +1069,30 @@ class res_partner(osv.osv): return False return True - __check_vat_mx_re = re.compile(r"(?P[A-Z&ñÑ]{3,4})" \ + __check_vat_mx_re = re.compile(r"(?P[A-Za-z\xd1\xf1&]{3,4})" \ r"[ \-_]?" \ - r"(?P[0-9]{2})(?P[01][1-9])(?P[0-3][0-9])" \ + r"(?P[0-9]{2})(?P[01][0-9])(?P[0-3][0-9])" \ r"[ \-_]?" \ - r"(?P[A-Z0-9&ñÑ\xd1\xf1]{3})$") + r"(?P[A-Za-z0-9&\xd1\xf1]{3})$") def check_vat_mx(self, vat): ''' Mexican VAT verification Verificar RFC México ''' + # we convert to 8-bit encoding, to help the regex parse only bytes + vat = ustr(vat).encode('iso8859-1') m = self.__check_vat_mx_re.match(vat) if not m: #No valid format return False try: - datetime.date(int(m.group('ano')), int(m.group('mes')), int(m.group('dia'))) + ano = int(m.group('ano')) + if ano > 30: + ano = 1900 + ano + else: + ano = 2000 + ano + datetime.date(ano, int(m.group('mes')), int(m.group('dia'))) except ValueError: return False