|
1 """ |
|
2 AT-specific Form helpers |
|
3 """ |
|
4 |
|
5 import re |
|
6 |
|
7 from django.utils.translation import ugettext_lazy as _ |
|
8 from django.forms.fields import Field, RegexField, Select |
|
9 from django.forms import ValidationError |
|
10 |
|
11 re_ssn = re.compile(r'^\d{4} \d{6}') |
|
12 |
|
13 class ATZipCodeField(RegexField): |
|
14 """ |
|
15 A form field that validates its input is an Austrian postcode. |
|
16 |
|
17 Accepts 4 digits. |
|
18 """ |
|
19 default_error_messages = { |
|
20 'invalid': _('Enter a zip code in the format XXXX.'), |
|
21 } |
|
22 def __init__(self, *args, **kwargs): |
|
23 super(ATZipCodeField, self).__init__(r'^\d{4}$', |
|
24 max_length=None, min_length=None, *args, **kwargs) |
|
25 |
|
26 class ATStateSelect(Select): |
|
27 """ |
|
28 A Select widget that uses a list of AT states as its choices. |
|
29 """ |
|
30 def __init__(self, attrs=None): |
|
31 from django.contrib.localflavor.at.at_states import STATE_CHOICES |
|
32 super(ATStateSelect, self).__init__(attrs, choices=STATE_CHOICES) |
|
33 |
|
34 class ATSocialSecurityNumberField(Field): |
|
35 """ |
|
36 Austrian Social Security numbers are composed of a 4 digits and 6 digits |
|
37 field. The latter represents in most cases the person's birthdate while |
|
38 the first 4 digits represent a 3-digits counter and a one-digit checksum. |
|
39 |
|
40 The 6-digits field can also differ from the person's birthdate if the |
|
41 3-digits counter suffered an overflow. |
|
42 |
|
43 This code is based on information available on |
|
44 http://de.wikipedia.org/wiki/Sozialversicherungsnummer#.C3.96sterreich |
|
45 """ |
|
46 |
|
47 default_error_messages = { |
|
48 'invalid': _(u'Enter a valid Austrian Social Security Number in XXXX XXXXXX format.'), |
|
49 } |
|
50 |
|
51 def clean(self, value): |
|
52 if not re_ssn.search(value): |
|
53 raise ValidationError(self.error_messages['invalid']) |
|
54 sqnr, date = value.split(" ") |
|
55 sqnr, check = (sqnr[:3], (sqnr[3])) |
|
56 if int(sqnr) < 100: |
|
57 raise ValidationError(self.error_messages['invalid']) |
|
58 res = int(sqnr[0])*3 + int(sqnr[1])*7 + int(sqnr[2])*9 \ |
|
59 + int(date[0])*5 + int(date[1])*8 + int(date[2])*4 \ |
|
60 + int(date[3])*2 + int(date[4])*1 + int(date[5])*6 |
|
61 res = res % 11 |
|
62 if res != int(check): |
|
63 raise ValidationError(self.error_messages['invalid']) |
|
64 return u'%s%s %s'%(sqnr, check, date,) |
|
65 |