python-stdnum branch master updated. 1.20-9-gaf3a728
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
python-stdnum branch master updated. 1.20-9-gaf3a728
- 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.20-9-gaf3a728
- Date: Sat, 27 Jul 2024 14:56:37 +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 af3a728f6f3533da7ad398614163cc0f776dcb95 (commit)
from 0da257c6646c2565eeb1820e3d2a1a1d95d12884 (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=af3a728f6f3533da7ad398614163cc0f776dcb95
commit af3a728f6f3533da7ad398614163cc0f776dcb95
Author: Jeff Horemans <jeff.horemans@vortex-financials.be>
Date: Tue Jul 4 13:57:39 2023 +0200
Add Belgian SSN number
Closes https://github.com/arthurdejong/python-stdnum/pull/438
diff --git a/stdnum/be/ssn.py b/stdnum/be/ssn.py
new file mode 100644
index 0000000..65045c1
--- /dev/null
+++ b/stdnum/be/ssn.py
@@ -0,0 +1,155 @@
+# coding: utf-8
+# ssn.py - function for handling Belgian social security numbers
+#
+# Copyright (C) 2023-2024 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
+
+"""SSN, INSZ, NISS (Belgian social security number).
+
+The Belgian social security identification number, also known as the INSZ
+number (Identificatienummer van de sociale zekerheid), NISS number (Numéro
+d'identification de la sécurité sociale) or ENSS number (Erkennungsnummer
+der sozialen Sicherheit), is the unique identification number of a person
+working in or covered for social benefits in Belgium.
+
+For Belgian residents, the number is identical to their Belgian National
+Number (Rijksregisternummer, Numéro National).
+For non-residents, the number is identical to their Belgian BIS number.
+
+Both numbers consists of 11 digits and encode a person's date of birth and
+gender. It encodes the date of birth in the first 6 digits in the format
+YYMMDD. The following 3 digits represent a counter of people born on the same
+date, separated by sex (odd for male and even for females respectively). The
+final 2 digits form a check number based on the 9 preceding digits.
+
+
+More information:
+
+* https://www.socialsecurity.be/site_nl/employer/applics/belgianidpro/index.htm
+* https://overheid.vlaanderen.be/personeel/regelgeving/insz-nummer
+* https://www.ksz-bcss.fgov.be/nl/project/rijksregisterksz-registers
+
+>>> compact('85.07.30-033 28')
+'85073003328'
+>>> compact('98.47.28-997.65')
+'98472899765'
+>>> validate('85 07 30 033 28')
+'85073003328'
+>>> validate('98 47 28 997 65')
+'98472899765'
+>>> validate('17 07 30 033 84')
+'17073003384'
+>>> validate('01 49 07 001 85')
+'01490700185'
+>>> validate('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+
+>>> guess_type('85.07.30-033 28')
+'nn'
+>>> guess_type('98.47.28-997.65')
+'bis'
+
+>>> format('85073003328')
+'85.07.30-033.28'
+>>> get_birth_date('85.07.30-033 28')
+datetime.date(1985, 7, 30)
+>>> get_birth_year('85.07.30-033 28')
+1985
+>>> get_birth_month('85.07.30-033 28')
+7
+>>> get_gender('85.07.30-033 28')
+'M'
+
+>>> 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 bis, nn
+from stdnum.exceptions import *
+
+
+_ssn_modules = (nn, bis)
+
+
+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 Belgian SSN. This searches for
+ the proper sub-type and validates using that."""
+ try:
+ return bis.validate(number)
+ except InvalidComponent:
+ # Only try NN validation in case of an invalid component,
+ # other validation errors are shared between BIS and NN
+ return nn.validate(number)
+
+
+def is_valid(number):
+ """Check if the number is a valid Belgian SSN number."""
+ try:
+ return bool(validate(number))
+ except ValidationError:
+ return False
+
+
+def guess_type(number):
+ """Return the Belgian SSN type for which this number is valid."""
+ for mod in _ssn_modules:
+ if mod.is_valid(number):
+ return mod.__name__.rsplit('.', 1)[-1]
+
+
+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')."""
+ for mod in _ssn_modules:
+ if mod.is_valid(number):
+ return mod.get_gender(number)
diff --git a/tests/test_be_ssn.doctest b/tests/test_be_ssn.doctest
new file mode 100644
index 0000000..88ff1e2
--- /dev/null
+++ b/tests/test_be_ssn.doctest
@@ -0,0 +1,205 @@
+test_be_ssn.doctest - more detailed doctests for stdnum.be.ssn module
+
+Copyright (C) 2022 Arthur de Jong
+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.ssn module. It
+tries to test more corner cases and detailed functionality that is not
+really useful as module documentation.
+
+>>> from stdnum.be import ssn
+
+
+Extra tests for getting birth date, year and/or month from National Number.
+
+
+>>> ssn.get_birth_date('85.07.30-033 28')
+datetime.date(1985, 7, 30)
+>>> ssn.get_birth_year('85.07.30-033 28')
+1985
+>>> ssn.get_birth_month('85.07.30-033 28')
+7
+>>> ssn.get_birth_date('17 07 30 033 84')
+datetime.date(2017, 7, 30)
+>>> ssn.get_birth_year('17 07 30 033 84')
+2017
+>>> ssn.get_birth_month('17 07 30 033 84')
+7
+>>> ssn.get_birth_date('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> ssn.get_birth_year('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> ssn.get_birth_month('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> ssn.get_birth_date('00000100166') # Exact date of birth unknown
(fictitious date case 1900-00-01)
+>>> ssn.get_birth_year('00000100166')
+>>> ssn.get_birth_month('00000100166')
+>>> ssn.get_birth_date('00000100195') # Exact date of birth unknown
(fictitious date case 2000-00-01)
+>>> ssn.get_birth_year('00000100195')
+>>> ssn.get_birth_month('00000100195')
+>>> ssn.get_birth_date('00000000128') # Only birth year known (2000-00-00)
+>>> ssn.get_birth_year('00000000128')
+2000
+>>> ssn.get_birth_month('00000000128')
+>>> ssn.get_birth_date('00010000135') # Only birth year and month known
(2000-01-00)
+>>> ssn.get_birth_year('00010000135')
+2000
+>>> ssn.get_birth_month('00010000135')
+1
+>>> ssn.get_birth_date('85073500107') # Unknown day of birth date (35)
+>>> ssn.get_birth_year('85073500107')
+1985
+>>> ssn.get_birth_month('85073500107')
+7
+>>> ssn.get_birth_date('85133000105') # Invalid month (13)
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> ssn.get_birth_year('85133000105')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> ssn.get_birth_month('85133000105')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+
+
+
+Extra tests for getting gender from National Number
+
+>>> ssn.get_gender('75.06.08-980.09')
+'F'
+>>> ssn.get_gender('12345678901')
+
+
+Extra tests for getting birth date, year and/or month from BIS number.
+
+
+>>> ssn.get_birth_date('75.46.08-980.95')
+datetime.date(1975, 6, 8)
+>>> ssn.get_birth_year('75.46.08-980.95')
+1975
+>>> ssn.get_birth_month('75.46.08-980.95')
+6
+>>> ssn.get_birth_date('01 49 07 001 85')
+datetime.date(2001, 9, 7)
+>>> ssn.get_birth_year('01 49 07 001 85')
+2001
+>>> ssn.get_birth_month('01 49 07 001 85')
+9
+>>> ssn.get_birth_date('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> ssn.get_birth_year('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> ssn.get_birth_month('12345678901')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> ssn.get_birth_date('00400100155') # Exact date of birth unknown
(fictitious date case 1900-00-01)
+>>> ssn.get_birth_year('00400100155')
+>>> ssn.get_birth_month('00400100155')
+>>> ssn.get_birth_date('00200100112') # Birth date and gender unknown
+>>> ssn.get_birth_year('00200100112')
+>>> ssn.get_birth_month('00200100112')
+>>> ssn.get_birth_date('00400100184') # Exact date of birth unknown
(fictitious date case 2000-00-01)
+>>> ssn.get_birth_year('00400100184')
+>>> ssn.get_birth_month('00400100184')
+>>> ssn.get_birth_date('00200100141') # Birth date and gender unknown
+>>> ssn.get_birth_year('00200100141')
+>>> ssn.get_birth_month('00200100141')
+>>> ssn.get_birth_date('00400000117') # Only birth year known (2000-00-00)
+>>> ssn.get_birth_year('00400000117')
+2000
+>>> ssn.get_birth_month('00400000117')
+>>> ssn.get_birth_date('00200000171') # Only birth year known and gender
unknown
+>>> ssn.get_birth_year('00200000171')
+2000
+>>> ssn.get_birth_month('00200000171')
+>>> ssn.get_birth_date('00410000124') # Only birth year and month known
(2000-01-00)
+>>> ssn.get_birth_year('00410000124')
+2000
+>>> ssn.get_birth_month('00410000124')
+1
+>>> ssn.get_birth_date('00210000178') # Only birth year and month known
(2000-01-00) and gender unknown
+>>> ssn.get_birth_year('00210000178')
+2000
+>>> ssn.get_birth_month('00210000178')
+1
+>>> ssn.get_birth_date('85473500193') # Unknown day of birth date (35)
+>>> ssn.get_birth_year('85473500193')
+1985
+>>> ssn.get_birth_month('85473500193')
+7
+>>> ssn.get_birth_date('85273500150') # Unknown day of birth date (35) and
gender unknown
+>>> ssn.get_birth_year('85273500150')
+1985
+>>> ssn.get_birth_month('85273500150')
+7
+>>> ssn.get_birth_date('85533000191') # Invalid month (13)
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> ssn.get_birth_year('85533000191')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> ssn.get_birth_month('85533000191')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> ssn.get_birth_date('85333000148')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> ssn.get_birth_year('85333000148')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> ssn.get_birth_month('85333000148')
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+
+
+Extra tests for getting gender from BIS number.
+
+>>> ssn.get_gender('75.46.08-980.95')
+'F'
+>>> ssn.get_gender('75.26.08-980.52') # Gender unknown (month incremented by
20)
+>>> ssn.get_gender('85473500193')
+'M'
+>>> ssn.get_gender('85273500150')
+>>> ssn.get_gender('12345678901')
+
+
+Extra tests for guessing type of invalid numbers
+
+
+>>> ssn.guess_type('12345678901')
-----------------------------------------------------------------------
Summary of changes:
stdnum/be/ssn.py | 155 +++++++++++++++++++++++++++++++++++
tests/test_be_ssn.doctest | 205 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 360 insertions(+)
create mode 100644 stdnum/be/ssn.py
create mode 100644 tests/test_be_ssn.doctest
hooks/post-receive
--
python-stdnum
- python-stdnum branch master updated. 1.20-9-gaf3a728,
Commits of the python-stdnum project