8000 Add various United States Tax number modules · sharoonthomas/python-stdnum@188d3ea · GitHub
[go: up one dir, main page]

Skip to content

Commit 188d3ea

Browse files
committed
Add various United States Tax number modules
This adds modules for the Individual Taxpayer Identification Number (ITIN), the Employer Identification Number (EIN), Adoption Taxpayer Identification Number (ATIN) and Preparer Tax Identification Number (PTIN) that together with the Social Security Number (SSN) are valid Taxpayer Identification Numbers (TIN)
2 parents 70b974b + 9530635 commit 188d3ea

File tree

6 files changed

+443
-0
lines changed

6 files changed

+443
-0
lines changed

stdnum/us/atin.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# atin.py - functions for handling ATINs
2+
#
3+
# Copyright (C) 2013 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+
"""ATIN (U.S. Adoption Taxpayer Identification Number).
21+
22+
An Adoption Taxpayer Identification Number (ATIN) is a temporary
23+
nine-digit number issued by the United States IRS for a child for whom the
24+
adopting parents cannot obtain a Social Security Number.
25+
26+
>>> validate('123-45-6789')
27+
'123456789'
28+
>>> validate('1234-56789') # dash in the wrong place
29+
Traceback (most recent call last):
30+
...
31+
InvalidFormat: ...
32+
>>> format('123456789')
33+
'123-45-6789'
34+
"""
35+
36+
import re
37+
38+
from stdnum.exceptions import *
39+
from stdnum.util import clean
40+
41+
42+
# regular expression for matching ATINs
43+
_atin_re = re.compile('^[0-9]{3}-?[0-9]{2}-?[0-9]{4}$')
44+
45+
46+
def compact(number):
47+
"""Convert the number to the minimal representation. This strips the
48+
number of any valid separators and removes surrounding whitespace."""
49+
return clean(number, '-').strip()
50+
51+
52+
def validate(number):
53+
"""Checks to see if the number provided is a valid ATIN. This checks
54+
the length and formatting if it is present."""
55+
match = _atin_re.search(clean(number, '').strip())
56+
if not match:
57+
raise InvalidFormat()
58+
# sadly, no more information on ATIN number validation was found
59+
return compact(number)
60+
61+
62+
def is_valid(number):
63+
"""Checks to see if the number provided is a valid ATIN. This checks
64+
the length and formatting if it is present."""
65+
try:
66+
return bool(validate(number))
67+
except ValidationError:
68+
return False
69+
70+
71+
def format(number):
72+
"""Reformat the passed number to the standard format."""
73+
if len(number) == 9:
74+
number = number[:3] + '-' + number[3:5] + '-' + number[5:]
75+
return number

stdnum/us/ein.dat

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# manually converted from the IRS website
2+
# http://www.irs.gov/Businesses/Small-Businesses-&-Self-Employed/How-EINs-are-Assigned-and-Valid-EIN-Prefixes
3+
4+
01,02,03,04,05,06,11,13,14,16,21,22,23,25,34,51,52,54,55,56,57,58,59,65 campus="Brookhaven"
5+
10,12 campus="Andover"
6+
15,24 campus="Fresno"
7+
20,26,27,45,46 campus="Internet"
8+
30,32,35,36,37,38,61 campus="Cincinnati"
9+
31 campus="Small Business Administration (SBA)"
10+
33,39,41,42,43,46,48,62,63,64,66,68,71,72,73,74,75,76,77,81,82,83,84,85,86,87,88,91,92,93,98,99 campus="Philadelphia"
11+
40,44 campus="Kansas City"
12+
50,53 campus="Austin"
13+
60,67 campus="Atlanta"
14+
80,90 campus="Ogden"
15+
94,95 campus="Memphis"

stdnum/us/ein.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# ein.py - functions for handling EINs
2+
#
3+
# Copyright (C) 2013 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+
"""EIN (U.S. Employer Identification Number).
21+
22+
The Employer Identification Number, also known as Federal Employer
23+
Identification Number (FEIN), is used to identify a business entity in the
24+
United States. It is issued to anyone that has to pay withholding taxes on
25+
employees.
26+
27+
>>> validate('91-1144442')
28+
'911144442'
29+
>>> get_campus('04-2103594') == 'Brookhaven'
30+
True
31+
>>> validate('911-14-4442') # dash in the wrong place
32+
Traceback (most recent call last):
33+
...
34+
InvalidFormat: ...
35+
>>> validate('07-1144442') # wrong prefix
36+
Traceback (most recent call last):
37+
...
38+
InvalidComponent: ...
39+
>>> format('042103594')
40+
'04-2103594'
41+
"""
42+
43+
import re
44+
45+
from stdnum.exceptions import *
46+
from stdnum.util import clean
47+
48+
49+
# regular expression for matching EINs
50+
_ein_re = re.compile('^(?P<area>[0-9]{2})-?(?P<group>[0-9]{7})$')
51+
52+
53+
def compact(number):
54+
"""Convert the number to the minimal representation. This strips the
55+
number of any valid separators and removes surrounding whitespace."""
56+
return clean(number, '-').strip()
57+
58+
59+
def get_campus(number):
60+
"""Determine the Campus or other location that issued the EIN."""
61+
from stdnum import numdb
62+
number = compact(number)
63+
results = numdb.get('us/ein').info(number)[0][1]
64+
if not results:
65+
raise InvalidComponent()
66+
return results['campus']
67+
68+
69+
def validate(number):
70+
"""Checks to see if the number provided is a valid EIN. This checks
71+
the length, groups and formatting if it is present."""
72+
match = _ein_re.search(clean(number, '').strip())
73+
if not match:
74+
raise InvalidFormat()
75+
get_campus(number) # raises exception for unknown campus
76+
return compact(number)
77+
78+
79+
def is_valid(number):
80+
"""Checks to see if the number provided is a valid EIN. This checks
81+
the length, groups and formatting if it is present."""
82+
try:
83+
return bool(validate(number))
84+
except ValidationError:
85+
return False
86+
87+
88+
def format(number):
89+
"""Reformat the passed number to the standard format."""
90+
if len(number) == 9:
91+
number = number[:2] + '-' + number[2:]
92+
return number

