Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add field for greek Social Security Number (AMKA) #337

Merged
merged 7 commits into from
Jul 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ New flavors:
New fields for existing flavors:

- `NLLicensePlateField` in NL flavor.
- `GRSocialSecurityNumberField` (AMKA) in GR flavore

Modifications to existing flavors:

Expand Down
44 changes: 44 additions & 0 deletions localflavor/gr/forms.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
"""Greek-specific forms helpers."""
import datetime
import re

from django.core.validators import EMPTY_VALUES
from django.forms import Field, RegexField, ValidationError
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _

from localflavor.generic.checksums import luhn


class GRPostalCodeField(RegexField):
"""
Expand Down Expand Up @@ -60,3 +63,44 @@ def clean(self, value):
if mod != check:
raise ValidationError(self.error_messages['invalid'])
return val


class GRSocialSecurityNumberCodeField(RegexField):
"""
Greek social security number (AMKA) field.

The allow_test_value option can be used to enable the usage of the
non valid 00000000000 (11 zeros) value for testing and development
"""

default_error_messages = {
'invalid': _('Enter a valid greek social security number (AMKA - 11 digits).'),
}

def __init__(self, allow_test_value=False, *args, **kwargs):
self.allow_test_value = allow_test_value
super(GRSocialSecurityNumberCodeField, self).__init__(r'^[0-9\s\-]+$', *args, **kwargs)

def check_date(self, val):
try:
datetime.datetime.strptime(val[:6], '%d%m%y')
except:
raise ValidationError(self.error_messages['invalid'])

def clean(self, value):
super(GRSocialSecurityNumberCodeField, self).clean(value)
if value in self.empty_values:
return self.empty_value
val = re.sub('[\-\s]', '', force_text(value))
if not val or len(val) < 11:
raise ValidationError(self.error_messages['invalid'])
if self.allow_test_value and val == '00000000000':
return val
if not all(char.isdigit() for char in val):
raise ValidationError(self.error_messages['invalid'])

self.check_date(val)
if not luhn(val):
raise ValidationError(self.error_messages['invalid'])

return val
24 changes: 23 additions & 1 deletion tests/test_gr.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.test import SimpleTestCase

from localflavor.gr.forms import GRPostalCodeField, GRTaxNumberCodeField
from localflavor.gr.forms import GRPostalCodeField, GRSocialSecurityNumberCodeField, GRTaxNumberCodeField


class GRLocalFlavorTests(SimpleTestCase):
Expand Down Expand Up @@ -52,3 +52,25 @@ def test_GRPostalCodeField(self):
'b231a': error,
}
self.assertFieldOutput(GRPostalCodeField, valid, invalid)

def test_GRSocialSecurityNumberCodeField(self):
"""It's not easy finding valid AMKAs in the internet, these were created by hand"""
error = ['Enter a valid greek social security number (AMKA - 11 digits).']

valid = {
'20107201921': '20107201921',
'14059202672': '14059202672',
'03059302467': '03059302467',
}

invalid = {
'20207201920': error,
'12345678901': error,
'ab345678901': error,
'00000000000': error,
'1': error,
'123': error,
'aaa': error,
}
self.assertFieldOutput(GRSocialSecurityNumberCodeField, valid, invalid)
self.assertFieldOutput(GRSocialSecurityNumberCodeField, {'00000000000': '00000000000',}, {}, field_kwargs={'allow_test_value': True})