Ticket #15713: localflavor_pl_id_card.diff

File localflavor_pl_id_card.diff, 5.0 KB (added by xtrqt, 4 years ago)

Patch with docs and tests

  • django/contrib/localflavor/pl/forms.py

    diff --git a/django/contrib/localflavor/pl/forms.py b/django/contrib/localflavor/pl/forms.py
    index d1e9773..3bbc1ba 100644
    a b class PLPESELField(RegexField): 
    6262            result += int(number[i]) * multiple_table[i]
    6363        return result % 10 == 0
    6464
     65class PLNationalIDCardNumberField(RegexField):
     66    """
     67    A form field that validates as Polish National ID Card Number.
     68
     69    Checks the following rules:
     70        * the length consist of 3 letter and 6 digits
     71        * has a valid checksum
     72
     73    The algorithm is documented at http://en.wikipedia.org/wiki/Polish_identity_card.
     74    """
     75    default_error_messages = {
     76        'invalid': _(u'National ID Card Number consists of 3 letters and 6 digits.'),
     77        'checksum': _(u'Wrong checksum for the National ID Card Number.'),
     78    }
     79
     80    def __init__(self, *args, **kwargs):
     81        super(PLNationalIDCardNumberField, self).__init__(r'^[A-Za-z]{3}\d{6}$',
     82            max_length=None, min_length=None, *args, **kwargs)
     83
     84    def clean(self,value):
     85        super(PLNationalIDCardNumberField, self).clean(value)
     86        if value in EMPTY_VALUES:
     87            return u''
     88           
     89        value = value.upper()
     90           
     91        if not self.has_valid_checksum(value):
     92            raise ValidationError(self.error_messages['checksum'])
     93        return u'%s' % value
     94
     95    def has_valid_checksum(self, number):
     96        """
     97        Calculates a checksum with the provided algorithm.
     98        """
     99        letter_dict = {'A': 10, 'B': 11, 'C': 12, 'D': 13,
     100                       'E': 14, 'F': 15, 'G': 16, 'H': 17,
     101                       'I': 18, 'J': 19, 'K': 20, 'L': 21,
     102                       'M': 22, 'N': 23, 'O': 24, 'P': 25,
     103                       'Q': 26, 'R': 27, 'S': 28, 'T': 29,
     104                       'U': 30, 'V': 31, 'W': 32, 'X': 33,
     105                       'Y': 34, 'Z': 35}
     106       
     107        # convert letters to integer values
     108        int_table = [(not c.isdigit()) and letter_dict[c] or int(c) \
     109                     for c in number]
     110               
     111        multiple_table = (7, 3, 1, -1, 7, 3, 1, 7, 3)
     112        result = 0
     113        for i in range(len(int_table)):
     114            result += int_table[i] * multiple_table[i]
     115       
     116        return result % 10 == 0
     117
     118       
    65119class PLNIPField(RegexField):
    66120    """
    67121    A form field that validates as Polish Tax Number (NIP).
    class PLPostalCodeField(RegexField): 
    158212    def __init__(self, *args, **kwargs):
    159213        super(PLPostalCodeField, self).__init__(r'^\d{2}-\d{3}$',
    160214            max_length=None, min_length=None, *args, **kwargs)
     215
  • docs/ref/contrib/localflavor.txt

    diff --git a/docs/ref/contrib/localflavor.txt b/docs/ref/contrib/localflavor.txt
    index f54341e..90a4da4 100644
    a b Poland (``pl``) 
    628628
    629629.. _PESEL: http://en.wikipedia.org/wiki/PESEL
    630630
     631.. class:: pl.forms.PLNationalIDCardNumberField
     632
     633    A form field that validates input as a Polish National ID Card number. The
     634    valid format is AAAXXXXXX, where A is letter (A-Z), X is digit and left-most
     635    digit is checksum digit. More information about checksum calculation algorithm
     636    see `Polish identity card`_.
     637   
     638
     639.. _`Polish identity card`: http://en.wikipedia.org/wiki/Polish_identity_card
     640
    631641.. class:: pl.forms.PLREGONField
    632642
    633643    A form field that validates input as a Polish National Official Business
  • tests/regressiontests/forms/localflavor/pl.py

    diff --git a/tests/regressiontests/forms/localflavor/pl.py b/tests/regressiontests/forms/localflavor/pl.py
    index 51721f8..e13a20f 100644
    a b  
    11from django.contrib.localflavor.pl.forms import (PLProvinceSelect,
    2     PLCountySelect, PLPostalCodeField, PLNIPField, PLPESELField, PLREGONField)
     2    PLCountySelect, PLPostalCodeField, PLNIPField, PLPESELField, PLNationalIDCardNumberField, PLREGONField)
    33
    44from utils import LocalFlavorTestCase
    55
    class PLLocalFlavorTests(LocalFlavorTestCase): 
    445445        }
    446446        self.assertFieldOutput(PLPESELField, valid, invalid)
    447447   
     448    def test_PLNationalIDCardNumberField(self):
     449        error_checksum = [u'Wrong checksum for the National ID Card Number.']
     450        error_format = [u'National ID Card Number consists of 3 letters and 6 digits.']
     451        valid = {
     452            'ABC123458': 'ABC123458',
     453            'abc123458': 'ABC123458',
     454        }
     455        invalid = {
     456            'ABC123457': error_checksum,
     457            'abc123457': error_checksum,
     458            'a12Aaaaaa': error_format,
     459            'AA1234443': error_format,
     460        }
     461        self.assertFieldOutput(PLNationalIDCardNumberField, valid, invalid)
     462   
     463   
    448464    def test_PLREGONField(self):
    449465        error_checksum = [u'Wrong checksum for the National Business Register Number (REGON).']
    450466        error_format = [u'National Business Register Number (REGON) consists of 9 or 14 digits.']
Back to Top