diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2013-05-17 13:18:31 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2013-06-08 14:45:39 +0200 |
commit | 10710dcccf7ae453983d785e8fbcc5a53dfb485e (patch) | |
tree | 402fb1cb96f994cbbd42789b0d935a0880f93989 | |
parent | 4753c09e81a0adb6b62d12ad60f5a5107d5033c2 (diff) |
Implement validate() for United Kingdom numbers
-rw-r--r-- | stdnum/gb/vat.py | 57 | ||||
-rw-r--r-- | tests/test_gb_vat.doctest | 52 |
2 files changed, 75 insertions, 34 deletions
diff --git a/stdnum/gb/vat.py b/stdnum/gb/vat.py index 98b4a35..f502a5c 100644 --- a/stdnum/gb/vat.py +++ b/stdnum/gb/vat.py @@ -1,6 +1,6 @@ # vat.py - functions for handling United Kingdom VAT numbers # -# 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 @@ -25,17 +25,18 @@ government departments (first two digits are GD) or a 5-digit number for health authorities (first two digits are HA). The 9-digit variants use a weighted checksum. ->>> compact('GB 980 7806 84') +>>> validate('GB 980 7806 84') '980780684' ->>> is_valid('980780684') -True ->>> is_valid('802311781') # invalid check digit -False +>>> validate('802311781') # invalid check digit +Traceback (most recent call last): + ... +InvalidChecksum: ... >>> format('980780684') '980 7806 84' """ from stdnum.util import clean +from stdnum.exceptions import * def compact(number): @@ -54,26 +55,40 @@ def checksum(number): return sum(weights[i] * int(n) for i, n in enumerate(number)) % 97 +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 len(number) == 5: + if not number[2:].isdigit(): + raise InvalidFormat() + if number.startswith('GD') and int(number[2:]) < 500: + # government department + pass + elif number.startswith('HA') and int(number[2:]) >= 500: + # health authority + pass + else: + raise InvalidComponent() + elif len(number) in (9, 12): + if not number.isdigit(): + raise InvalidFormat() + # standard number: nnn nnnn nn + # branch trader: nnn nnnn nn nnn (ignore the last thee digits) + if checksum(number[:9]) not in (0, 42): + 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) == 5 and number.startswith('GD') and number[2:].isdigit(): - # government department - return int(number[2:]) < 500 - if len(number) == 5 and number.startswith('HA') and number[2:].isdigit(): - # health authority - return int(number[2:]) >= 500 - if len(number) == 12 and number.isdigit(): - # branch trader: nnn nnnn nn nnn (ignore the last thee digits) - return checksum(number[:-3]) in (0, 42) - if len(number) == 9 and number.isdigit(): - # standard number: nnn nnnn nn - return checksum(number) in (0, 42) - return False def format(number): diff --git a/tests/test_gb_vat.doctest b/tests/test_gb_vat.doctest index 1537a5d..cdcfe36 100644 --- a/tests/test_gb_vat.doctest +++ b/tests/test_gb_vat.doctest @@ -1,6 +1,6 @@ test_gb_vat.doctest - more detailed doctests for stdnum.gb.vat module -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,20 +27,46 @@ really useful as module documentation. Normal values that should just work. ->>> vat.is_valid('980780684') # standard number -True ->>> vat.is_valid('242338087388') # branch trader -True ->>> vat.is_valid('GD100') # government department -True ->>> vat.is_valid('HA501') # health authority -True - +>>> vat.validate('980780684') # standard number +'980780684' +>>> vat.validate('242338087388') # branch trader +'242338087388' +>>> vat.validate('GD100') # government department +'GD100' +>>> vat.validate('HA501') # health authority +'HA501' -Invalid checksum: ->>> vat.is_valid('802311781') # invalid check digit -False +Invalid long numbers: + +>>> vat.validate('802311781') # invalid check digit +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> vat.validate('9807806842') # too long for standard number +Traceback (most recent call last): + ... +InvalidLength: ... +>>> vat.validate('9807806B4') # invalid digit +Traceback (most recent call last): + ... +InvalidFormat: ... + + +Some variations on the short format: + +>>> vat.validate('ZZ100') # unknown code +Traceback (most recent call last): + ... +InvalidComponent: ... +>>> vat.validate('GD600') # government department with high number +Traceback (most recent call last): + ... +InvalidComponent: ... +>>> vat.validate('HA201') # health authority with low number +Traceback (most recent call last): + ... +InvalidComponent: ... Formatting tests: |