From f6309cbf8058b77729f9ba96c26accdbb7ae5596 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Fri, 10 Apr 2009 01:03:44 +0000 Subject: [PATCH] Fixed #8515 -- Fixed validation of Polish REGON numbers. Patch from Piotr Lewandowski. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10460 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/localflavor/pl/forms.py | 39 ++++++++----------- tests/regressiontests/forms/localflavor/pl.py | 12 +++++- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/django/contrib/localflavor/pl/forms.py b/django/contrib/localflavor/pl/forms.py index ee362fcd6d..b908580568 100644 --- a/django/contrib/localflavor/pl/forms.py +++ b/django/contrib/localflavor/pl/forms.py @@ -100,20 +100,18 @@ class PLNIPField(RegexField): class PLREGONField(RegexField): """ - A form field that validated as Polish National Official Business Register - Number (REGON). Valid numbers contain 7 or 9 digits. + A form field that validates its input is a REGON number. - More on the field: http://www.stat.gov.pl/bip/regon_ENG_HTML.htm - - The checksum algorithm is documented at http://wipos.p.lodz.pl/zylla/ut/nip-rego.html + Valid regon number consists of 9 or 14 digits. + See http://www.stat.gov.pl/bip/regon_ENG_HTML.htm for more information. """ default_error_messages = { - 'invalid': _(u'National Business Register Number (REGON) consists of 7 or 9 digits.'), + 'invalid': _(u'National Business Register Number (REGON) consists of 9 or 14 digits.'), 'checksum': _(u'Wrong checksum for the National Business Register Number (REGON).'), } def __init__(self, *args, **kwargs): - super(PLREGONField, self).__init__(r'^\d{7,9}$', + super(PLREGONField, self).__init__(r'^\d{9,14}$', max_length=None, min_length=None, *args, **kwargs) def clean(self,value): @@ -126,25 +124,20 @@ class PLREGONField(RegexField): """ Calculates a checksum with the provided algorithm. """ - multiple_table_7 = (2, 3, 4, 5, 6, 7) - multiple_table_9 = (8, 9, 2, 3, 4, 5, 6, 7) - result = 0 + weights = ( + (8, 9, 2, 3, 4, 5, 6, 7, -1), + (2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8, -1), + (8, 9, 2, 3, 4, 5, 6, 7, -1, 0, 0, 0, 0, 0), + ) - if len(number) == 7: - multiple_table = multiple_table_7 - else: - multiple_table = multiple_table_9 + weights = [table for table in weights if len(table) == len(number)] - for i in range(len(number)-1): - result += int(number[i]) * multiple_table[i] + for table in weights: + checksum = sum([int(n) * w for n, w in zip(number, table)]) + if checksum % 11 % 10: + return False - result %= 11 - if result == 10: - result = 0 - if result == int(number[-1]): - return True - else: - return False + return bool(weights) class PLPostalCodeField(RegexField): """ diff --git a/tests/regressiontests/forms/localflavor/pl.py b/tests/regressiontests/forms/localflavor/pl.py index ce6ccda81a..52f1305ca8 100644 --- a/tests/regressiontests/forms/localflavor/pl.py +++ b/tests/regressiontests/forms/localflavor/pl.py @@ -67,8 +67,18 @@ ValidationError: [u'National Identification Number consists of 11 digits.'] >>> from django.contrib.localflavor.pl.forms import PLREGONField >>> f = PLREGONField() +>>> f.clean('12345678512347') +u'12345678512347' >>> f.clean('590096454') u'590096454' +>>> f.clean('123456784') +Traceback (most recent call last): +... +ValidationError: [u'Wrong checksum for the National Business Register Number (REGON).'] +>>> f.clean('12345678412342') +Traceback (most recent call last): +... +ValidationError: [u'Wrong checksum for the National Business Register Number (REGON).'] >>> f.clean('590096453') Traceback (most recent call last): ... @@ -76,6 +86,6 @@ ValidationError: [u'Wrong checksum for the National Business Register Number (RE >>> f.clean('590096') Traceback (most recent call last): ... -ValidationError: [u'National Business Register Number (REGON) consists of 7 or 9 digits.'] +ValidationError: [u'National Business Register Number (REGON) consists of 9 or 14 digits.'] """