Code

Ticket #11217: localflavor.hu.diff

File localflavor.hu.diff, 7.2 KB (added by nagyv, 5 years ago)

Hungarian localflavor patch

Line 
1Index: django/contrib/localflavor/ro/forms.py
2===================================================================
3--- django/contrib/localflavor/ro/forms.py      (revision 10844)
4+++ django/contrib/localflavor/ro/forms.py      (working copy)
5@@ -8,6 +8,7 @@
6 from django.forms import ValidationError, Field, RegexField, Select
7 from django.forms.fields import EMPTY_VALUES
8 from django.utils.translation import ugettext_lazy as _
9+from django.contrib.localflavor.generic.util import validate_iban
10 
11 class ROCIFField(RegexField):
12     """
13@@ -150,20 +151,10 @@
14         Strips - and spaces, performs country code and checksum validation
15         """
16         value = super(ROIBANField, self).clean(value)
17-        value = value.replace('-','')
18-        value = value.replace(' ','')
19-        value = value.upper()
20-        if value[0:2] != 'RO':
21+        if validate_iban(value, 20):
22+            return value
23+        else:
24             raise ValidationError(self.error_messages['invalid'])
25-        numeric_format = ''
26-        for char in value[4:] + value[0:4]:
27-            if char.isalpha():
28-                numeric_format += str(ord(char) - 55)
29-            else:
30-                numeric_format += char
31-        if int(numeric_format) % 97 != 1:
32-            raise ValidationError(self.error_messages['invalid'])
33-        return value
34 
35 class ROPhoneNumberField(RegexField):
36     """Romanian phone number field"""
37Index: django/contrib/localflavor/generic/util.py
38===================================================================
39--- django/contrib/localflavor/generic/util.py  (revision 0)
40+++ django/contrib/localflavor/generic/util.py  (revision 0)
41@@ -0,0 +1,25 @@
42+def validate_iban(value, length):
43+    '''
44+    Validate an International Bank Account Number (IBAN)
45+   
46+    Based on
47+    * http://en.wikipedia.org/wiki/International_Bank_Account_Number#Calculating_and_validating_IBAN_checksums
48+    * and django.contrib.localflavor.ro.ROIBANField
49+   
50+    @param value: the value to check
51+    @param length: the length of the BBAN specific to each country
52+    '''
53+    value = value.replace('-', '')
54+    value = value.replace('', '')
55+    if not len(value) == length:
56+        return False
57+   
58+    value = value.upper()
59+    for char in value[4:] + value[0:4]:
60+        if char.isalpha():
61+            numeric_format += str(ord(char) - 55)
62+        else:
63+            numeric_format += char
64+    if int(numeric_format) % 97 != 1:
65+        return False
66+    return value
67\ No newline at end of file
68Index: django/contrib/localflavor/hu/__init__.py
69===================================================================
70Index: django/contrib/localflavor/hu/forms.py
71===================================================================
72--- django/contrib/localflavor/hu/forms.py      (revision 0)
73+++ django/contrib/localflavor/hu/forms.py      (revision 0)
74@@ -0,0 +1,93 @@
75+# -*- coding: utf-8 -*
76+"""
77+IT-specific Form helpers
78+"""
79+
80+from django.forms import ValidationError
81+from django.forms.fields import Field, RegexField, Select, EMPTY_VALUES
82+from django.utils.translation import ugettext_lazy as _
83+from django.utils.encoding import smart_unicode
84+from django.contrib.localflavor.generic.util import validate_iban
85+import re
86+
87+class HUZipCodeField(RegexField):
88+    default_error_messages = {
89+        'invalid': _('Enter a valid zip code.'),
90+    }
91+    def __init__(self, *args, **kwargs):
92+        super(HUZipCodeField, self).__init__(r'^\d{4}$',
93+        max_length=None, min_length=None, *args, **kwargs)
94+
95+class HUVatNumberField(Field):
96+    """
97+    A form field that validates Hungarian VAT numbers (adószám).
98+    """
99+    default_error_messages = {
100+        'invalid': _(u'Enter a valid VAT number.'),
101+    }
102+
103+    def clean(self, value):
104+        value = super(HUVatNumberField, self).clean(value)
105+        if value == u'':
106+            return value
107+        try:
108+            vat_number = int(value)
109+        except ValueError:
110+            raise ValidationError(self.error_messages['invalid'])
111+       
112+        if not len(vat_number) == 11:
113+            raise ValidationError(self.error_messages['invalid'])
114+        elif not vat_number[9] in (1,2,3):
115+            raise ValidationError(self.error_messages['invalid'])
116+        return smart_unicode(vat_number)
117+   
118+class HUIBANField(RegexField):
119+    '''
120+    A form field that validates Hungarian IBAN codes
121+   
122+    Format: HUkk BBBB BBBC CCCC CCCC CCCC CCCC
123+        B = bank code, C = account No.
124+    '''
125+    default_error_messages = {
126+          'invalid': _('Enter a valid IBAN number in the format HUkk XXXX XXXX XXXX XXXX XXXX XXXX'),
127+      }
128+    def __init__(self, *args, **kwargs):
129+        super(HUIBANField, self).__init__(r'^HU[0-9-\s]{26,30}$',
130+            max_length=32, min_length=28, *args, **kwargs)
131+
132+    def clean(self, value):
133+        '''
134+        Strips unnecessary values, and perform checksum validation
135+        '''
136+        value = super(HUIBANField, self).clean(value)
137+        if validate_iban(value, 24):
138+            return value
139+        else:
140+            raise ValidationError(self.error_messages['invalid'])
141+
142+class HUPhoneNumberField(RegexField):
143+    '''
144+    A form field to represent Hungarian phone numbers
145+    '''
146+    default_error_messages = {
147+      'invalid': _('Enter a valid phone number. E.g. 1/234-5678')
148+      }
149+    def __init__(self, *args, **kwargs):
150+        super(HUPhoneNumberField, self).__init__(r'^\d{8,15}$',
151+             max_length=16, min_length=7, *args, **kwargs)
152+       
153+    def clean(self, value):
154+        '''
155+        Strip 06, whitespaces, dashes
156+        '''
157+        value = super(HUPhoneNumberField, self).clean(value)
158+        value = value.replace(' ', '')
159+        value = value.replace('-', '')
160+        value = value.replace('/', '')
161+        value = value[:2] == '06' and value[2:] or value
162+        # mobile phone numbers might have 8 digits
163+        if not len(value) == 8: # Bp: 1+7, other: 2+6
164+            raise ValidationError(self.error_messages['invalid'])
165+        elif len(value) == 10 and value[:2] not in (20, 30, 70, 71):
166+            raise ValidationError(self.error_messages['invalid'])
167+        return value
168Index: docs/ref/contrib/localflavor.txt
169===================================================================
170--- docs/ref/contrib/localflavor.txt    (revision 10844)
171+++ docs/ref/contrib/localflavor.txt    (working copy)
172@@ -48,6 +48,7 @@
173     * Finland_
174     * France_
175     * Germany_
176+    * Hungary_
177     * Iceland_
178     * India_
179     * Italy_
180@@ -88,6 +89,7 @@
181 .. _Finland: `Finland (fi)`_
182 .. _France: `France (fr)`_
183 .. _Germany: `Germany (de)`_
184+.. _Hungary: `Hungary (hu`_
185 .. _The Netherlands: `The Netherlands (nl)`_
186 .. _Iceland: `Iceland (is\_)`_
187 .. _India: `India (in\_)`_
188@@ -308,7 +310,26 @@
189 .. class:: de.forms.DEStateSelect
190 
191     A ``Select`` widget that uses a list of German states as its choices.
192+   
193+Hungary (``hu``)
194+================
195 
196+.. class:: hu.forms.HUZipCodeField
197+
198+       A form field to check Hungarian ZIP codes. They should be 4 digits long.
199+       
200+.. class:: hu.forms.HUVatNumberField
201+
202+       A form field to check Hungarian VAT numbers (adószám).
203+       
204+.. class:: hu.forms.HUIBANField
205+
206+       A form field to check Hungarian IBAN numbers.
207+       
208+.. class:: hu.forms.HUPhoneNumberField
209+
210+       A form field to check Hungarian phone numbers.
211+
212 The Netherlands (``nl``)
213 ========================
214