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