stdnum/us/itin.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# itin.py - functions for handling ITINs
2+
#
3+
# Copyright (C) 2013 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+
"""ITIN (U.S. Individual Taxpayer Identification Number).
21+
22+
The Individual Taxpayer Identification Number is issued by the United
23+
States IRS to individuals who are required to have a taxpayer
24+
identification number but who are not eligible to obtain a Social Security
25+
Number.
26+
27+
It is a nine-digit number that begins with the number 9 and the
28+
fourth and fifth digit are expected to be in a certain range.
29+
30+
>>> validate('912-90-3456')
31+
'912903456'
32+
>>> validate('9129-03456') # dash in the wrong place
33+
Traceback (most recent call last):
34+
...
35+
InvalidFormat: ...
36+
>>> validate('123-45-6789') # wrong start digit
37+
Traceback (most recent call last):
38+
...
39+
InvalidComponent: ...
40+
>>> validate('912-93-4567') # wrong group
41+
Traceback (most recent call last):
42+
...
43+
InvalidComponent: ...
44+
>>> compact('1234-56-789')
45+
'123456789'
46+
>>> format('111223333')
47+
'111-22-3333'
48+
"""
49+
50+
import re
51+
52+
from stdnum.exceptions import *
53+
from stdnum.util import clean
54+
55+
56+
# regular expression for matching ITINs
57+
_itin_re = re.compile('^(?P<area>[0-9]{3})-?(?P<group>[0-9]{2})-?[0-9]{4}$')
58+
59+
60+
# allowed group digits
61+
_allowed_groups = set((str(x) for x in range(70, 100) if x not in (89, 93)))
62+
63+
64+
def compact(number):
65+
"""Convert the number to the minimal representation. This strips the
66+
number of any valid separators and removes surrounding whitespace."""
67+
return clean(number, '-').strip()
68+
69+
70+
def validate(number):
71+
"""Checks to see if the number provided is a valid ITIN. This checks
72+
the length, groups and formatting if it is present."""
73+
match = _itin_re.search(clean(number, '').strip())
74+
if not match:
75+
raise InvalidFormat()
76+
area = match.group('area')
77+
group = match.group('group')
78+
if area[0] != '9' or group not in _allowed_groups:
79+
raise InvalidComponent()
80+
return compact(number)
81+
82+
83+
def is_valid(number):
84+
"""Checks to see if the number provided is a valid ITIN. This checks
85+
the length, groups and formatting if it is present."""
86+
try:
87+
return bool(validate(number))
88+
except ValidationError:
89+
return False
90+
91+
92+
def format(number):
93+
"""Reformat the passed number to the standard format."""
94+
if len(number) == 9:
95+
number = number[:3] + '-' + number[3:5] + '-' + number[5:]
96+
return number

stdnum/us/ptin.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# ptin.py - functions for handling PTINs
2+
#
3+
# Copyright (C) 2013 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+
"""PTIN (U.S. Preparer Tax Identification Number).
21+
22+
A Preparer Tax Identification Number (PTIN) is United States
23+
identification number for tax return preparers. It is an eight-digit
24+
number prefixed with a capital P.
25+
26+
>>> validate('P-00634642')
27+
'P00634642'
28+
>>> validate('P01594846')
29+
'P01594846'
30+
>>> validate('00634642') # missing P
31+
Traceback (most recent call last):
32+
...
33+
InvalidFormat: ...
34+
"""
35+
36+
import re
37+
38+
from stdnum.exceptions import *
39+
from stdnum.util import clean
40+
41+
42+
# regular expression for matching PTINs
43+
_ptin_re = re.compile('^P[0-9]{8}$')
44+
45+
46+
def compact(number):
47+
"""Convert the number to the minimal representation. This strips the
48+
number of any valid separators and removes surrounding whitespace."""
49+
return clean(number, '-').strip()
50+
51+
52+
def validate(number):
53+
"""Checks to see if the number provided is a valid PTIN. This checks
54+
the length, groups and formatting if it is present."""
55+
number = compact(number).upper()
56+
if not _ptin_re.search(number):
57+
raise InvalidFormat()
58+
# sadly, no more information on PTIN number validation was found
59+
return number
60+
61+
62+
def is_valid(number):
63+
"""Checks to see if the number provided is a valid ATIN. This checks
64+
the length, groups and formatting if it is present."""
65+
try:
66+
return bool(validate(number))
67+
except ValidationError:
68+
return False

0 commit comments

Comments
 (0)
0