1# vat.py - functions for handling Maltese VAT numbers 2# 3# Copyright (C) 2012-2015 Arthur de Jong 4# 5# This library is free software; you can redistribute it and/or 6# modify it under the terms of the GNU Lesser General Public 7# License as published by the Free Software Foundation; either 8# version 2.1 of the License, or (at your option) any later version. 9# 10# This library is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# Lesser General Public License for more details. 14# 15# You should have received a copy of the GNU Lesser General Public 16# License along with this library; if not, write to the Free Software 17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18# 02110-1301 USA 19 20"""VAT (Maltese VAT number). 21 22The Maltese VAT registration number contains 8 digits and uses a simple 23weigted checksum. 24 25>>> validate('MT 1167-9112') 26'11679112' 27>>> validate('1167-9113') # invalid check digits 28Traceback (most recent call last): 29 ... 30InvalidChecksum: ... 31""" 32 33from stdnum.exceptions import * 34from stdnum.util import clean, isdigits 35 36 37def compact(number): 38 """Convert the number to the minimal representation. This strips the 39 number of any valid separators and removes surrounding whitespace.""" 40 number = clean(number, ' -').upper().strip() 41 if number.startswith('MT'): 42 number = number[2:] 43 return number 44 45 46def checksum(number): 47 """Calculate the checksum.""" 48 weights = (3, 4, 6, 7, 8, 9, 10, 1) 49 return sum(w * int(n) for w, n in zip(weights, number)) % 37 50 51 52def validate(number): 53 """Check if the number is a valid VAT number. This checks the length, 54 formatting and check digit.""" 55 number = compact(number) 56 if not isdigits(number) or number[0] == '0': 57 raise InvalidFormat() 58 if len(number) != 8: 59 raise InvalidLength() 60 if checksum(number) != 0: 61 raise InvalidChecksum() 62 return number 63 64 65def is_valid(number): 66 """Check if the number is a valid VAT number.""" 67 try: 68 return bool(validate(number)) 69 except ValidationError: 70 return False 71