1# veronumero.py - functions for handling Finnish individual tax numbers
2# coding: utf-8
3#
4# Copyright (C) 2017 Holvi Payment Services Oy
5# Copyright (C) 2017 Arthur de Jong
6#
7# This library is free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 2.1 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20# 02110-1301 USA
21
22"""
23Veronumero (Finnish individual tax number).
24
25The Veronumero an individual tax number that is assigned to workers in the
26construction industry in Finland. The number is separate from the HETU and is
27a 12 digit number without any embedded information such as birth dates.
28
29More information:
30
31* https://www.vero.fi/en/detailed-guidance/guidance/48791/individual_tax_numbers__instructions_fo/
32* https://prosentti.vero.fi/Veronumerorekisteri/Tarkistus/VeronumeronTarkistus.aspx
33
34>>> validate('123456789123')
35'123456789123'
36>>> validate('12345678912A')
37Traceback (most recent call last):
38    ...
39InvalidFormat: ...
40>>> validate('123456789')
41Traceback (most recent call last):
42    ...
43InvalidLength: ...
44"""
45
46from stdnum.exceptions import *
47from stdnum.util import clean, isdigits
48
49
50def compact(number):
51    """Convert the Veronumero to the minimal representation. This strips
52    surrounding whitespace and removes separators."""
53    return clean(number, ' ').strip()
54
55
56def validate(number):
57    """Check if the number is a valid tax number. This checks the length and
58    formatting."""
59    number = compact(number)
60    if not isdigits(number):
61        raise InvalidFormat()
62    if len(number) != 12:
63        raise InvalidLength()
64    # there is no known check digit validation
65    return number
66
67
68def is_valid(number):
69    """Check if the number is a valid tax number."""
70    try:
71        return bool(validate(number))
72    except ValidationError:
73        return False
74