Skip to content

Commit

Permalink
Add support for Tanzania TIN
Browse files Browse the repository at this point in the history
Fixes #224.
  • Loading branch information
unho committed Mar 5, 2023
1 parent 6d366e3 commit 7d4a98d
Show file tree
Hide file tree
Showing 3 changed files with 340 additions and 0 deletions.
21 changes: 21 additions & 0 deletions stdnum/tz/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# __init__.py - collection of Tanzania numbers
# coding: utf-8
#
# Copyright (C) 2023 Leandro Regueiro
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA

"""Collection of Tanzania numbers."""
73 changes: 73 additions & 0 deletions stdnum/tz/tin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# tin.py - functions for handling Tanzania TIN numbers
# coding: utf-8
#
# Copyright (C) 2023 Leandro Regueiro
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA

"""TIN (Taxpayer Identification Number, or TIN namba, Tanzania tax number).
This number consists of 9 digits, usually separated into three groups
using hyphens to make it easier to read, like XXX-XXX-XXX.
>>> validate('121-207-079')
'121207079'
>>> validate('12345')
Traceback (most recent call last):
...
InvalidLength: ...
>>> format('121207079')
'121-207-079'
""" # noqa: E501

from stdnum.exceptions import *
from stdnum.util import clean, isdigits


def compact(number):
"""Convert the number to the minimal representation.
This strips the number of any valid separators and removes surrounding
whitespace.
"""
return str(clean(number, u' -–').strip())


def validate(number):
"""Check if the number is a valid Tanzania TIN number.
This checks the length and formatting.
"""
number = compact(number)
if len(number) != 9:
raise InvalidLength()
if not isdigits(number):
raise InvalidFormat()
return number


def is_valid(number):
"""Check if the number is a valid Tanzania TIN number."""
try:
return bool(validate(number))
except ValidationError:
return False


def format(number):
"""Reformat the number to the standard presentation format."""
number = compact(number)
return '-'.join([number[:3], number[3:-3], number[-3:]])
246 changes: 246 additions & 0 deletions tests/test_tz_tin.doctest
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
test_tz_tin.doctest - more detailed doctests for stdnum.tz.tin module
coding: utf-8

Copyright (C) 2023 Leandro Regueiro

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA


This file contains more detailed doctests for the stdnum.tz.tin module. It
tries to test more corner cases and detailed functionality that is not really
useful as module documentation.

>>> from stdnum.tz import tin


Tests for some corner cases.

>>> tin.validate('121-207-079')
'121207079'
>>> tin.validate(u'121–207–079')
'121207079'
>>> tin.validate('121 207 079')
'121207079'
>>> tin.validate('121 - 207 - 079')
'121207079'
>>> tin.validate('121207079')
'121207079'
>>> tin.format('121207079')
'121-207-079'
>>> tin.validate('12345')
Traceback (most recent call last):
...
InvalidLength: ...
>>> tin.validate('VV3456789')
Traceback (most recent call last):
...
InvalidFormat: ...


These have been found online and should all be valid numbers.

>>> numbers = u'''
...
... 121-207-079
... 117-030-407
... 130-393-985
... 139 457 471
... 135-000-205
... 107-618-627
... 124-753-783
... 120-662-023
... 105-038-321
... 105-669-445
... 139-384-059
... 133-604-049
... 142-303-175
... 138-506-789
... 100-849-089
... 107-211-748
... 141-076-841
... 115-793-217
... 156-158-429
... 100-168-375
... 127-321-361
... 121-899-779
... 108-711-744
... 130-376-134
... 136-449-125
... 138-921-646
... 102-158-008
... 127-975-116
... 110-496-907
... 105-437-706
... 101-325-695
... 100-784-661
... 129-210-958
... 124-530-725
... 120-332-694
... 144 - 532 - 074
... 101-345-467
... 111-169-268
... 105-875-304
... 108-537-108
... 100-147-181
... 128-755-586
... 100-145-804
... 102-072-286
... 120-992-864
... 123-854-233
... 142-253-011
... 101-042-197
... 101-195-651
... 130 307 337
... 138-360-679
... 130-084-273
... 107-089-765
... 144-436-253
... 130-265-529
... 132760721
... 135-972-118
... 105-632-991
... 101-034-879
... 112-911-847
... 100-195-232
... 120-884-336
... 110-170-335
... 100-895-803
... 129-506-202
... 145-456-789
... 120-537-776
... 136-968-017
... 100-202-646
... 103150524
... 117-953-300
... 125-181-317
... 134-267-437
... 125 319 890
... 122-452-328
... 118-847-407
... 107-855-106
... 116-738-023
... 144-372-069
... 100-146-630
... 102-825-128
... 113-521-937
... 128-263-454
... 138-675-009
... 120-364-529
... 141-610-678
... 126 – 041 – 349
... 108-998-350
... 115-577-239
... 125-885-020
... 132-800-723
... 110-402-910
... 138-692-302
... 103-626-137
... 153-443-971
... 111-927-480
... 116-285-088
... 129-937-084
... 142-002-078
... 115-302-302
... 127-491-690
... 127- 532-931
... 103-410-444
... 101-346-943
... 154-318-933
... 139-793-412
... 100147181
... 130-210- 392
... 138-584-666
... 120-036-815
... 117-653-218
... 131-946-961
... 118-690-265
... 125-801-153
... 129-042-877
... 135-202-827
... 115-575-503
... 106-091-625
... 120-723-987
... 122-044-483
... 104-746-047
... 123-854-233
... 100-101-297
... 117-305-341
... 107-075-259
... 100-178-117
... 107-966-013
... 112-166-386
... 122-034-178
... 138-882-756
... 117-409-171
... 107-260-692
... 100-197-898
... 137-843-951
... 107-199-101
... 126-085-451
... 135-769-827
... 118-926-862
... 115-692-127
... 126-471-688
... 112-351-035
... 123-288-602
... 121-786-524
... 113-225-246
... 138-007-286
... 122-992-136
... 101-041-662
... 139-953-462
... 109-345-180
... 908-263-792
... 111-588-198
... 125-967-574
... 107-588-582
... 116-800-403
... 101-299-570
... 139-362-756
... 131-057-857
... 106-736-839
... 101-151-425
... 101-668-479
... 104-368-867
... 113-663-903
... 121-666-944
... 135-703-877
... 132-761-728
... 106-955-581
... 130-882-110
... 105-861-400
... 140-564-044
... 134-154-497
... 115-236-776
... 129-515-406
... 119-343-100
... 110-034-326
... 119-264-251
... 101-024-490
... 107-538-844
... 101-473-368
... 104-979-386
... 100-173-697
... 106-535-590
... 140-148-628
... 111-039-240
... 105541295
... 100582775
... 100254484
...
... '''
>>> [x for x in numbers.splitlines() if x and not tin.is_valid(x)]
[]

0 comments on commit 7d4a98d

Please sign in to comment.