diff --git a/stdnum/ug/__init__.py b/stdnum/ug/__init__.py new file mode 100644 index 00000000..5f55ca72 --- /dev/null +++ b/stdnum/ug/__init__.py @@ -0,0 +1,24 @@ +# __init__.py - collection of Uganda 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 Uganda numbers.""" + +# provide aliases +from stdnum.ug import tin as vat # noqa: F401 diff --git a/stdnum/ug/tin.py b/stdnum/ug/tin.py new file mode 100644 index 00000000..b267f2a3 --- /dev/null +++ b/stdnum/ug/tin.py @@ -0,0 +1,76 @@ +# tin.py - functions for handling Uganda 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 (Tax identification number, Uganda tax number). + +This number consists of 10 digits. + +More information: + +* https://thetaxman.ura.go.ug/understanding-a-tax-identification-number-tin/ +* https://businessfocus.co.ug/how-to-get-taxpayer-identification-number-from-ura/ + +>>> validate('1000957588') +'1000957588' +>>> validate('12345') +Traceback (most recent call last): + ... +InvalidLength: ... +>>> format('1000957588') +'1000957588' +""" # 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 clean(number, ' -').strip() + + +def validate(number): + """Check if the number is a valid Uganda TIN number. + + This checks the length and formatting. + """ + number = compact(number) + if len(number) != 10: + raise InvalidLength() + if not isdigits(number): + raise InvalidFormat() + return number + + +def is_valid(number): + """Check if the number is a valid Uganda TIN number.""" + try: + return bool(validate(number)) + except ValidationError: + return False + + +def format(number): + """Reformat the number to the standard presentation format.""" + return compact(number) diff --git a/tests/test_ug_tin.doctest b/tests/test_ug_tin.doctest new file mode 100644 index 00000000..d8a41504 --- /dev/null +++ b/tests/test_ug_tin.doctest @@ -0,0 +1,262 @@ +test_ug_tin.doctest - more detailed doctests for stdnum.ug.tin module + +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.ug.tin module. It +tries to test more corner cases and detailed functionality that is not really +useful as module documentation. + +>>> from stdnum.ug import tin + + +Tests for some corner cases. + +>>> tin.validate('1000957588') +'1000957588' +>>> tin.validate('12345') +Traceback (most recent call last): + ... +InvalidLength: ... +>>> tin.validate('10009575XX') +Traceback (most recent call last): + ... +InvalidFormat: ... +>>> tin.format('1000957588') +'1000957588' + + +These have been found online and should all be valid numbers. + +>>> numbers = ''' +... +... 1000957588 +... 1000071933 +... 1008904187 +... 1024060758 +... 1008799009 +... 1014870350 +... 1000185668 +... 1000171284 +... 1000459992 +... 1017875693 +... 1001251612 +... 1006801945 +... 1000412258 +... 1000047445 +... 1019689817 +... 1000028435 +... 1002408394 +... 1009431677 +... 1000866974 +... 1000134869 +... 1000049868 +... 1000042267 +... 1000084312 +... 1000566633 +... 1000134272 +... 1000212673 +... 1000785042 +... 1000035743 +... 1000021193 +... 1000020447 +... 1000724864 +... 1000039236 +... 1000028435 +... 1000098610 +... 1000039754 +... 1000158605 +... 1000432017 +... 1000363499 +... 1000113650 +... 1000023585 +... 1000583175 +... 1000054556 +... 1000026312 +... 1000491360 +... 1000573706 +... 1000036164 +... 1000482371 +... 1000287073 +... 1000054984 +... 1000039364 +... 1000025311 +... 1007345542 +... 1000028459 +... 1000131286 +... 1006695918 +... 1000031221 +... 1000026692 +... 1000134517 +... 1000094357 +... 1000026640 +... 1000033720 +... 1000032087 +... 1000041342 +... 1000096342 +... 1000142650 +... 1000030513 +... 1000049844 +... 1000807252 +... 1000123395 +... 1000061408 +... 1000538227 +... 1000027848 +... 1000051722 +... 1000866974 +... 1000103360 +... 1000028311 +... 1000025080 +... 1000030537 +... 1007361580 +... 1000034745 +... 1000979287 +... 1000025739 +... 1000395040 +... 1000071398 +... 1000024679 +... 1000547002 +... 1000040558 +... 1000029757 +... 1001251277 +... 1006994240 +... 1000054563 +... 1000212642 +... 1000027589 +... 1009286336 +... 1000028725 +... 1000101316 +... 1000217913 +... 1000232097 +... 1000131714 +... 1000899143 +... 1000126305 +... 1000486398 +... 1000485398 +... 1000098116 +... 1000161646 +... 1003157831 +... 1000039778 +... 1000112373 +... 1000042764 +... 1002263840 +... 1000024517 +... 1000046996 +... 1000027144 +... 1000041214 +... 1000061415 +... 1001073346 +... 1000123274 +... 1007698660 +... 1000408392 +... 1010664806 +... 1000024790 +... 1000171284 +... 1000175899 +... 1000225635 +... 1000028428 +... 1000055626 +... 1000400663 +... 1000023944 +... 1000443250 +... 1009135185 +... 1000594518 +... 1000967830 +... 1000062775 +... 1008139706 +... 1000132401 +... 1000078012 +... 1004849404 +... 1000029771 +... 1000472771 +... 1000460461 +... 1000099925 +... 1000126688 +... 1000243257 +... 1000028818 +... 1000394477 +... 1003357368 +... 1009975388 +... 1000055115 +... 1000872860 +... 1010783208 +... 1012498175 +... 1002736330 +... 1007088485 +... 1001194444 +... 1008291934 +... 1000935599 +... 1000990088 +... 1000061201 +... 1000186445 +... 1013963845 +... 1003408785 +... 1013958964 +... 1012318235 +... 1012997342 +... 1000056565 +... 1003067438 +... 1000383555 +... 1000382561 +... 1000051622 +... 1000467745 +... 1002665506 +... 1008565695 +... 1000519607 +... 1002665720 +... 1002753555 +... 1010898089 +... 1013779859 +... 1001119029 +... 1007765966 +... 1000061584 +... 1014184753 +... 1000187094 +... 1007071087 +... 1014112010 +... 1000860008 +... 1007075485 +... 1000042719 +... 1000892736 +... 1000048515 +... 1000648662 +... 1001102936 +... 1000094364 +... 1011242712 +... 1001461384 +... 1000773861 +... 1001171140 +... 1010042518 +... 1010449314 +... 1011417274 +... 1003214205 +... 1006980615 +... 1009612881 +... 1009331018 +... 1007230785 +... 1000058160 +... 1001976219 +... 1002965640 +... 1003795342 +... 1002595231 +... 1002155752 +... 1000545200 +... +... ''' +>>> [x for x in numbers.splitlines() if x and not tin.is_valid(x)] +[]