|
1 """ |
|
2 Polish-specific form helpers |
|
3 """ |
|
4 |
|
5 import re |
|
6 |
|
7 from django.newforms import ValidationError |
|
8 from django.newforms.fields import Select, RegexField |
|
9 from django.utils.translation import ugettext as _ |
|
10 |
|
11 class PLVoivodeshipSelect(Select): |
|
12 """ |
|
13 A select widget with list of Polish voivodeships (administrative provinces) |
|
14 as choices. |
|
15 """ |
|
16 def __init__(self, attrs=None): |
|
17 from pl_voivodeships import VOIVODESHIP_CHOICES |
|
18 super(PLVoivodeshipSelect, self).__init__(attrs, choices=VOIVODESHIP_CHOICES) |
|
19 |
|
20 class PLAdministrativeUnitSelect(Select): |
|
21 """ |
|
22 A select widget with list of Polish administrative units as choices. |
|
23 """ |
|
24 def __init__(self, attrs=None): |
|
25 from pl_administrativeunits import ADMINISTRATIVE_UNIT_CHOICES |
|
26 super(PLAdministrativeUnitSelect, self).__init__(attrs, choices=ADMINISTRATIVE_UNIT_CHOICES) |
|
27 |
|
28 class PLNationalIdentificationNumberField(RegexField): |
|
29 """ |
|
30 A form field that validates as Polish Identification Number (PESEL). |
|
31 |
|
32 Checks the following rules: |
|
33 * the length consist of 11 digits |
|
34 * has a valid checksum |
|
35 |
|
36 The algorithm is documented at http://en.wikipedia.org/wiki/PESEL. |
|
37 """ |
|
38 default_error_messages = { |
|
39 'invalid': _(u'National Identification Number consists of 11 digits.'), |
|
40 'checksum': _(u'Wrong checksum for the National Identification Number.'), |
|
41 } |
|
42 |
|
43 def __init__(self, *args, **kwargs): |
|
44 super(PLNationalIdentificationNumberField, self).__init__(r'^\d{11}$', |
|
45 max_length=None, min_length=None, *args, **kwargs) |
|
46 |
|
47 def clean(self,value): |
|
48 super(PLNationalIdentificationNumberField, self).clean(value) |
|
49 if not self.has_valid_checksum(value): |
|
50 raise ValidationError(self.error_messages['checksum']) |
|
51 return u'%s' % value |
|
52 |
|
53 def has_valid_checksum(self, number): |
|
54 """ |
|
55 Calculates a checksum with the provided algorithm. |
|
56 """ |
|
57 multiple_table = (1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1) |
|
58 result = 0 |
|
59 for i in range(len(number)): |
|
60 result += int(number[i]) * multiple_table[i] |
|
61 return result % 10 == 0 |
|
62 |
|
63 class PLTaxNumberField(RegexField): |
|
64 """ |
|
65 A form field that validates as Polish Tax Number (NIP). |
|
66 Valid forms are: XXX-XXX-YY-YY or XX-XX-YYY-YYY. |
|
67 |
|
68 Checksum algorithm based on documentation at |
|
69 http://wipos.p.lodz.pl/zylla/ut/nip-rego.html |
|
70 """ |
|
71 default_error_messages = { |
|
72 'invalid': _(u'Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX.'), |
|
73 'checksum': _(u'Wrong checksum for the Tax Number (NIP).'), |
|
74 } |
|
75 |
|
76 def __init__(self, *args, **kwargs): |
|
77 super(PLTaxNumberField, self).__init__(r'^\d{3}-\d{3}-\d{2}-\d{2}$|^\d{2}-\d{2}-\d{3}-\d{3}$', |
|
78 max_length=None, min_length=None, *args, **kwargs) |
|
79 |
|
80 def clean(self,value): |
|
81 super(PLTaxNumberField, self).clean(value) |
|
82 value = re.sub("[-]", "", value) |
|
83 if not self.has_valid_checksum(value): |
|
84 raise ValidationError(self.error_messages['checksum']) |
|
85 return u'%s' % value |
|
86 |
|
87 def has_valid_checksum(self, number): |
|
88 """ |
|
89 Calculates a checksum with the provided algorithm. |
|
90 """ |
|
91 multiple_table = (6, 5, 7, 2, 3, 4, 5, 6, 7) |
|
92 result = 0 |
|
93 for i in range(len(number)-1): |
|
94 result += int(number[i]) * multiple_table[i] |
|
95 |
|
96 result %= 11 |
|
97 if result == int(number[-1]): |
|
98 return True |
|
99 else: |
|
100 return False |
|
101 |
|
102 class PLNationalBusinessRegisterField(RegexField): |
|
103 """ |
|
104 A form field that validated as Polish National Official Business Register Number (REGON) |
|
105 Valid forms are: 7 or 9 digits number |
|
106 |
|
107 More on the field: http://www.stat.gov.pl/bip/regon_ENG_HTML.htm |
|
108 |
|
109 The checksum algorithm is documented at http://wipos.p.lodz.pl/zylla/ut/nip-rego.html |
|
110 """ |
|
111 default_error_messages = { |
|
112 'invalid': _(u'National Business Register Number (REGON) consists of 7 or 9 digits.'), |
|
113 'checksum': _(u'Wrong checksum for the National Business Register Number (REGON).'), |
|
114 } |
|
115 |
|
116 def __init__(self, *args, **kwargs): |
|
117 super(PLNationalBusinessRegisterField, self).__init__(r'^\d{7,9}$', |
|
118 max_length=None, min_length=None, *args, **kwargs) |
|
119 |
|
120 def clean(self,value): |
|
121 super(PLNationalBusinessRegisterField, self).clean(value) |
|
122 if not self.has_valid_checksum(value): |
|
123 raise ValidationError(self.error_messages['checksum']) |
|
124 return u'%s' % value |
|
125 |
|
126 def has_valid_checksum(self, number): |
|
127 """ |
|
128 Calculates a checksum with the provided algorithm. |
|
129 """ |
|
130 multiple_table_7 = (2, 3, 4, 5, 6, 7) |
|
131 multiple_table_9 = (8, 9, 2, 3, 4, 5, 6, 7) |
|
132 result = 0 |
|
133 |
|
134 if len(number) == 7: |
|
135 multiple_table = multiple_table_7 |
|
136 else: |
|
137 multiple_table = multiple_table_9 |
|
138 |
|
139 for i in range(len(number)-1): |
|
140 result += int(number[i]) * multiple_table[i] |
|
141 |
|
142 result %= 11 |
|
143 if result == 10: |
|
144 result = 0 |
|
145 if result == int(number[-1]): |
|
146 return True |
|
147 else: |
|
148 return False |
|
149 |
|
150 class PLPostalCodeField(RegexField): |
|
151 """ |
|
152 A form field that validates as Polish postal code. |
|
153 Valid code is XX-XXX where X is digit. |
|
154 """ |
|
155 default_error_messages = { |
|
156 'invalid': _(u'Enter a postal code in the format XX-XXX.'), |
|
157 } |
|
158 |
|
159 def __init__(self, *args, **kwargs): |
|
160 super(PLPostalCodeField, self).__init__(r'^\d{2}-\d{3}$', |
|
161 max_length=None, min_length=None, *args, **kwargs) |