lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 1.17-41-g7be2291

[Date Prev][Date Next] [Thread Prev][Thread Next]

python-stdnum branch master updated. 1.17-41-g7be2291



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-stdnum".

The branch, master has been updated
       via  7be22919b22119816daf0317289563d961cd2168 (commit)
      from  acb6934ff1d74c411e78dc6a91b149600508c402 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://arthurdejong.org/git/python-stdnum/commit/?id=7be22919b22119816daf0317289563d961cd2168

commit 7be22919b22119816daf0317289563d961cd2168
Author: Leandro Regueiro <leandro.regueiro@gmail.com>
Date:   Sun Sep 11 18:35:33 2022 +0200

    Add support for Ghana TIN
    
    Closes https://github.com/arthurdejong/python-stdnum/pull/326
    Closes https://github.com/arthurdejong/python-stdnum/issues/262

diff --git a/stdnum/gh/__init__.py b/stdnum/gh/__init__.py
new file mode 100644
index 0000000..41922b4
--- /dev/null
+++ b/stdnum/gh/__init__.py
@@ -0,0 +1,24 @@
+# __init__.py - collection of Ghana numbers
+# coding: utf-8
+#
+# Copyright (C) 2022 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 Ghana numbers."""
+
+# provide aliases
+from stdnum.gh import tin as vat  # noqa: F401
diff --git a/stdnum/gh/tin.py b/stdnum/gh/tin.py
new file mode 100644
index 0000000..4ca6f6b
--- /dev/null
+++ b/stdnum/gh/tin.py
@@ -0,0 +1,93 @@
+# tin.py - functions for handling Ghana TIN numbers
+# coding: utf-8
+#
+# Copyright (C) 2022 Leandro Regueiro
+# Copyright (C) 2022 Arthur de Jong
+#
+# 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, Ghana tax number).
+
+This number is issued by the Ghana Revenue Authority (GRA) to individuals who
+are not eligible for the Ghanacard PIN and other entities.
+
+This number consists of 11 alpha-numeric characters. It begins with one of the
+following prefixes:
+
+  P00 For Individuals.
+  C00 For Companies limited by guarantee, shares, Unlimited (i.e organisation
+      required to register with the RGD).
+  G00 Government Agencies, MDAs.
+  Q00 Foreign Missions, Employees of foreign missions.
+  V00 Public Institutions, Trusts, Co-operatives, Foreign Shareholder
+      (Offshore), (Entities not registered by RGD).
+
+More information:
+
+* 
https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Ghana-TIN.pdf
+* https://gra.gov.gh/tin/
+* https://gra.gov.gh/tin/tin-faq/
+
+>>> validate('C0000803561')
+'C0000803561'
+>>> validate('C0000803562')
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
+"""  # noqa: E501
+
+import re
+
+from stdnum.exceptions import *
+from stdnum.util import clean
+
+
+_gh_tin_re = re.compile(r'^[PCGQV]{1}00[A-Z0-9]{8}$')
+
+
+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, ' ').upper()
+
+
+def calc_check_digit(number):
+    """Calculate the check digit for the TIN."""
+    check = sum((i + 1) * int(n) for i, n in enumerate(number[1:10])) % 11
+    return 'X' if check == 10 else str(check)
+
+
+def validate(number):
+    """Check if the number is a valid Ghana TIN."""
+    number = compact(number)
+    if len(number) != 11:
+        raise InvalidLength()
+    if not _gh_tin_re.match(number):
+        raise InvalidFormat()
+    if number[-1] != calc_check_digit(number):
+        raise InvalidChecksum()
+    return number
+
+
+def is_valid(number):
+    """Check if the number is a valid Ghana TIN."""
+    try:
+        return bool(validate(number))
+    except ValidationError:
+        return False
diff --git a/tests/test_gh_tin.doctest b/tests/test_gh_tin.doctest
new file mode 100644
index 0000000..6b6bec0
--- /dev/null
+++ b/tests/test_gh_tin.doctest
@@ -0,0 +1,104 @@
+test_gh_tin.doctest - more detailed doctests for stdnum.gh.tin module
+
+Copyright (C) 2022 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.gh.tin module. It
+tries to test more corner cases and detailed functionality that is not really
+useful as module documentation.
+
+>>> from stdnum.gh import tin
+
+
+Tests for some corner cases.
+
+>>> tin.validate('C0000803561')
+'C0000803561'
+>>> tin.validate('P0008816751')
+'P0008816751'
+>>> tin.validate('V0022862404')
+'V0022862404'
+>>> tin.validate('G0005513405')
+'G0005513405'
+>>> tin.validate('12345')
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> tin.validate('X0000803561')
+Traceback (most recent call last):
+    ...
+InvalidFormat: ...
+
+
+These have been found online and should all be valid numbers.
+
+>>> numbers = '''
+...
+... C0000803561
+... C0002147866
+... C0002442477
+... C0002551888
+... C000261992X
+... C0002862646
+... C0003136973
+... C0003137007
+... C0003165493
+... C0003168417
+... C0003257630
+... C0003257673
+... C0003268071
+... C0003278263
+... C0003278271
+... C000327828X
+... C0003278484
+... C0003417425
+... C0003442500
+... C000366497X
+... C0003664996
+... C0003831426
+... C0004056450
+... C0004524764
+... C0004656830
+... C0004743520
+... C0004894162
+... C0005015774
+... C0005203333
+... C0006570275
+... C0009705228
+... C0010952330
+... C001095242X
+... C0013225812
+... C0021485674
+... C0029454158
+... G0005513405
+... G0061140708
+... P0001525662
+... P0004697499
+... P0006187994
+... P0008816751
+... P0009329188
+... P0009329250
+... P0009487379
+... P0012631833
+... P0039937100
+... V0003107108
+... V0022862404
+...
+... '''
+>>> [x for x in numbers.splitlines() if x and not tin.is_valid(x)]
+[]

-----------------------------------------------------------------------

Summary of changes:
 stdnum/{ke => gh}/__init__.py   |   6 +--
 stdnum/{me/pib.py => gh/tin.py} |  61 +++++++++++++----------
 tests/test_gh_tin.doctest       | 104 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+), 28 deletions(-)
 copy stdnum/{ke => gh}/__init__.py (86%)
 copy stdnum/{me/pib.py => gh/tin.py} (50%)
 create mode 100644 tests/test_gh_tin.doctest


hooks/post-receive
-- 
python-stdnum