diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2013-05-17 23:30:58 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2013-06-08 14:45:38 +0200 |
commit | fc1432c89bb0e9fe5e1f5c3c2214b7869a458d96 (patch) | |
tree | 51a75c7e829929ba660194e4f7edafdb94a64b7c | |
parent | 62cafb46aa2da2a5309546fc23e9d6af2c353ad3 (diff) |
Implement validate() for French numbers
-rw-r--r-- | stdnum/fr/siren.py | 32 | ||||
-rw-r--r-- | stdnum/fr/tva.py | 71 |
2 files changed, 66 insertions, 37 deletions
diff --git a/stdnum/fr/siren.py b/stdnum/fr/siren.py index c3a4b9a..f57b0fa 100644 --- a/stdnum/fr/siren.py +++ b/stdnum/fr/siren.py @@ -1,7 +1,7 @@ # siren.py - functions for handling French SIREN 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,16 +26,19 @@ to validate the numbers. >>> compact('552 008 443') '552008443' ->>> is_valid('404833048') -True ->>> is_valid('404833047') -False +>>> validate('404833048') +'404833048' +>>> validate('404833047') +Traceback (most recent call last): + ... +InvalidChecksum: ... >>> to_tva('443 121 975') '46 443 121 975' """ -from stdnum.util import clean from stdnum import luhn +from stdnum.exceptions import * +from stdnum.util import clean # An online validation function is available but it does not provide an @@ -50,14 +53,25 @@ def compact(number): return clean(number, ' ').strip() +def validate(number): + """Checks to see if the number provided is a valid number. This checks + the length, formatting and check digit.""" + number = compact(number) + if not number.isdigit(): + raise InvalidFormat() + if len(number) != 9: + raise InvalidLength() + luhn.validate(number) + return number + + def is_valid(number): """Checks to see if the number provided is a valid number. This checks the length, formatting and check digit.""" try: - number = compact(number) - except: + return bool(validate(number)) + except ValidationError: return False - return len(number) == 9 and number.isdigit() and luhn.is_valid(number) def to_tva(number): diff --git a/stdnum/fr/tva.py b/stdnum/fr/tva.py index c6f8e01..dca4f49 100644 --- a/stdnum/fr/tva.py +++ b/stdnum/fr/tva.py @@ -1,7 +1,7 @@ # tva.py - functions for handling French TVA 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,21 @@ style numbers at least one is a alphabetic. >>> compact('Fr 40 303 265 045') '40303265045' ->>> is_valid('23334175221') -True ->>> is_valid('84 323 140 391') # incorrect check digit -False ->>> is_valid('K7399859412') # new-style number -True ->>> is_valid('4Z123456782') # new-style number starting with digit -True +>>> validate('23334175221') +'23334175221' +>>> validate('84 323 140 391') +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> validate('K7399859412') # new-style number +'K7399859412' +>>> validate('4Z123456782') # new-style number starting with digit +'4Z123456782' """ -from stdnum.util import clean +from stdnum.exceptions import * from stdnum.fr import siren +from stdnum.util import clean # the valid characters for the first two digits (O and I are missing) @@ -54,26 +57,38 @@ def compact(number): return number +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 all(x in _alphabet for x in number[:2]): + raise InvalidFormat() + if len(number) != 11: + raise InvalidLength() + siren.validate(number[2:]) + if number.isdigit(): + # all-numeric digits + if int(number[:2]) != (int(number[2:] + '12') % 97): + raise InvalidChecksum() + else: + # one of the first two digits isn't a number + if number[0].isdigit(): + check = ( + _alphabet.index(number[0]) * 24 + + _alphabet.index(number[1]) - 10) + else: + check = ( + _alphabet.index(number[0]) * 34 + + _alphabet.index(number[1]) - 100) + if (int(number[2:]) + 1 + check // 11) % 11 != (check % 11): + raise InvalidChecksum() + 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 False - if len(number) == 11 and siren.is_valid(number[2:]) and \ - number[0] in _alphabet and number[1] in _alphabet: - if number.isdigit(): - # all-numeric digits - return int(number[:2]) == int(number[2:] + '12') % 97 - else: - # one of the first two digits isn't a number - if number[0].isdigit(): - check = _alphabet.index(number[0]) * 24 + \ - _alphabet.index(number[1]) - 10 - else: - check = _alphabet.index(number[0]) * 34 + \ - _alphabet.index(number[1]) - 100 - return (int(number[2:]) + 1 + check // 11 ) % 11 == check % 11 - else: + return bool(validate(number)) + except ValidationError: return False |