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