base_vat: fix check_vat_mx, wrt. encoding, small letters and year range
[odoo/odoo.git] / addons / base_vat / base_vat.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    Copyright (C) 2008-2009 B2CK, Cedric Krier, Bertrand Chenal (the methods "check_vat_[a-z]{2}"
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22 import string
23
24 from osv import osv, fields
25 from tools.translate import _
26 from tools.misc import ustr
27 import re
28 import datetime
29
30 _ref_vat = {
31     'be': 'BE0477472701', 'at': 'ATU12345675',
32     'bg': 'BG1234567892', 'cy': 'CY12345678F',
33     'cz': 'CZ12345679', 'de': 'DE123456788',
34     'dk': 'DK12345674', 'ee': 'EE123456780',
35     'es': 'ESA12345674', 'fi': 'FI12345671',
36     'fr': 'FR32123456789', 'gb': 'GB123456782',
37     'gr': 'GR12345670', 'hu': 'HU12345676',
38     'ie': 'IE1234567T', 'it': 'IT12345670017',
39     'lt': 'LT123456715', 'lu': 'LU12345613',
40     'lv': 'LV41234567891', 'mt': 'MT12345634',
41     'nl': 'NL123456782B90', 'pl': 'PL1234567883',
42     'pt': 'PT123456789', 'ro': 'RO1234567897',
43     'se': 'SE123456789701', 'si': 'SI12345679',
44     'sk': 'SK0012345675', 'el': 'EL12345670',
45     'mx': 'MXABCD831230T1B',
46
47             }
48
49 def mult_add(i, j):
50     """Sum each digits of the multiplication of i and j."""
51     return reduce(lambda x, y: x + int(y), str(i*j), 0)
52
53 class res_partner(osv.osv):
54     _inherit = 'res.partner'
55
56     def _split_vat(self, vat):
57         vat_country, vat_number = vat[:2].lower(), vat[2:].replace(' ', '')
58         return vat_country, vat_number
59
60     def check_vat(self, cr, uid, ids, context=None):
61         '''
62         Check the VAT number depending of the country.
63         http://sima-pc.com/nif.php
64         '''
65         for partner in self.browse(cr, uid, ids, context=context):
66             if not partner.vat:
67                 continue
68             vat_country, vat_number = self._split_vat(partner.vat)
69             if not hasattr(self, 'check_vat_' + vat_country):
70                 return False
71             check = getattr(self, 'check_vat_' + vat_country)
72             if not check(vat_number):
73                 return False
74         return True
75
76     def vat_change(self, cr, uid, ids, value, context=None):
77         return {'value': {'vat_subjected': bool(value)}}
78
79     _columns = {
80         'vat_subjected': fields.boolean('VAT Legal Statement', help="Check this box if the partner is subjected to the VAT. It will be used for the VAT legal statement.")
81     }
82
83     def _construct_constraint_msg(self, cr, uid, ids, context=None):
84         def default_vat_check(cn, vn):
85             # by default, a VAT number is valid if:
86             #  it starts with 2 letters
87             #  has more than 3 characters
88             return cn[0] in string.ascii_lowercase and cn[1] in string.ascii_lowercase
89         vat_country, vat_number = self._split_vat(self.browse(cr, uid, ids)[0].vat)
90         if default_vat_check(vat_country, vat_number):
91             vat_no = vat_country in _ref_vat and _ref_vat[vat_country] or 'Country Code + Vat Number'
92             return _('The Vat does not seems to be correct. You should have entered something like this %s'), (vat_no)
93         return _('The VAT is invalid, It should begin with the country code'), ()
94
95     _constraints = [(check_vat, _construct_constraint_msg, ["vat"])]
96
97     # code from the following methods come from Tryton (B2CK)
98     # http://www.tryton.org/hgwebdir.cgi/modules/relationship/file/544d1de586d9/party.py
99     def check_vat_at(self, vat):
100         '''
101         Check Austria VAT number.
102         '''
103         if len(vat) != 9:
104             return False
105         if vat[0] != 'U':
106             return False
107         num = vat[1:]
108         try:
109             int(num)
110         except:
111             return False
112         sum = int(num[0]) + mult_add(2, int(num[1])) + \
113                 int(num[2]) + mult_add(2, int(num[3])) + \
114                 int(num[4]) + mult_add(2, int(num[5])) + \
115                 int(num[6])
116         check = 10 - ((sum + 4) % 10)
117         if check == 10:
118             check = 0
119         if int(vat[-1:]) != check:
120             return False
121         return True
122
123     def check_vat_be(self, vat):
124         '''
125         Check Belgium VAT number.
126         '''
127         if len(vat) != 10:
128             return False
129         try:
130             int(vat)
131         except:
132             return False
133         if int(vat[-2:]) != \
134                 97 - (int(vat[:8]) % 97):
135             return False
136         return True
137
138     def check_vat_bg(self, vat):
139         '''
140         Check Bulgaria VAT number.
141         '''
142         if len(vat) not in [9,10]:
143             return False
144         try:
145             int(vat)
146         except:
147             return False
148         if int(vat[0]) in (2, 3) and \
149                 int(vat[1:2]) != 22:
150             return False
151         sum = 4 * int(vat[0]) + 3 * int(vat[1]) + 2 * int(vat[2]) + \
152                 7 * int(vat[3]) + 6 * int(vat[4]) + 5 * int(vat[5]) + \
153                 4 * int(vat[6]) + 3 * int(vat[7]) + 2 * int(vat[8])
154         check = 11 - (sum % 11)
155         if check == 11:
156             check = 0
157         return True
158
159     def check_vat_cy(self, vat):
160         '''
161         Check Cyprus VAT number.
162         '''
163         if len(vat) != 9:
164             return False
165         try:
166             int(vat[:8])
167         except:
168             return False
169         n0 = int(vat[0])
170         n1 = int(vat[1])
171         n2 = int(vat[2])
172         n3 = int(vat[3])
173         n4 = int(vat[4])
174         n5 = int(vat[5])
175         n6 = int(vat[6])
176         n7 = int(vat[7])
177
178         def conv(x):
179             if x == 0:
180                 return 1
181             elif x == 1:
182                 return 0
183             elif x == 2:
184                 return 5
185             elif x == 3:
186                 return 7
187             elif x == 4:
188                 return 9
189             elif x == 5:
190                 return 13
191             elif x == 6:
192                 return 15
193             elif x == 7:
194                 return 17
195             elif x == 8:
196                 return 19
197             elif x == 9:
198                 return 21
199             return x
200         n0 = conv(n0)
201         n2 = conv(n2)
202         n4 = conv(n4)
203         n6 = conv(n6)
204
205         sum = n0 + n1 + n2 + n3 + n4 + n5 + n6 + n7
206         check = chr(sum % 26 + 65)
207         if check != vat[8]:
208             return False
209         return True
210
211     def check_vat_cz(self, vat):
212         '''
213         Check Czech Republic VAT number.
214         '''
215         if len(vat) not in (8, 9, 10):
216             return False
217         try:
218             int(vat)
219         except:
220             return False
221
222         if len(vat) == 8:
223             if int(vat[0]) not in (0, 1, 2, 3, 4, 5, 6, 7, 8):
224                 return False
225             sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \
226                     5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \
227                     2 * int(vat[6])
228             check = 11 - (sum % 11)
229             if check == 10:
230                 check = 0
231             if check == 11:
232                 check = 1
233             if check != int(vat[7]):
234                 return False
235         elif len(vat) == 9 and int(vat[0]) == 6:
236             sum = 8 * int(vat[1]) + 7 * int(vat[2]) + 6 * int(vat[3]) + \
237                     5 * int(vat[4]) + 4 * int(vat[5]) + 3 * int(vat[6]) + \
238                     2 * int(vat[7])
239             check = 9 - ((11 - (sum % 11)) % 10)
240             if check != int(vat[8]):
241                 return False
242         elif len(vat) == 9:
243             if int(vat[0:2]) > 53 and int(vat[0:2]) < 80:
244                 return False
245             if int(vat[2:4]) < 1:
246                 return False
247             if int(vat[2:4]) > 12 and int(vat[2:4]) < 51:
248                 return False
249             if int(vat[2:4]) > 62:
250                 return False
251             if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0:
252                 if int(vat[4:6]) < 1:
253                     return False
254                 if int(vat[4:6]) > 28:
255                     return False
256             if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0:
257                 if int(vat[4:6]) < 1:
258                     return False
259                 if int(vat[4:6]) > 29:
260                     return False
261             if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61):
262                 if int(vat[4:6]) < 1:
263                     return False
264                 if int(vat[4:6]) > 30:
265                     return False
266             if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12, 51,
267                     53, 55, 57, 58, 60, 62):
268                 if int(vat[4:6]) < 1:
269                     return False
270                 if int(vat[4:6]) > 31:
271                     return False
272         elif len(vat) == 10:
273             if int(vat[0:2]) < 54:
274                 return False
275             if int(vat[2:4]) < 1:
276                 return False
277             if int(vat[2:4]) > 12 and int(vat[2:4]) < 51:
278                 return False
279             if int(vat[2:4]) > 62:
280                 return False
281             if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0:
282                 if int(vat[4:6]) < 1:
283                     return False
284                 if int(vat[4:6]) > 28:
285                     return False
286             if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0:
287                 if int(vat[4:6]) < 1:
288                     return False
289                 if int(vat[4:6]) > 29:
290                     return False
291             if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61):
292                 if int(vat[4:6]) < 1:
293                     return False
294                 if int(vat[4:6]) > 30:
295                     return False
296             if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12, 51,
297                     53, 55, 57, 58, 60, 62):
298                 if int(vat[4:6]) < 1:
299                     return False
300                 if int(vat[4:6]) > 31:
301                     return False
302             if (int(vat[0:2]) + int(vat[2:4]) + int(vat[4:6]) + int(vat[6:8]) +
303                     int(vat[8:10])) % 11 != 0:
304                 return False
305             if int(vat[0:10]) % 11 != 0:
306                 return False
307         return True
308
309     def check_vat_de(self, vat):
310         '''
311         Check Germany VAT number.
312         '''
313         if len(vat) != 9:
314             return False
315         try:
316             int(vat)
317         except:
318             return False
319         if int(vat[0:7]) <= 0:
320             return False
321         sum = 0
322         for i in range(8):
323             sum = (2 * ((int(vat[i]) + sum + 9) % 10 + 1)) % 11
324         check = 11 - sum
325         if check == 10:
326             check = 0
327         if int(vat[8]) != check:
328             return False
329         return True
330
331     def check_vat_dk(self, vat):
332         '''
333         Check Denmark VAT number.
334         '''
335         if len(vat) != 8:
336             return False
337         try:
338             int(vat)
339         except:
340             return False
341         if int(vat[0]) <= 0:
342             return False
343         sum = 2 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \
344                 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \
345                 2 * int(vat[6]) + int(vat[7])
346         if sum % 11 != 0:
347             return False
348         return True
349
350     def check_vat_ee(self, vat):
351         '''
352         Check Estonia VAT number.
353         '''
354         if len(vat) != 9:
355             return False
356         try:
357             int(vat)
358         except:
359             return False
360         sum = 3 * int(vat[0]) + 7 * int(vat[1]) + 1 * int(vat[2]) + \
361                 3 * int(vat[3]) + 7 * int(vat[4]) + 1 * int(vat[5]) + \
362                 3 * int(vat[6]) + 7 * int(vat[7])
363         check = 10 - (sum % 10)
364         if check == 10:
365             check = 0
366         if check != int(vat[8]):
367             return False
368         return True
369
370     def check_vat_es(self, vat):
371         '''
372         Check Spain VAT number.
373         '''
374         if len(vat) != 9:
375             return False
376
377         conv = {
378             1: 'T',
379             2: 'R',
380             3: 'W',
381             4: 'A',
382             5: 'G',
383             6: 'M',
384             7: 'Y',
385             8: 'F',
386             9: 'P',
387             10: 'D',
388             11: 'X',
389             12: 'B',
390             13: 'N',
391             14: 'J',
392             15: 'Z',
393             16: 'S',
394             17: 'Q',
395             18: 'V',
396             19: 'H',
397             20: 'L',
398             21: 'C',
399             22: 'K',
400             23: 'E',
401         }
402         #Legal persons with profit aim
403         if vat[0] in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'U', 'V'):
404             try:
405                 int(vat[1:8])
406             except:
407                 return False
408             sum = mult_add(2, int(vat[1])) + int(vat[2]) + \
409                     mult_add(2, int(vat[3])) + int(vat[4]) + \
410                     mult_add(2, int(vat[5])) + int(vat[6]) + \
411                     mult_add(2, int(vat[7]))
412             check = 10 - (sum % 10)
413             if check == 10:
414                 check = 0
415             return True
416         #Legal persons with non-profit aim
417         elif vat[0] in ('N', 'P', 'Q', 'R', 'S', 'W'):
418             try:
419                 int(vat[1:8])
420             except:
421                 return False
422             sum = mult_add(2, int(vat[1])) + int(vat[2]) + \
423                     mult_add(2, int(vat[3])) + int(vat[4]) + \
424                     mult_add(2, int(vat[5])) + int(vat[6]) + \
425                     mult_add(2, int(vat[7]))
426             check = 10 - (sum % 10)
427             check = chr(check + 64)
428             if check != vat[8]:
429                 return False
430             return True
431         #Foreign natural persons, under age 14 or non-residents
432         elif vat[0] in ('K', 'L', 'M', 'X', 'Y', 'Z'):
433             if vat[0] == 'Y':
434                 check_value = '1' + vat[1:8]
435             elif vat[0] == 'Z':
436                 check_value = '2' + vat[1:8]
437             else:
438                 check_value = vat[1:8]
439
440             try:
441                 int(check_value)
442             except:
443                 return False
444             check = 1 + (int(check_value) % 23)
445
446             check = conv[check]
447             if check != vat[8]:
448                 return False
449             return True
450         #Spanish natural persons
451         else:
452             try:
453                 int(vat[:8])
454             except:
455                 return False
456             check = 1 + (int(vat[:8]) % 23)
457
458             check = conv[check]
459             if check != vat[8]:
460                 return False
461             return True
462
463     def check_vat_fi(self, vat):
464         '''
465         Check Finland VAT number.
466         '''
467         if len(vat) != 8:
468             return False
469         try:
470             int(vat)
471         except:
472             return False
473         sum = 7 * int(vat[0]) + 9 * int(vat[1]) + 10 * int(vat[2]) + \
474                 5 * int(vat[3]) + 8 * int(vat[4]) + 4 * int(vat[5]) + \
475                 2 * int(vat[6])
476         check = 11 - (sum % 11)
477         if check == 11:
478             check = 0
479         if check == 10:
480             return False
481         if check != int(vat[7]):
482             return False
483         return True
484
485     def check_vat_fr(self, vat):
486         '''
487         Check France VAT number.
488         '''
489         if len(vat) != 11:
490             return False
491
492         try:
493             int(vat[2:11])
494         except:
495             return False
496
497         system = None
498         try:
499             int(vat[0:2])
500             system = 'old'
501         except:
502             system = 'new'
503
504         if system == 'old':
505             check = ((int(vat[2:11]) * 100) + 12) % 97
506             if check != int(vat[0:2]):
507                 return False
508             return True
509         else:
510             conv = ['0', '1', '2', '3', '4', '5', '6', '7',
511                 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
512                 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T',
513                 'U', 'V', 'W', 'X', 'Y', 'Z']
514             if vat[0] not in conv \
515                     or vat[1] not in conv:
516                 return False
517             c1 = conv.index(vat[0])
518             c2 = conv.index(vat[1])
519
520             if c1 < 10:
521                 sum = c1 * 24 + c2 - 10
522             else:
523                 sum = c1 * 34 + c2 - 100
524
525             x = sum % 11
526             sum = (int(sum) / 11) + 1
527             y = (int(vat[2:11]) + sum) % 11
528             if x != y:
529                 return False
530             return True
531
532     def check_vat_gb(self, vat):
533         '''
534         Check United Kingdom VAT number.
535         '''
536
537         if len(vat) == 5:
538             try:
539                 int(vat[2:5])
540             except:
541                 return False
542
543             if vat[0:2] == 'GD':
544                 if int(vat[2:5]) >= 500:
545                     return False
546                 return True
547             if vat[0:2] == 'HA':
548                 if int(vat[2:5]) < 500:
549                     return False
550                 return True
551             return False
552         elif len(vat) in (9, 10):
553             try:
554                 int(vat)
555             except:
556                 return False
557
558             if int(vat[0:7]) < 1:
559                 return False
560             if int(vat[0:7]) > 19999 and int(vat[0:7]) < 1000000:
561                 return False
562             if int(vat[7:9]) > 97:
563                 return False
564             if len(vat) == 10 and int(vat[9]) != 3:
565                 return False
566
567             sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \
568                     5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \
569                     2 * int(vat[6]) + 10 * int(vat[7]) + int(vat[8])
570             if int(vat[0:3]) > 100:
571                 if sum % 97 not in (0, 55, 42):
572                     return False
573             else:
574                 if sum % 97 != 0:
575                     return False
576             return True
577         elif len(vat) in (12, 13):
578             try:
579                 int(vat)
580             except:
581                 return False
582
583             if int(vat[0:3]) not in (0, 1):
584                 return False
585
586             if int(vat[3:10]) < 1:
587                 return False
588             if int(vat[3:10]) > 19999 and int(vat[3:10]) < 1000000:
589                 return False
590             if int(vat[10:12]) > 97:
591                 return False
592             if len(vat) == 13 and int(vat[12]) != 3:
593                 return False
594
595             sum = 8 * int(vat[3]) + 7 * int(vat[4]) + 6 * int(vat[5]) + \
596                     5 * int(vat[6]) + 4 * int(vat[7]) + 3 * int(vat[8]) + \
597                     2 * int(vat[9]) + 10 * int(vat[10]) + int(vat[11])
598             if sum % 97 != 0:
599                 return False
600             return True
601         return False
602
603     def check_vat_gr(self, vat):
604         '''
605         Check Greece VAT number.
606         '''
607         try:
608             int(vat)
609         except:
610             return False
611         if len(vat) == 8:
612             sum = 128 * int(vat[0]) + 64 * int(vat[1]) + 32 * int(vat[2]) + \
613                     16 * int(vat[3]) + 8 * int(vat[4]) + 4 * int(vat[5]) + \
614                     2 * int(vat[6])
615             check = sum % 11
616             if check == 10:
617                 check = 0
618             if check != int(vat[7]):
619                 return False
620             return True
621         elif len(vat) == 9:
622             sum = 256 * int(vat[0]) + 128 * int(vat[1]) + 64 * int(vat[2]) + \
623                     32 * int(vat[3]) + 16 * int(vat[4]) + 8 * int(vat[5]) + \
624                     4 * int(vat[6]) + 2 * int(vat[7])
625             check = sum % 11
626             if check == 10:
627                 check = 0
628             if check != int(vat[8]):
629                 return False
630             return True
631         return False
632
633     def check_vat_el(self, vat):
634         return self.check_vat_gr(vat)
635
636     def check_vat_hu(self, vat):
637         '''
638         Check Hungary VAT number.
639         '''
640         if len(vat) != 8:
641             return False
642         try:
643             int(vat)
644         except:
645             return False
646         if int(vat[0]) <= 0:
647             return False
648         sum = 9 * int(vat[0]) + 7 * int(vat[1]) + 3 * int(vat[2]) + \
649                 1 * int(vat[3]) + 9 * int(vat[4]) + 7 * int(vat[5]) + \
650                 3 * int(vat[6])
651         check = 10 - (sum % 10)
652         if check == 10:
653             check = 0
654         if check != int(vat[7]):
655             return False
656         return True
657
658     def check_vat_ie(self, vat):
659         '''
660         Check Ireland VAT number.
661         '''
662         if len(vat) != 8:
663             return False
664         if (ord(vat[1]) >= 65 and ord(vat[1]) <= 90) \
665                 or vat[1] in ('+', '*'):
666             try:
667                 int(vat[0])
668                 int(vat[2:7])
669             except:
670                 return False
671
672             if int(vat[0]) <= 6:
673                 return False
674
675             sum = 7 * int(vat[2]) + 6 * int(vat[3]) + 5 * int(vat[4]) + \
676                     4 * int(vat[5]) + 3 * int(vat[6]) + 2 * int(vat[0])
677             check = sum % 23
678             if check == 0:
679                 check = 'W'
680             else:
681                 check = chr(check + 64)
682             if check != vat[7]:
683                 return False
684             return True
685         else:
686             try:
687                 int(vat[0:7])
688             except:
689                 return False
690
691             sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \
692                     5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \
693                     2 * int(vat[6])
694             check = sum % 23
695             if check == 0:
696                 check = 'W'
697             else:
698                 check = chr(check + 64)
699             if check != vat[7]:
700                 return False
701             return True
702
703     def check_vat_it(self, vat):
704         '''
705         Check Italy VAT number.
706         '''
707         if len(vat) != 11:
708             return False
709         try:
710             int(vat)
711         except:
712             return False
713         if int(vat[0:7]) <= 0:
714             return False
715         if int(vat[7:10]) <= 0:
716             return False
717         if int(vat[7:10]) > 100 and int(vat[7:10]) < 120:
718             return False
719
720         sum = int(vat[0]) + mult_add(2, int(vat[1])) + int(vat[2]) + \
721                 mult_add(2, int(vat[3])) + int(vat[4]) + \
722                 mult_add(2, int(vat[5])) + int(vat[6]) + \
723                 mult_add(2, int(vat[7])) + int(vat[8]) + \
724                 mult_add(2, int(vat[9]))
725         check = 10 - (sum % 10)
726         if check == 10:
727             check = 0
728         if check != int(vat[10]):
729             return False
730         return True
731
732     def check_vat_lt(self, vat):
733         '''
734         Check Lithuania VAT number.
735         '''
736         try:
737             int(vat)
738         except:
739             return False
740
741         if len(vat) == 9:
742             if int(vat[7]) != 1:
743                 return False
744             sum = 1 * int(vat[0]) + 2 * int(vat[1]) + 3 * int(vat[2]) + \
745                     4 * int(vat[3]) + 5 * int(vat[4]) + 6 * int(vat[5]) + \
746                     7 * int(vat[6]) + 8 * int(vat[7])
747             if sum % 11 == 10:
748                 sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 5 * int(vat[2]) + \
749                         6 * int(vat[3]) + 7 * int(vat[4]) + 8 * int(vat[5]) + \
750                         9 * int(vat[6]) + 1 * int(vat[7])
751             check = sum % 11
752             if check == 10:
753                 check = 0
754             if check != int(vat[8]):
755                 return False
756             return True
757         elif len(vat) == 12:
758             if int(vat[10]) != 1:
759                 return False
760             sum = 1 * int(vat[0]) + 2 * int(vat[1]) + 3 * int(vat[2]) + \
761                     4 * int(vat[3]) + 5 * int(vat[4]) + 6 * int(vat[5]) + \
762                     7 * int(vat[6]) + 8 * int(vat[7]) + 9 * int(vat[8]) + \
763                     1 * int(vat[9]) + 2 * int(vat[10])
764             if sum % 11 == 10:
765                 sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 5 * int(vat[2]) + \
766                         6 * int(vat[3]) + 7 * int(vat[4]) + 8 * int(vat[5]) + \
767                         9 * int(vat[6]) + 1 * int(vat[7]) + 2 * int(vat[8]) + \
768                         3 * int(vat[9]) + 4 * int(vat[10])
769             check = sum % 11
770             if check == 10:
771                 check = 0
772             if check != int(vat[11]):
773                 return False
774             return True
775         return False
776
777     def check_vat_lu(self, vat):
778         '''
779         Check Luxembourg VAT number.
780         '''
781         if len(vat) != 8:
782             return False
783         try:
784             int(vat)
785         except:
786             return False
787         if int(vat[0:6]) <= 0:
788             return False
789         check = int(vat[0:6]) % 89
790         if check != int(vat[6:8]):
791             return False
792         return True
793
794     def check_vat_lv(self, vat):
795         '''
796         Check Latvia VAT number.
797         '''
798         if len(vat) != 11:
799             return False
800         try:
801             int(vat)
802         except:
803             return False
804         if int(vat[0]) >= 4:
805             sum = 9 * int(vat[0]) + 1 * int(vat[1]) + 4 * int(vat[2]) + \
806                     8 * int(vat[3]) + 3 * int(vat[4]) + 10 * int(vat[5]) + \
807                     2 * int(vat[6]) + 5 * int(vat[7]) + 7 * int(vat[8]) + \
808                     6 * int(vat[9])
809             if sum % 11 == 4 and int(vat[0]) == 9:
810                 sum = sum - 45
811             if sum % 11 == 4:
812                 check = 4 - (sum % 11)
813             elif sum % 11 > 4:
814                 check = 14 - (sum % 11)
815             elif sum % 11 < 4:
816                 check = 3 - (sum % 11)
817             if check != int(vat[10]):
818                 return False
819             return True
820         else:
821             if int(vat[2:4]) == 2 and int(vat[4:6]) % 4 > 0:
822                 if int(vat[0:2]) < 1 or int(vat[0:2]) > 28:
823                     return False
824             if int(vat[2:4]) == 2 and int(vat[4:6]) % 4 == 0:
825                 if int(vat[0:2]) < 1 or int(vat[0:2]) > 29:
826                     return False
827             if int(vat[2:4]) in (4, 6, 9, 11):
828                 if int(vat[0:2]) < 1 or int(vat[0:2]) > 30:
829                     return False
830             if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12):
831                 if int(vat[0:2]) < 1 or int(vat[0:2]) > 31:
832                     return False
833             if int(vat[2:4]) < 1 or int(vat[2:4]) > 12:
834                 return False
835             return True
836
837     def check_vat_mt(self, vat):
838         '''
839         Check Malta VAT number.
840         '''
841         if len(vat) != 8:
842             return False
843         try:
844             int(vat)
845         except:
846             return False
847
848         if int(vat[0:6]) < 100000:
849             return False
850
851         sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 6 * int(vat[2]) + \
852                 7 * int(vat[3]) + 8 * int(vat[4]) + 9 * int(vat[5])
853         check = 37 - (sum % 37)
854         if check != int(vat[6:8]):
855             return False
856         return True
857
858     def check_vat_nl(self, vat):
859         '''
860         Check Netherlands VAT number.
861         '''
862         if len(vat) != 12:
863             return False
864         try:
865             int(vat[0:9])
866             int(vat[10:12])
867         except:
868             return False
869         if int(vat[0:8]) <= 0:
870             return False
871         if vat[9] != 'B':
872             return False
873
874         sum = 9 * int(vat[0]) + 8 * int(vat[1]) + 7 * int(vat[2]) + \
875                 6 * int(vat[3]) + 5 * int(vat[4]) + 4 * int(vat[5]) + \
876                 3 * int(vat[6]) + 2 * int(vat[7])
877
878         check = sum % 11
879         if check == 10:
880             return False
881         if check != int(vat[8]):
882             return False
883         return True
884
885     def check_vat_pl(self, vat):
886         '''
887         Check Poland VAT number.
888         '''
889         if len(vat) != 10:
890             return False
891         try:
892             int(vat)
893         except:
894             return False
895
896         sum = 6 * int(vat[0]) + 5 * int(vat[1]) + 7 * int(vat[2]) + \
897                 2 * int(vat[3]) + 3 * int(vat[4]) + 4 * int(vat[5]) + \
898                 5 * int(vat[6]) + 6 * int(vat[7]) + 7 * int(vat[8])
899         check = sum % 11
900         if check == 10:
901             return False
902         if check != int(vat[9]):
903             return False
904         return True
905
906     def check_vat_pt(self, vat):
907         '''
908         Check Portugal VAT number.
909         '''
910         if len(vat) != 9:
911             return False
912         try:
913             int(vat)
914         except:
915             return False
916
917         if int(vat[0]) <= 0:
918             return False
919
920         sum = 9 * int(vat[0]) + 8 * int(vat[1]) + 7 * int(vat[2]) + \
921                 6 * int(vat[3]) + 5 * int(vat[4]) + 4 * int(vat[5]) + \
922                 3 * int(vat[6]) + 2 * int(vat[7])
923         check = 11 - (sum % 11)
924         if check == 10 or check == 11:
925             check = 0
926         return True
927
928     def check_vat_ro(self, vat):
929         '''
930         Check Romania VAT number.
931         '''
932         try:
933             int(vat)
934         except:
935             return False
936
937         if len(vat) >= 2 and len(vat) <= 10:
938             vat = (10 - len(vat)) * '0' + vat
939             sum = 7 * int(vat[0]) + 5 * int(vat[1]) + 3 * int(vat[2]) + \
940                     2 * int(vat[3]) + 1 * int(vat[4]) + 7 * int(vat[5]) + \
941                     5 * int(vat[6]) + 3 * int(vat[7]) + 2 * int(vat[8])
942             check = (sum * 10) % 11
943             if check == 10:
944                 check = 0
945             if check != int(vat[9]):
946                 return False
947             return True
948         elif len(vat) == 13:
949             if int(vat[0]) not in (1, 2, 3, 4, 6):
950                 return False
951             if int(vat[3:5]) < 1 or int(vat[3:5]) > 12:
952                 return False
953             if int(vat[3:5]) == 2 and int(vat[1:3]) % 4 > 0:
954                 if int(vat[5:7]) < 1 or int(vat[5:7]) > 28:
955                     return False
956             if int(vat[3:5]) == 2 and int(vat[1:3]) % 4 == 0:
957                 if int(vat[5:7]) < 1 or int(vat[5:7]) > 29:
958                     return False
959             if int(vat[3:5]) in (4, 6, 9, 11):
960                 if int(vat[5:7]) < 1 or int(vat[5:7]) > 30:
961                     return False
962             if int(vat[3:5]) in (1, 3, 5, 7, 8, 10, 12):
963                 if int(vat[5:7]) < 1 or int(vat[5:7]) > 31:
964                     return False
965
966             sum = 2 * int(vat[0]) + 7 * int(vat[1]) + 9 * int(vat[2]) + \
967                     1 * int(vat[3]) + 4 * int(vat[4]) + 6 * int(vat[5]) + \
968                     3 * int(vat[6]) + 5 * int(vat[7]) + 8 * int(vat[8]) + \
969                     2 * int(vat[9]) + 7 * int(vat[10]) + 9 * int(vat[11])
970             check = sum % 11
971             if check == 10:
972                 check = 1
973             if check != int(vat[12]):
974                 return False
975             return True
976         return False
977
978     def check_vat_se(self, vat):
979         '''
980         Check Sweden VAT number.
981         '''
982         if len(vat) != 12:
983             return False
984         try:
985             int(vat)
986         except:
987             return False
988
989         if int(vat[9:11]) < 0:
990             return False
991
992         sum = mult_add(2, int(vat[0])) + int(vat[1]) + \
993                 mult_add(2, int(vat[2])) + int(vat[3]) + \
994                 mult_add(2, int(vat[4])) + int(vat[5]) + \
995                 mult_add(2, int(vat[6])) + int(vat[7]) + \
996                 mult_add(2, int(vat[8]))
997         check = 10 - (sum % 10)
998         if check == 10:
999             check = 0
1000         if check != int(vat[9]):
1001             return False
1002         return True
1003
1004     def check_vat_si(self, vat):
1005         '''
1006         Check Slovenia VAT number.
1007         '''
1008         if len(vat) != 8:
1009             return False
1010         try:
1011             int(vat)
1012         except:
1013             return False
1014         if int(vat[0:7]) <= 999999:
1015             return False
1016
1017         sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \
1018                 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \
1019                 2 * int(vat[6])
1020         check = 11 - (sum % 11)
1021         if check == 10:
1022             check = 0
1023         if check == 11:
1024             check = 1
1025         if check != int(vat[7]):
1026             return False
1027         return True
1028
1029     def check_vat_sk(self, vat):
1030         '''
1031         Check Slovakia VAT number.
1032         '''
1033         try:
1034             int(vat)
1035         except:
1036             return False
1037         if len(vat) not in(9, 10):
1038             return False
1039
1040         if int(vat[0:2]) in (0, 10, 20) and len(vat) == 10:
1041             return True
1042
1043         if len(vat) == 10:
1044             if int(vat[0:2]) < 54 or int(vat[0:2]) > 99:
1045                 return False
1046
1047         if len(vat) == 9:
1048             if int(vat[0:2]) > 53 :
1049                 return False
1050
1051         if int(vat[2:4]) < 1:
1052             return False
1053         if int(vat[2:4]) > 12 and int(vat[2:4]) < 51:
1054             return False
1055         if int(vat[2:4]) > 62:
1056             return False
1057         if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0:
1058             if int(vat[4:6]) < 1 or int(vat[4:6]) > 28:
1059                 return False
1060         if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0:
1061             if int(vat[4:6]) < 1 or int(vat[4:6]) > 29:
1062                 return False
1063         if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61):
1064             if int(vat[4:6]) < 1 or int(vat[4:6]) > 30:
1065                 return False
1066         if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12,
1067                 51, 53, 55, 57, 58, 60, 62):
1068             if int(vat[4:6]) < 1 or int(vat[4:6]) > 31:
1069                 return False
1070         return True
1071
1072     __check_vat_mx_re = re.compile(r"(?P<primeras>[A-Za-z\xd1\xf1&]{3,4})" \
1073                                     r"[ \-_]?" \
1074                                     r"(?P<ano>[0-9]{2})(?P<mes>[01][0-9])(?P<dia>[0-3][0-9])" \
1075                                     r"[ \-_]?" \
1076                                     r"(?P<code>[A-Za-z0-9&\xd1\xf1]{3})$")
1077     
1078     def check_vat_mx(self, vat):
1079         ''' Mexican VAT verification
1080         
1081         Verificar RFC México
1082         '''
1083         # we convert to 8-bit encoding, to help the regex parse only bytes
1084         vat = ustr(vat).encode('iso8859-1')
1085         m = self.__check_vat_mx_re.match(vat)
1086         if not m:
1087             #No valid format
1088             return False
1089         try:
1090             ano = int(m.group('ano'))
1091             if ano > 30:
1092                 ano = 1900 + ano
1093             else:
1094                 ano = 2000 + ano
1095             datetime.date(ano, int(m.group('mes')), int(m.group('dia')))
1096         except ValueError:
1097             return False
1098         
1099         #Valid format and valid date
1100         return True
1101         
1102 res_partner()
1103
1104 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: