Ticket #14400: django-lv.diff

File django-lv.diff, 8.2 KB (added by Kristaps Kūlis, 14 years ago)
  • django/contrib/localflavor/lv/models.py

     
     1# needed for some testing, see ticket #7198
  • django/contrib/localflavor/lv/forms.py

     
     1# encoding: utf-8
     2import time
     3import re
     4
     5from django.forms import ValidationError
     6from django.forms.fields import CharField, RegexField
     7from django.utils.translation import ugettext_lazy as _
     8
     9identity_number_digits_re = re.compile(r'^(\d{11})$')
     10
     11class LVPhoneField(RegexField):
     12   
     13    default_error_messages = {
     14        'invalid': _('Phone numbers must be in XXXXXXXX format.'),
     15    }
     16    def __init__(self, *args, **kwargs):
     17        super(LVPhoneField, self).__init__(r'^(\d{8})$',
     18            max_length=None, min_length=None, *args, **kwargs)
     19
     20class LVPostalCodeField(RegexField):
     21    default_error_messages = {
     22        'invalid' : _('Postal code fields must be in LV-XXXX format')
     23    }
     24    def __init__(self, *args, **kwargs):
     25        super(LVPostalCodeField, self).__init__(r'LV-(\d{4})$',
     26                max_length = None, min_length = None, *args, **kwargs)
     27
     28class LVIdentityNumberField(CharField):
     29    """
     30        Latvian identity number field.
     31        Checks following rules that number is valid:
     32        - first 6 digits form valid date
     33        - conforms form XXXXXX-XXXXX
     34        - last digit is valid checksum
     35            algorithm for validation
     36            (1101 – (1*PK[1] + 6*PK[2] + 3*PK[3] + 7*PK[4] + 9*PK[5] + 10*PK[6] + 5*PK[7] + 8*PK[8] + 4*PK[9] + 2*PK[10])) mod 11
     37    """
     38    default_error_messages = {
     39        'invalid':  _('Identity numbers must be in XXXXXX-XXXXX format')
     40    }
     41    def clean(self, value):
     42        super(LVIdentityNumberField, self).clean(value)
     43        date = value[:6]
     44        meta = value[7:]
     45        value = date+ meta
     46        if not identity_number_digits_re.match(value):
     47            raise ValidationError(self.error_messages['invalid'])
     48        try:
     49            time.strptime(date, "%d%m%y")
     50        except ValueError:
     51            raise ValidationError(self.error_messages['invalid'])
     52        def calculate_checksum(code):
     53            """ common knownledge algorithm for calculating identity number checksum """
     54            checksum = 0
     55            validation_data = [1,6,3,7,9,10,5,8,4,2]
     56            for i in xrange(0, 10):
     57                checksum += int(code[i]) * validation_data[i]
     58            checksum =  (1101 - checksum) % 11
     59            return checksum
     60        if calculate_checksum(value) != int(value[10]):
     61            raise ValidationError(self.error_messages['invalid'])
     62        return value
  • tests/regressiontests/forms/tests.py

     
    3131from localflavor.us import tests as localflavor_us_tests
    3232from localflavor.uy import tests as localflavor_uy_tests
    3333from localflavor.za import tests as localflavor_za_tests
     34from localflavor.lv import *
    3435from regressions import tests as regression_tests
    3536from util import tests as util_tests
    3637from widgets import tests as widgets_tests
  • tests/regressiontests/forms/localflavor/lv.py

     
     1import unittest
     2from django.forms import ValidationError
     3from django.contrib.localflavor.lv.forms import LVPhoneField
     4from django.contrib.localflavor.lv.forms import LVPostalCodeField
     5from django.contrib.localflavor.lv.forms import LVIdentityNumberField
     6
     7class LVPhoneFieldTestCase(unittest.TestCase):
     8    """ test LVPhone field """
     9    def test_valid(self):
     10        """ test valid phone number """
     11        field = LVPhoneField()
     12        self.assertEquals(field.clean("27175629"), "27175629")
     13    def test_invalid(self):
     14        """ test invalid phone number """
     15        field = LVPhoneField()
     16        self.assertRaises(ValidationError, field.clean, "7175629")
     17
     18
     19class LVIdentityNumberFieldTestCase(unittest.TestCase):
     20    def setUp(self):
     21        self.field = LVIdentityNumberField()
     22    def test_valid(self):
     23        """
     24        test valid identity number field un publicly known identity number of
     25        Aivars Lembergs
     26        """
     27        self.assertEquals(self.field.clean("260953-11667"), "26095311667")
     28    def test_with_invalid_date_and_valid_checksum(self):
     29        """ test with invalid date and valid checksum """
     30        self.assertRaises(ValidationError, self.field.clean, "300290-11545")
     31    def test_with_valid_date_and_invalid_checksum(self):
     32        """ ValidationError on valid date and invalid checksum """
     33        self.assertRaises(ValidationError, self.field.clean, "251278-11634")
     34    def test_with_characters_inside(self):
     35        """ test that identity should fail if it contains characters """
     36        self.assertRaises(ValidationError, self.field.clean, "abcdef-12145")
     37    def test_length_validation(self):
     38        self.assertRaises(ValidationError, self.field.clean, "080690-111711")
     39        self.assertRaises(ValidationError, self.field.clean, "080690-1177")
     40       
     41class LVPostalCodeFieldTestCase(unittest.TestCase):
     42    def setUp(self):
     43        self.field = LVPostalCodeField()
     44    def test_with_invalid_prefix(self):
     45        """ all postal code`s have prefix LV """
     46        self.assertRaises(ValidationError, self.field.clean, "LR-1024")
     47    def test_with_invalid_code(self):
     48        """ all postal codes contain prefix, dash and numbers """
     49        self.assertRaises(ValidationError, self.field.clean, "LV-10S3")
     50    def test_with_invalid_digits(self):
     51        """ there is just 4 digits """
     52        self.assertRaises(ValidationError, self.field.clean, "LV-10244")
     53        self.assertRaises(ValidationError, self.field.clean, "LV-102")
     54    def test_valid(self):
     55        self.assertEqual(self.field.clean("LV-1024"), "LV-1024")
     56       
  • AUTHORS

     
    517517    Gasper Zejn <zejn@kiberpipa.org>
    518518    Jarek Zgoda <jarek.zgoda@gmail.com>
    519519    Cheng Zhang
     520    Kristaps Kulis <Kristaps.Kulis@Gmail.com>
    520521
    521522A big THANK YOU goes to:
    522523
  • docs/ref/contrib/localflavor.txt

     
    5353    * Italy_
    5454    * Japan_
    5555    * Kuwait_
     56    * Latvia_
    5657    * Mexico_
    5758    * `The Netherlands`_
    5859    * Norway_
     
    100101.. _Italy: `Italy (it)`_
    101102.. _Japan: `Japan (jp)`_
    102103.. _Kuwait: `Kuwait (kw)`_
     104.. _Latvia: `Latvia (lv)`_
    103105.. _Mexico: `Mexico (mx)`_
    104106.. _Norway: `Norway (no)`_
    105107.. _Peru: `Peru (pe)`_
     
    468470    * The birthdate of the person is a valid date.
    469471    * The calculated checksum equals to the last digit of the Civil ID.
    470472
     473Latvia (``lv``)
     474===============
     475.. class:: lv.forms.LVPhoneField
     476
     477    A form field that validates input as Latvian phone number. A valid phone
     478    number must consist of 8 digits
     479
     480.. class:: lv.forms.LVPostalCodeField
     481
     482    A form field that validates input as Latvian postal code number. A valid
     483    postal code number must start with LV- and contain 4 digits
     484
     485.. class:: lv.forms.LVIdentityNumberField
     486
     487    A form field that validates input as Latvian identity number. A valid identity
     488    number must obey the following rules:
     489
     490    * The number starts with 6 digits, followed by dash and then 5 digits
     491    * The first 6 digits form valid birthdate of person
     492    * The last digit equals to calculated checksum
     493
    471494Mexico (``mx``)
    472495===============
    473496
Back to Top