Source code for localflavor.kw.forms
"""
Kuwait-specific Form helpers
"""
from __future__ import unicode_literals
import re
from datetime import date
from django.core.validators import EMPTY_VALUES
from django.forms import ValidationError
from django.forms.fields import Field, Select
from django.utils.translation import gettext_lazy as _
from .kw_governorates import GOVERNORATE_CHOICES
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})''', re.VERBOSE)
[docs]class KWCivilIDNumberField(Field):
"""
Kuwaiti Civil ID numbers are 12 digits, second to seventh digits
represents the person's birthdate.
Checks the following rules to determine the validty of the number:
* The number consist of 12 digits.
* The birthdate of the person is a valid date.
* The calculated checksum equals to the last digit of the Civil ID.
"""
default_error_messages = {
'invalid': _('Enter a valid Kuwaiti Civil ID number'),
}
def has_valid_checksum(self, value):
weight = (2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
calculated_checksum = 0
for i in range(11):
calculated_checksum += int(value[i]) * weight[i]
remainder = calculated_checksum % 11
checkdigit = 11 - remainder
if checkdigit != int(value[11]):
return False
return True
def clean(self, value):
super(KWCivilIDNumberField, self).clean(value)
if value in EMPTY_VALUES:
return ''
match = re.match(id_re, value)
if not match:
raise ValidationError(self.error_messages['invalid'])
gd = match.groupdict()
# Fix the dates so that those born
# in 2000+ pass the validation check
if int(value[0]) == 3:
gd['yy'] = '20{}'.format(gd['yy'])
elif int(value[0]) == 2:
gd['yy'] = '19{}'.format(gd['yy'])
try:
date(int(gd['yy']), int(gd['mm']), int(gd['dd']))
except ValueError:
raise ValidationError(self.error_messages['invalid'])
if not self.has_valid_checksum(value):
raise ValidationError(self.error_messages['invalid'])
return value
[docs]class KWGovernorateSelect(Select):
"""
A Select widget that uses a list of Kuwait governorates
as its choices.
"""
def __init__(self, attrs=None):
super(KWGovernorateSelect, self).__init__(attrs,
choices=GOVERNORATE_CHOICES)