diff options
Diffstat (limited to 'stdnum')
-rw-r--r-- | stdnum/bg/egn.py | 56 | ||||
-rw-r--r-- | stdnum/bg/pnf.py | 37 | ||||
-rw-r--r-- | stdnum/bg/vat.py | 48 |
3 files changed, 94 insertions, 47 deletions
diff --git a/stdnum/bg/egn.py b/stdnum/bg/egn.py index d704543..7f94946 100644 --- a/stdnum/bg/egn.py +++ b/stdnum/bg/egn.py @@ -1,7 +1,7 @@ # egn.py - functions for handling Bulgarian national identification numbers # coding: utf-8 # -# Copyright (C) 2012 Arthur de Jong +# Copyright (C) 2012, 2013 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -27,18 +27,23 @@ digit. >>> compact('752316 926 3') '7523169263' ->>> is_valid('8032056031') -True +>>> validate('8032056031') +'8032056031' >>> get_birth_date('7542011030') datetime.date(2075, 2, 1) ->>> is_valid('7552010004') # invalid check digit -False ->>> is_valid('8019010008') # invalid date -False +>>> validate('7552A10004') # invalid digit +Traceback (most recent call last): + ... +InvalidFormat: ... +>>> validate('8019010008') # invalid date +Traceback (most recent call last): + ... +InvalidComponent: ... """ import datetime +from stdnum.exceptions import * from stdnum.util import clean @@ -66,24 +71,35 @@ def get_birth_date(number): elif month > 20: year -= 100 month -= 20 - return datetime.date(year, month, day) + try: + return datetime.date(year, month, day) + except ValueError: + raise InvalidComponent() -def is_valid(number): +def validate(number): """Checks to see if the number provided is a valid national identification number. This checks the length, formatting, embedded date and check digit.""" - try: - number = compact(number) - except: - return False - if not number.isdigit() or len(number) != 10: - return False + number = compact(number) + if not number.isdigit(): + raise InvalidFormat() + if len(number) != 10: + raise InvalidLength() # check if birth date is valid + birth_date = get_birth_date(number) + # TODO: check that the birth date is not in the future + # check the check digit + if calc_check_digit(number[:-1]) != number[-1]: + raise InvalidChecksum() + return number + + +def is_valid(number): + """Checks to see if the number provided is a valid national + identification number. This checks the length, formatting, embedded + date and check digit.""" try: - birth_date = get_birth_date(number) - # TODO: check that the birth date is not in the future - except ValueError: + return bool(validate(number)) + except ValidationError: return False - # check the check digit - return calc_check_digit(number[:-1]) == number[-1] diff --git a/stdnum/bg/pnf.py b/stdnum/bg/pnf.py index e03d33a..bddfb2b 100644 --- a/stdnum/bg/pnf.py +++ b/stdnum/bg/pnf.py @@ -1,7 +1,7 @@ # pnf.py - functions for handling Bulgarian personal number of a foreigner # coding: utf-8 # -# Copyright (C) 2012 Arthur de Jong +# Copyright (C) 2012, 2013 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -23,14 +23,19 @@ The personal number of a foreigner is a 10-digit number where the last digit is the result of a weighted checksum. ->>> compact('7111 042 925') +>>> validate('7111 042 925') '7111042925' ->>> is_valid('7111042925') -True ->>> is_valid('7111042922') # invalid check digit -False +>>> validate('7111042922') # invalid check digit +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> validate('71110A2922') # invalid digit +Traceback (most recent call last): + ... +InvalidFormat: ... """ +from stdnum.exceptions import * from stdnum.util import clean @@ -47,13 +52,25 @@ def calc_check_digit(number): return str(sum(weights[i] * int(n) for i, n in enumerate(number)) % 10) +def validate(number): + """Checks to see if the number provided is a valid national + identification number. This checks the length, formatting, embedded + date and check digit.""" + number = compact(number) + if not number.isdigit(): + raise InvalidFormat() + if len(number) != 10: + raise InvalidLength() + if calc_check_digit(number[:-1]) != number[-1]: + raise InvalidChecksum() + return number + + def is_valid(number): """Checks to see if the number provided is a valid national identification number. This checks the length, formatting, embedded date and check digit.""" try: - number = compact(number) - except: + return bool(validate(number)) + except ValidationError: return False - return number.isdigit() and len(number) == 10 and \ - calc_check_digit(number[:-1]) == number[-1] diff --git a/stdnum/bg/vat.py b/stdnum/bg/vat.py index 644af68..e04141d 100644 --- a/stdnum/bg/vat.py +++ b/stdnum/bg/vat.py @@ -1,7 +1,7 @@ # vat.py - functions for handling Bulgarian VAT numbers # coding: utf-8 # -# Copyright (C) 2012 Arthur de Jong +# Copyright (C) 2012, 2013 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -26,14 +26,17 @@ others) long. Each type of number has it's own check digit algorithm. >>> compact('BG 175 074 752') '175074752' ->>> is_valid('175074752') -True ->>> is_valid('175074751') # invalid check digit -False +>>> validate('175074752') +'175074752' +>>> validate('175074751') # invalid check digit +Traceback (most recent call last): + ... +InvalidChecksum: ... """ -from stdnum.util import clean from stdnum.bg import egn, pnf +from stdnum.exceptions import * +from stdnum.util import clean def compact(number): @@ -61,19 +64,30 @@ def calc_check_digit_other(number): return str((11 - sum(weights[i] * int(n) for i, n in enumerate(number))) % 11) +def validate(number): + """Checks to see if the number provided is a valid VAT number. This + checks the length, formatting and check digit.""" + number = compact(number) + if not number.isdigit(): + raise InvalidFormat() + if len(number) == 9: + # 9 digit numbers are for legal entities + if number[-1] != calc_check_digit_legal(number[:-1]): + raise InvalidChecksum() + elif len(number) == 10: + # 10 digit numbers are for physical persons, foreigners and others + if not egn.is_valid(number) and not pnf.is_valid(number) and \ + number[-1] != calc_check_digit_other(number[:-1]): + raise InvalidChecksum() + else: + raise InvalidLength() + return number + + def is_valid(number): """Checks to see if the number provided is a valid VAT number. This checks the length, formatting and check digit.""" try: - number = compact(number) - except: + return bool(validate(number)) + except ValidationError: return False - if len(number) == 9 and number.isdigit(): - # 9 digit numbers are for legal entities - return number[-1] == calc_check_digit_legal(number[:-1]) - if len(number) == 10 and number.isdigit(): - # 10 digit numbers are for physical persons, foreigners and others - return egn.is_valid(number) or \ - pnf.is_valid(number) or \ - number[-1] == calc_check_digit_other(number[:-1]) - return False |