python-stdnum branch master updated. 1.18-24-gbe33a80
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
python-stdnum branch master updated. 1.18-24-gbe33a80
- From: Commits of the python-stdnum project <python-stdnum-commits [at] lists.arthurdejong.org>
- To: python-stdnum-commits [at] lists.arthurdejong.org
- Reply-to: python-stdnum-users [at] lists.arthurdejong.org, python-stdnum-commits [at] lists.arthurdejong.org
- Subject: python-stdnum branch master updated. 1.18-24-gbe33a80
- Date: Sun, 25 Jun 2023 18:22:04 +0200 (CEST)
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 be33a801fd1b4728915a89f3f82979cafa3c57f0 (commit)
from 8ce4a47ce14f2775398fdae1e387362f21258ee3 (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=be33a801fd1b4728915a89f3f82979cafa3c57f0
commit be33a801fd1b4728915a89f3f82979cafa3c57f0
Author: Jeff Horemans <jeff.horemans@vortex-financials.be>
Date: Tue Jun 20 11:08:42 2023 +0200
Add Belgian BIS Number
Closes https://github.com/arthurdejong/python-stdnum/pull/418
diff --git a/stdnum/be/bis.py b/stdnum/be/bis.py
new file mode 100644
index 0000000..467f3b7
--- /dev/null
+++ b/stdnum/be/bis.py
@@ -0,0 +1,125 @@
+# coding=utf-8
+# bis.py - functions for handling Belgian BIS numbers
+#
+# Copyright (C) 2023 Jeff Horemans
+#
+# 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
+
+"""BIS (Belgian BIS number).
+
+
+The BIS number (BIS-nummer, Numéro BIS) is a unique identification number
+for individuals who are not registered in the National Register, but who
+still have a relationship with the Belgian government.
+This includes frontier workers, persons who own property in Belgium,
+persons with Belgian social security rights but who do not reside in Belgium,
etc.
+
+The number is issued by the Belgian Crossroads Bank for Social Security (Banque
+Carrefour de la sécurité sociale, Kruispuntbank voor Sociale Zekerheid) and is
+constructed much in the same way as the Belgian National Number, i.e.
consisting of
+11 digits, encoding the person's date of birth and gender, a checksum, etc.
+Other than with the national number though, the month of birth of the BIS
number
+is increased by 20 or 40, depending on whether the sex of the person was known
+at the time or not.
+
+
+More information:
+
+* https://sma-help.bosa.belgium.be/en/faq/where-can-i-find-my-bis-number#7326
+* https://www.socialsecurity.be/site_nl/employer/applics/belgianidpro/index.htm
+* https://nl.wikipedia.org/wiki/Rijksregisternummer
+* https://fr.wikipedia.org/wiki/Numéro_de_registre_national
+
+>>> compact('98.47.28-997.65')
+'98472899765'
+>>> validate('98 47 28 997 65')
+'98472899765'
+>>> validate('01 49 07 001 85')
+'01490700185'
+>>> validate('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> format('98472899765')
+'98.47.28-997.65'
+>>> get_birth_date('98.47.28-997.65')
+datetime.date(1998, 7, 28)
+>>> get_birth_year('98.47.28-997.65')
+1998
+>>> get_birth_month('98.47.28-997.65')
+7
+>>> get_gender('98.47.28-997.65')
+'M'
+"""
+
+from stdnum.be import nn
+from stdnum.exceptions import *
+from stdnum.util import isdigits
+
+
+def compact(number):
+ """Convert the number to the minimal representation. This strips the number
+ of any valid separators and removes surrounding whitespace."""
+ return nn.compact(number)
+
+
+def validate(number):
+ """Check if the number is a valid BIS Number."""
+ number = compact(number)
+ if not isdigits(number) or int(number) <= 0:
+ raise InvalidFormat()
+ if len(number) != 11:
+ raise InvalidLength()
+ nn._get_birth_date_parts(number)
+ if not 20 <= int(number[2:4]) <= 32 and not 40 <= int(number[2:4]) <= 52:
+ raise InvalidComponent('Month must be in 20..32 or 40..52 range')
+ return number
+
+
+def is_valid(number):
+ """Check if the number is a valid BIS Number."""
+ try:
+ return bool(validate(number))
+ except ValidationError:
+ return False
+
+
+def format(number):
+ """Reformat the number to the standard presentation format."""
+ return nn.format(number)
+
+
+def get_birth_year(number):
+ """Return the year of the birth date."""
+ return nn.get_birth_year(number)
+
+
+def get_birth_month(number):
+ """Return the month of the birth date."""
+ return nn.get_birth_month(number)
+
+
+def get_birth_date(number):
+ """Return the date of birth."""
+ return nn.get_birth_date(number)
+
+
+def get_gender(number):
+ """Get the person's gender ('M' or 'F'), which for BIS
+ numbers is only known if the month was incremented with 40."""
+ number = compact(number)
+ if int(number[2:4]) >= 40:
+ return nn.get_gender(number)
diff --git a/stdnum/be/nn.py b/stdnum/be/nn.py
index 12b05cb..1de122a 100644
--- a/stdnum/be/nn.py
+++ b/stdnum/be/nn.py
@@ -115,11 +115,12 @@ def _get_birth_date_parts(number):
# If the fictitious dates 1900/00/01 or 2000/00/01 are detected,
# the birth date (including the year) was not known when the number
# was issued.
- if number[:6] == '000001':
+ if number[:6] in ('000001', '002001', '004001'):
return (None, None, None)
year = int(number[:2]) + century
- month, day = int(number[2:4]), int(number[4:6])
+ month = int(number[2:4]) % 20
+ day = int(number[4:6])
# When the month is zero, it was either unknown when the number was issued,
# or the day counter ran out. In both cases, the month and day are not
known
# reliably.
@@ -128,7 +129,7 @@ def _get_birth_date_parts(number):
# Verify range of month
if month > 12:
- raise InvalidComponent('month must be in 1..12')
+ raise InvalidComponent('Month must be in 1..12')
# Case when only the day of the birth date is unknown
if day == 0 or day > calendar.monthrange(year, month)[1]:
@@ -145,6 +146,8 @@ def validate(number):
if len(number) != 11:
raise InvalidLength()
_get_birth_date_parts(number)
+ if not 0 <= int(number[2:4]) <= 12:
+ raise InvalidComponent('Month must be in 1..12')
return number
diff --git a/tests/test_be_bis.doctest b/tests/test_be_bis.doctest
new file mode 100644
index 0000000..b52607c
--- /dev/null
+++ b/tests/test_be_bis.doctest
@@ -0,0 +1,136 @@
+test_be_bis.doctest - more detailed doctests for stdnum.be.bis module
+
+Copyright (C) 2023 Jeff Horemans
+
+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.be.bis module. It
+tries to test more corner cases and detailed functionality that is not
+really useful as module documentation.
+
+>>> from stdnum.be import bis
+
+
+Extra tests for getting birth date, year and/or month
+
+
+>>> bis.get_birth_date('75.46.08-980.95')
+datetime.date(1975, 6, 8)
+>>> bis.get_birth_year('75.46.08-980.95')
+1975
+>>> bis.get_birth_month('75.46.08-980.95')
+6
+>>> bis.get_birth_date('01 49 07 001 85')
+datetime.date(2001, 9, 7)
+>>> bis.get_birth_year('01 49 07 001 85')
+2001
+>>> bis.get_birth_month('01 49 07 001 85')
+9
+>>> bis.get_birth_date('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> bis.get_birth_year('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> bis.get_birth_month('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> bis.get_birth_date('00400100155') # Exact date of birth unknown
(fictitious date case 1900-00-01)
+>>> bis.get_birth_year('00400100155')
+>>> bis.get_birth_month('00400100155')
+>>> bis.get_birth_date('00200100112') # Birth date and gender unknown
+>>> bis.get_birth_year('00200100112')
+>>> bis.get_birth_month('00200100112')
+>>> bis.get_birth_date('00400100184') # Exact date of birth unknown
(fictitious date case 2000-00-01)
+>>> bis.get_birth_year('00400100184')
+>>> bis.get_birth_month('00400100184')
+>>> bis.get_birth_date('00200100141') # Birth date and gender unknown
+>>> bis.get_birth_year('00200100141')
+>>> bis.get_birth_month('00200100141')
+>>> bis.get_birth_date('00400000117') # Only birth year known (2000-00-00)
+>>> bis.get_birth_year('00400000117')
+2000
+>>> bis.get_birth_month('00400000117')
+>>> bis.get_birth_date('00200000171') # Only birth year known and gender
unknown
+>>> bis.get_birth_year('00200000171')
+2000
+>>> bis.get_birth_month('00200000171')
+>>> bis.get_birth_date('00410000124') # Only birth year and month known
(2000-01-00)
+>>> bis.get_birth_year('00410000124')
+2000
+>>> bis.get_birth_month('00410000124')
+1
+>>> bis.get_birth_date('00210000178') # Only birth year and month known
(2000-01-00) and gender unknown
+>>> bis.get_birth_year('00210000178')
+2000
+>>> bis.get_birth_month('00210000178')
+1
+>>> bis.get_birth_date('85473500193') # Unknown day of birth date (35)
+>>> bis.get_birth_year('85473500193')
+1985
+>>> bis.get_birth_month('85473500193')
+7
+>>> bis.get_birth_date('85273500150') # Unknown day of birth date (35) and
gender unknown
+>>> bis.get_birth_year('85273500150')
+1985
+>>> bis.get_birth_month('85273500150')
+7
+>>> bis.get_birth_date('85533000191') # Invalid month (13)
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> bis.get_birth_year('85533000191')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> bis.get_birth_month('85533000191')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> bis.get_birth_date('85333000148')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> bis.get_birth_year('85333000148')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> bis.get_birth_month('85333000148')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+
+
+Extra tests for getting gender.
+
+>>> bis.get_gender('75.46.08-980.95')
+'F'
+>>> bis.get_gender('75.26.08-980.52') # Gender unknown (month incremented by
20)
+>>> bis.get_gender('85473500193')
+'M'
+>>> bis.get_gender('85273500150')
+
+
+A NN should not be considered a valid BIS number.
+
+>>> bis.validate('00000100195')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
diff --git a/tests/test_be_nn.doctest b/tests/test_be_nn.doctest
index cada6b5..ebab87a 100644
--- a/tests/test_be_nn.doctest
+++ b/tests/test_be_nn.doctest
@@ -91,3 +91,11 @@ Extra tests for getting gender
>>> nn.get_gender('75.06.08-980.09')
'F'
+
+
+A BIS number is not considered a valid NN.
+
+>>> nn.validate('00400100184')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
-----------------------------------------------------------------------
Summary of changes:
stdnum/be/bis.py | 125 ++++++++++++++++++++++++++++++++++++++++++
stdnum/be/nn.py | 9 ++-
tests/test_be_bis.doctest | 136 ++++++++++++++++++++++++++++++++++++++++++++++
tests/test_be_nn.doctest | 8 +++
4 files changed, 275 insertions(+), 3 deletions(-)
create mode 100644 stdnum/be/bis.py
create mode 100644 tests/test_be_bis.doctest
hooks/post-receive
--
python-stdnum
- python-stdnum branch master updated. 1.18-24-gbe33a80,
Commits of the python-stdnum project