From 07b9f82a353cbaddec43708e1174f68cd04ba063 Mon Sep 17 00:00:00 2001 From: Leandro Regueiro Date: Fri, 9 Sep 2022 21:35:19 +0200 Subject: [PATCH] Add support for Hong Kong TIN Fixes #320. --- stdnum/hk/__init__.py | 24 +++++++++++ stdnum/hk/brn.py | 84 +++++++++++++++++++++++++++++++++++++++ tests/test_hk_brn.doctest | 70 ++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 stdnum/hk/__init__.py create mode 100644 stdnum/hk/brn.py create mode 100644 tests/test_hk_brn.doctest diff --git a/stdnum/hk/__init__.py b/stdnum/hk/__init__.py new file mode 100644 index 00000000..829e2300 --- /dev/null +++ b/stdnum/hk/__init__.py @@ -0,0 +1,24 @@ +# __init__.py - collection of Hong Kong 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 Hong Kong numbers.""" + +# provide aliases +from stdnum.hk import brn as vat # noqa: F401 diff --git a/stdnum/hk/brn.py b/stdnum/hk/brn.py new file mode 100644 index 00000000..26f00d43 --- /dev/null +++ b/stdnum/hk/brn.py @@ -0,0 +1,84 @@ +# nit.py - functions for handling Hong Kong BR 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 + +"""BRN (Bussiness Registration number, Hong Kong tax number). + +Sometimes also called "商業登記號碼" or "BR No." + +This number consists of 8 digits. It is the first 8 digits at the front of the +Business Registration Certificate Number, which in turn has the +22222222-XXX-XX-XX-X format. It is provided by the Inland Revenue Department +(IRD) of Hong Kong at the date of incorporation. + +More information: + +* https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Hong-Kong-TIN.pdf +* https://sleek.com/hk/resources/hong-kong-business-registration-number-vs-company-registration-number/ +* https://blog.startupr.hk/hong-kong-business-registration-number-brn/ + +>>> validate('31130878') +'31130878' +>>> validate('1767 4094') +'17674094' +>>> validate('12345') +Traceback (most recent call last): + ... +InvalidLength: ... +>>> format('1767 4094') +'17674094' +""" # 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, ' -') + + +def validate(number): + """Check if the number is a valid Hong Kong BR number. + + This checks the length and formatting. + """ + number = compact(number) + if len(number) != 8: + raise InvalidLength() + if not isdigits(number): + raise InvalidFormat() + return number + + +def is_valid(number): + """Check if the number is a valid Hong Kong BR 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_hk_brn.doctest b/tests/test_hk_brn.doctest new file mode 100644 index 00000000..c489911f --- /dev/null +++ b/tests/test_hk_brn.doctest @@ -0,0 +1,70 @@ +test_hk_brn.doctest - more detailed doctests for stdnum.hk.brn 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.hk.brn module. It +tries to test more corner cases and detailed functionality that is not really +useful as module documentation. + +>>> from stdnum.hk import brn + + +Tests for some corner cases. + +>>> brn.validate('31130878') +'31130878' +>>> brn.validate('1767 4094') +'17674094' +>>> brn.format('1767 4094') +'17674094' +>>> brn.validate('12345') +Traceback (most recent call last): + ... +InvalidLength: ... +>>> brn.validate('X2345678') +Traceback (most recent call last): + ... +InvalidFormat: ... + + +These have been found online and should all be valid numbers. + +>>> numbers = ''' +... +... 31130878 +... 52399423 +... 71623118 +... 33120398 +... 34647541 +... 58443527 +... 34214805 +... 12004664 +... 71536751 +... 1767 4094 +... 13603580 +... 34773491 +... 34395970 +... 33833767 +... 65556656 +... 15538767 +... 58650623 +... +... ''' +>>> [x for x in numbers.splitlines() if x and not brn.is_valid(x)] +[]