app/django/contrib/localflavor/nl/forms.py
changeset 54 03e267d67478
child 323 ff1a9aa48cfd
equal deleted inserted replaced
53:57b4279d8c4e 54:03e267d67478
       
     1 """
       
     2 NL-specific Form helpers
       
     3 """
       
     4 
       
     5 import re
       
     6 
       
     7 from django.newforms import ValidationError
       
     8 from django.newforms.fields import Field, Select, EMPTY_VALUES
       
     9 from django.utils.translation import ugettext as _
       
    10 from django.utils.encoding import smart_unicode
       
    11 
       
    12 pc_re = re.compile('^\d{4}[A-Z]{2}$')
       
    13 sofi_re = re.compile('^\d{9}$')
       
    14 numeric_re = re.compile('^\d+$')
       
    15 
       
    16 class NLZipCodeField(Field):
       
    17     """
       
    18     A Dutch postal code field.
       
    19     """
       
    20     default_error_messages = {
       
    21         'invalid': _('Enter a valid postal code'),
       
    22     }
       
    23 
       
    24     def clean(self, value):
       
    25         super(NLZipCodeField, self).clean(value)
       
    26         if value in EMPTY_VALUES:
       
    27             return u''
       
    28 
       
    29         value = value.strip().upper().replace(' ', '')
       
    30         if not pc_re.search(value):
       
    31             raise ValidationError(self.error_messages['invalid'])
       
    32 
       
    33         if int(value[:4]) < 1000:
       
    34             raise ValidationError(self.error_messages['invalid'])
       
    35 
       
    36         return u'%s %s' % (value[:4], value[4:])
       
    37 
       
    38 class NLProvinceSelect(Select):
       
    39     """
       
    40     A Select widget that uses a list of provinces of the Netherlands as its
       
    41     choices.
       
    42     """
       
    43     def __init__(self, attrs=None):
       
    44         from nl_provinces import PROVINCE_CHOICES
       
    45         super(NLProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
       
    46 
       
    47 class NLPhoneNumberField(Field):
       
    48     """
       
    49     A Dutch telephone number field.
       
    50     """
       
    51     default_error_messages = {
       
    52         'invalid': _('Enter a valid phone number'),
       
    53     }
       
    54 
       
    55     def clean(self, value):
       
    56         super(NLPhoneNumberField, self).clean(value)
       
    57         if value in EMPTY_VALUES:
       
    58             return u''
       
    59 
       
    60         phone_nr = re.sub('[\-\s\(\)]', '', smart_unicode(value))
       
    61 
       
    62         if len(phone_nr) == 10 and numeric_re.search(phone_nr):
       
    63             return value
       
    64 
       
    65         if phone_nr[:3] == '+31' and len(phone_nr) == 12 and \
       
    66            numeric_re.search(phone_nr[3:]):
       
    67             return value
       
    68 
       
    69         raise ValidationError(self.error_messages['invalid'])
       
    70 
       
    71 class NLSoFiNumberField(Field):
       
    72     """
       
    73     A Dutch social security number (SoFi/BSN) field.
       
    74 
       
    75     http://nl.wikipedia.org/wiki/Sofinummer
       
    76     """
       
    77     default_error_messages = {
       
    78         'invalid': _('Enter a valid SoFi number'),
       
    79     }
       
    80 
       
    81     def clean(self, value):
       
    82         super(NLSoFiNumberField, self).clean(value)
       
    83         if value in EMPTY_VALUES:
       
    84             return u''
       
    85 
       
    86         if not sofi_re.search(value):
       
    87             raise ValidationError(self.error_messages['invalid'])
       
    88 
       
    89         if int(value) == 0:
       
    90             raise ValidationError(self.error_messages['invalid'])
       
    91 
       
    92         checksum = 0
       
    93         for i in range(9, 1, -1):
       
    94             checksum += int(value[9-i]) * i
       
    95         checksum -= int(value[-1])
       
    96 
       
    97         if checksum % 11 != 0:
       
    98             raise ValidationError(self.error_messages['invalid'])
       
    99 
       
   100         return value