diff --git a/stdnum/tz/__init__.py b/stdnum/tz/__init__.py new file mode 100644 index 00000000..c8160234 --- /dev/null +++ b/stdnum/tz/__init__.py @@ -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.""" diff --git a/stdnum/tz/tin.py b/stdnum/tz/tin.py new file mode 100644 index 00000000..226f4e97 --- /dev/null +++ b/stdnum/tz/tin.py @@ -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' +""" + +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:]]) diff --git a/tests/test_tz_tin.doctest b/tests/test_tz_tin.doctest new file mode 100644 index 00000000..a2318e00 --- /dev/null +++ b/tests/test_tz_tin.doctest @@ -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)] +[]