Ticket #8515: regon-validation.patch

File regon-validation.patch, 3.8 KB (added by Piotr Lewandowski <django@…>, 16 years ago)
  • django/contrib/localflavor/pl/forms.py

     
    100100
    101101class PLREGONField(RegexField):
    102102    """
    103     A form field that validated as Polish National Official Business Register
    104     Number (REGON). Valid numbers contain 7 or 9 digits.
     103    A form field that validates its input is a REGON number.
    105104
    106     More on the field: http://www.stat.gov.pl/bip/regon_ENG_HTML.htm
    107 
    108     The checksum algorithm is documented at http://wipos.p.lodz.pl/zylla/ut/nip-rego.html
     105    Valid regon number consists of 9 or 14 digits.
     106    See http://www.stat.gov.pl/bip/regon_ENG_HTML.htm for more information.
    109107    """
    110108    default_error_messages = {
    111         'invalid': _(u'National Business Register Number (REGON) consists of 7 or 9 digits.'),
     109        'invalid': _(u'National Business Register Number (REGON) consists of 9 or 14 digits.'),
    112110        'checksum': _(u'Wrong checksum for the National Business Register Number (REGON).'),
    113111    }
    114112
    115113    def __init__(self, *args, **kwargs):
    116         super(PLREGONField, self).__init__(r'^\d{7,9}$',
     114        super(PLREGONField, self).__init__(r'^\d{9,14}$',
    117115            max_length=None, min_length=None, *args, **kwargs)
    118116
    119117    def clean(self,value):
    120118        super(PLREGONField, self).clean(value)
    121119        if not self.has_valid_checksum(value):
    122120            raise ValidationError(self.error_messages['checksum'])
    123         return u'%s' % value
     121        return unicode(value)
    124122
    125123    def has_valid_checksum(self, number):
    126124        """
    127125        Calculates a checksum with the provided algorithm.
    128126        """
    129         multiple_table_7 = (2, 3, 4, 5, 6, 7)
    130         multiple_table_9 = (8, 9, 2, 3, 4, 5, 6, 7)
    131         result = 0
     127        weights = (
     128            (8, 9, 2, 3, 4, 5, 6, 7, -1),
     129            (2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8, -1),
     130            (8, 9, 2, 3, 4, 5, 6, 7, -1, 0, 0, 0, 0, 0),
     131        )
    132132
    133         if len(number) == 7:
    134             multiple_table = multiple_table_7
    135         else:
    136             multiple_table = multiple_table_9
     133        weights = [table for table in weights if len(table) == len(number)]
    137134
    138         for i in range(len(number)-1):
    139             result += int(number[i]) * multiple_table[i]
     135        for table in weights:
     136            checksum = sum([int(n) * w for n, w in zip(number, table)])
     137            if checksum % 11 % 10 != 0:
     138                return False
    140139
    141         result %= 11
    142         if result == 10:
    143             result = 0
    144         if result  == int(number[-1]):
    145             return True
    146         else:
    147             return False
     140        return bool(weights)
    148141
    149142class PLPostalCodeField(RegexField):
    150143    """
  • tests/regressiontests/forms/localflavor/pl.py

     
    6767
    6868>>> from django.contrib.localflavor.pl.forms import PLREGONField
    6969>>> f = PLREGONField()
     70>>> f.clean('12345678512347')
     71u'12345678512347'
    7072>>> f.clean('590096454')
    7173u'590096454'
     74>>> f.clean('123456784')
     75Traceback (most recent call last):
     76...
     77ValidationError: [u'Wrong checksum for the National Business Register Number (REGON).']
     78>>> f.clean('12345678412342')
     79Traceback (most recent call last):
     80...
     81ValidationError: [u'Wrong checksum for the National Business Register Number (REGON).']
    7282>>> f.clean('590096453')
    7383Traceback (most recent call last):
    7484...
     
    7686>>> f.clean('590096')
    7787Traceback (most recent call last):
    7888...
    79 ValidationError: [u'National Business Register Number (REGON) consists of 7 or 9 digits.']
     89ValidationError: [u'National Business Register Number (REGON) consists of 9 or 14 digits.']
    8090
    8191"""
Back to Top