web/lib/django/contrib/localflavor/kw/forms.py
changeset 29 cc9b7e14412b
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
       
     1 """
       
     2 Kuwait-specific Form helpers
       
     3 """
       
     4 import re
       
     5 from datetime import date
       
     6 
       
     7 from django.core.validators import EMPTY_VALUES
       
     8 from django.forms import ValidationError
       
     9 from django.forms.fields import Field, RegexField
       
    10 from django.utils.translation import gettext as _
       
    11 
       
    12 id_re = re.compile(r'^(?P<initial>\d{1})(?P<yy>\d\d)(?P<mm>\d\d)(?P<dd>\d\d)(?P<mid>\d{4})(?P<checksum>\d{1})')
       
    13 
       
    14 class KWCivilIDNumberField(Field):
       
    15     """
       
    16     Kuwaiti Civil ID numbers are 12 digits, second to seventh digits
       
    17     represents the person's birthdate.
       
    18 
       
    19     Checks the following rules to determine the validty of the number:
       
    20         * The number consist of 12 digits.
       
    21         * The birthdate of the person is a valid date.
       
    22         * The calculated checksum equals to the last digit of the Civil ID.
       
    23     """
       
    24     default_error_messages = {
       
    25         'invalid': _('Enter a valid Kuwaiti Civil ID number'),
       
    26     }
       
    27 
       
    28     def has_valid_checksum(self, value):
       
    29         weight = (2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
       
    30         calculated_checksum = 0
       
    31         for i in range(11):
       
    32             calculated_checksum += int(value[i]) * weight[i]
       
    33 
       
    34         remainder = calculated_checksum % 11
       
    35         checkdigit = 11 - remainder
       
    36         if checkdigit != int(value[11]):
       
    37             return False
       
    38         return True
       
    39 
       
    40     def clean(self, value):
       
    41         super(KWCivilIDNumberField, self).clean(value)
       
    42         if value in EMPTY_VALUES:
       
    43             return u''
       
    44 
       
    45         if not re.match(r'^\d{12}$', value):
       
    46             raise ValidationError(self.error_messages['invalid'])
       
    47 
       
    48         match = re.match(id_re, value)
       
    49 
       
    50         if not match:
       
    51             raise ValidationError(self.error_messages['invalid'])
       
    52 
       
    53         gd = match.groupdict()
       
    54 
       
    55         try:
       
    56             d = date(int(gd['yy']), int(gd['mm']), int(gd['dd']))
       
    57         except ValueError:
       
    58             raise ValidationError(self.error_messages['invalid'])
       
    59 
       
    60         if not self.has_valid_checksum(value):
       
    61             raise ValidationError(self.error_messages['invalid'])
       
    62 
       
    63         return value