From 8770f80e9539bb4b9b2c909951eefd92bf5e4312 Mon Sep 17 00:00:00 2001 From: Burhan Khalid Date: Sat, 5 Nov 2016 15:17:30 +0100 Subject: [PATCH 1/2] merge upstream --- localflavor/kw/forms.py | 58 ++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/localflavor/kw/forms.py b/localflavor/kw/forms.py index c55b937c1..7d50d5868 100644 --- a/localflavor/kw/forms.py +++ b/localflavor/kw/forms.py @@ -3,25 +3,39 @@ """ from __future__ import unicode_literals +import textwrap 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.forms.fields import RegexField, Select from django.utils.translation import gettext_lazy as _ from .kw_governorates import GOVERNORATE_CHOICES -id_re = re.compile(r'''^(?P\d{1}) +id_re = re.compile(r'''^(?P\d) (?P\d\d) (?P\d\d) (?P
\d\d) (?P\d{4}) - (?P\d{1})''', re.VERBOSE) + (?P\d)''', re.VERBOSE) -class KWCivilIDNumberField(Field): +def is_valid_kw_civilid_checksum(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 + + +class KWCivilIDNumberField(RegexField): """ Kuwaiti Civil ID numbers are 12 digits, second to seventh digits represents the person's birthdate. @@ -35,43 +49,32 @@ class KWCivilIDNumberField(Field): '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 __init__(self, max_length=12, min_length=12, *args, **kwargs): + super(KWCivilIDNumberField, self).__init__(r'\d{12}', + max_length, + min_length, *args, **kwargs) 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() + cc = value[0] # Century value + yy, mm, dd = textwrap.wrap(value[1:7], 2) # Date parts # 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']) + if int(cc) == 3: + yy = '20{}'.format(yy) + elif int(cc) == 2: + yy = '19{}'.format(yy) try: - date(int(gd['yy']), int(gd['mm']), int(gd['dd'])) + date(int(yy), int(mm), int(dd)) except ValueError: raise ValidationError(self.error_messages['invalid']) - if not self.has_valid_checksum(value): + if not is_valid_kw_civilid_checksum(value): raise ValidationError(self.error_messages['invalid']) return value @@ -82,6 +85,7 @@ 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) From 9f6922ff30d000330ba145de2da275ef67feb24b Mon Sep 17 00:00:00 2001 From: Burhan Khalid Date: Sat, 5 Nov 2016 15:41:47 +0100 Subject: [PATCH 2/2] sorting imports --- localflavor/kw/forms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/localflavor/kw/forms.py b/localflavor/kw/forms.py index 7d50d5868..9ebeda331 100644 --- a/localflavor/kw/forms.py +++ b/localflavor/kw/forms.py @@ -3,8 +3,8 @@ """ from __future__ import unicode_literals -import textwrap import re +import textwrap from datetime import date from django.core.validators import EMPTY_VALUES @@ -14,6 +14,7 @@ from .kw_governorates import GOVERNORATE_CHOICES + id_re = re.compile(r'''^(?P\d) (?P\d\d) (?P\d\d)