python-stdnum branch master updated. 1.17-20-gc5595c7
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
python-stdnum branch master updated. 1.17-20-gc5595c7
- 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.17-20-gc5595c7
- Date: Sun, 14 Aug 2022 22:04:55 +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 c5595c7e80277bbf2102f293c1f4fbcec07f7101 (commit)
from 4d4a0b35dd8db8a4ddba469dc2cb646f1f877785 (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=c5595c7e80277bbf2102f293c1f4fbcec07f7101
commit c5595c7e80277bbf2102f293c1f4fbcec07f7101
Author: petr.prikryl <petr.prikryl@olc.cz>
Date: Wed Jun 8 17:14:40 2022 +0200
Add Czech bank account numbers
Closes https://github.com/arthurdejong/python-stdnum/issues/295
Closes https://github.com/arthurdejong/python-stdnum/pull/296
diff --git a/stdnum/cz/bankaccount.py b/stdnum/cz/bankaccount.py
new file mode 100644
index 0000000..76169a6
--- /dev/null
+++ b/stdnum/cz/bankaccount.py
@@ -0,0 +1,133 @@
+# bankaccount.py - functions for handling Czech bank account numbers
+# coding: utf-8
+#
+# Copyright (C) 2022 Petr Přikryl
+#
+# 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
+
+"""Czech bank account number.
+
+The Czech bank account numbers consist of up to 20 digits:
+ UUUUUK-MMMMMMMMKM/XXXX
+
+The first part is prefix that is up to 6 digits. The following part is from 2
to 10 digits.
+Both parts could be filled with zeros from left if missing.
+The final 4 digits represent the bank code.
+
+More information:
+
+*
https://www.penize.cz/osobni-ucty/424173-tajemstvi-cisla-uctu-klicem-pro-banky-je-11
+* http://www.zlatakoruna.info/zpravy/ucty/cislo-uctu-v-cr
+
+>>> validate('34278-0727558021/0100')
+'034278-0727558021/0100'
+>>> validate('4278-727558021/0100') # invalid check digits (prefix)
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+>>> validate('34278-727558021/0000') # invalid bank
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> format('34278-727558021/0100')
+'034278-0727558021/0100'
+>>> to_bic('34278-727558021/0100')
+'KOMBCZPP'
+"""
+
+import re
+
+from stdnum.exceptions import *
+from stdnum.util import clean
+
+
+_bankaccount_re = re.compile(
+ r'((?P<prefix>[0-9]{0,6})-)?(?P<root>[0-9]{2,10})\/(?P<bank>[0-9]{4})')
+
+
+def compact(number):
+ """Convert the number to the minimal representation. This strips the
+ number of any valid separators and removes surrounding whitespace."""
+ number = clean(number).strip()
+ match = _bankaccount_re.match(number)
+ if match:
+ # zero-pad valid numbers
+ prefix = (match.group('prefix') or '').zfill(6)
+ root = match.group('root').zfill(10)
+ number = ''.join((prefix, '-', root, '/', match.group('bank')))
+ return number
+
+
+def _split(number):
+ """Split valid numbers into prefix, root and bank parts of the number."""
+ match = _bankaccount_re.match(number)
+ if not match:
+ raise InvalidFormat()
+ return match.group('prefix'), match.group('root'), match.group('bank')
+
+
+def _info(bank):
+ """Look up information for the bank."""
+ from stdnum import numdb
+ info = {}
+ for nr, found in numdb.get('cz/banks').info(bank):
+ info.update(found)
+ return info
+
+
+def info(number):
+ """Return a dictionary of data about the supplied number. This typically
+ returns the name of the bank and branch and a BIC if it is valid."""
+ prefix, root, bank = _split(compact(number))
+ return _info(bank)
+
+
+def to_bic(number):
+ """Return the BIC for the bank that this number refers to."""
+ bic = info(number).get('bic')
+ if bic:
+ return str(bic)
+
+
+def _calc_checksum(number):
+ weights = (6, 3, 7, 9, 10, 5, 8, 4, 2, 1)
+ return sum(w * int(n) for w, n in zip(weights, number.zfill(10))) % 11
+
+
+def validate(number):
+ """Check if the number provided is a valid bank account number."""
+ number = compact(number)
+ prefix, root, bank = _split(number)
+ if _calc_checksum(prefix) != 0:
+ raise InvalidChecksum()
+ if _calc_checksum(root) != 0:
+ raise InvalidChecksum()
+ if 'bank' not in _info(bank):
+ raise InvalidComponent()
+ return number
+
+
+def is_valid(number):
+ """Check if the number provided is a valid bank account 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/stdnum/cz/banks.dat b/stdnum/cz/banks.dat
new file mode 100644
index 0000000..df1a272
--- /dev/null
+++ b/stdnum/cz/banks.dat
@@ -0,0 +1,59 @@
+# generated from kody_bank_CR.csv downloaded from
+#
https://www.cnb.cz/cs/platebni-styk/.galleries/ucty_kody_bank/download/kody_bank_CR.csv
+0100 bic="KOMBCZPP" bank="Komerční banka, a.s." certis="True"
+0300 bic="CEKOCZPP" bank="Československá obchodní banka, a. s." certis="True"
+0600 bic="AGBACZPP" bank="MONETA Money Bank, a.s." certis="True"
+0710 bic="CNBACZPP" bank="ČESKÁ NÁRODNÍ BANKA" certis="True"
+0800 bic="GIBACZPX" bank="Česká spořitelna, a.s." certis="True"
+2010 bic="FIOBCZPP" bank="Fio banka, a.s." certis="True"
+2020 bic="BOTKCZPP" bank="MUFG Bank (Europe) N.V. Prague Branch" certis="True"
+2060 bic="CITFCZPP" bank="Citfin, spořitelní družstvo" certis="True"
+2070 bic="MPUBCZPP" bank="TRINITY BANK a.s." certis="True"
+2100 bank="Hypoteční banka, a.s." certis="True"
+2200 bank="Peněžní dům, spořitelní družstvo" certis="True"
+2220 bic="ARTTCZPP" bank="Artesa, spořitelní družstvo" certis="True"
+2250 bic="CTASCZ22" bank="Banka CREDITAS a.s." certis="True"
+2260 bank="NEY spořitelní družstvo" certis="True"
+2275 bank="Podnikatelská družstevní záložna"
+2600 bic="CITICZPX" bank="Citibank Europe plc, organizační složka"
+2700 bic="BACXCZPP" bank="UniCredit Bank Czech Republic and Slovakia, a.s."
certis="True"
+3030 bic="AIRACZPP" bank="Air Bank a.s." certis="True"
+3050 bic="BPPFCZP1" bank="BNP Paribas Personal Finance SA, odštěpný závod"
certis="True"
+3060 bic="BPKOCZPP" bank="PKO BP S.A., Czech Branch" certis="True"
+3500 bic="INGBCZPP" bank="ING Bank N.V." certis="True"
+4000 bic="EXPNCZPP" bank="Expobank CZ a.s." certis="True"
+4300 bic="NROZCZPP" bank="Národní rozvojová banka, a.s." certis="True"
+5500 bic="RZBCCZPP" bank="Raiffeisenbank a.s." certis="True"
+5800 bic="JTBPCZPP" bank="J&T BANKA, a.s."
+6000 bic="PMBPCZPP" bank="PPF banka a.s." certis="True"
+6100 bic="EQBKCZPP" bank="Raiffeisenbank a.s. (do 31. 12. 2021 Equa bank
a.s.)" certis="True"
+6200 bic="COBACZPX" bank="COMMERZBANK Aktiengesellschaft, pobočka Praha"
certis="True"
+6210 bic="BREXCZPP" bank="mBank S.A., organizační složka" certis="True"
+6300 bic="GEBACZPP" bank="BNP Paribas S.A., pobočka Česká republika"
certis="True"
+6700 bic="SUBACZPP" bank="Všeobecná úverová banka a.s., pobočka Praha"
certis="True"
+6800 bic="VBOECZ2X" bank="Sberbank CZ, a.s. v likvidaci" certis="True"
+7910 bic="DEUTCZPX" bank="Deutsche Bank Aktiengesellschaft Filiale Prag,
organizační složka" certis="True"
+7950 bank="Raiffeisen stavební spořitelna a.s." certis="True"
+7960 bank="ČSOB Stavební spořitelna, a.s." certis="True"
+7970 bank="MONETA Stavební Spořitelna, a.s." certis="True"
+7990 bank="Modrá pyramida stavební spořitelna, a.s." certis="True"
+8030 bic="GENOCZ21" bank="Volksbank Raiffeisenbank Nordoberpfalz eG pobočka
Cheb" certis="True"
+8040 bic="OBKLCZ2X" bank="Oberbank AG pobočka Česká republika" certis="True"
+8060 bank="Stavební spořitelna České spořitelny, a.s." certis="True"
+8090 bic="CZEECZPP" bank="Česká exportní banka, a.s." certis="True"
+8150 bic="MIDLCZPP" bank="HSBC Continental Europe, Czech Republic"
certis="True"
+8190 bank="Sparkasse Oberlausitz-Niederschlesien" certis="True"
+8198 bic="FFCSCZP1" bank="FAS finance company s.r.o."
+8199 bic="MOUSCZP2" bank="MoneyPolo Europe s.r.o."
+8200 bank="PRIVAT BANK der Raiffeisenlandesbank Oberösterreich
Aktiengesellschaft, pobočka Česká republika"
+8220 bic="PAERCZP1" bank="Payment execution s.r.o."
+8230 bank="ABAPAY s.r.o."
+8240 bank="Družstevní záložna Kredit, v likvidaci"
+8250 bic="BKCHCZPP" bank="Bank of China (CEE) Ltd. Prague Branch" certis="True"
+8255 bic="COMMCZPP" bank="Bank of Communications Co., Ltd., Prague Branch
odštěpný závod" certis="True"
+8265 bic="ICBKCZPP" bank="Industrial and Commercial Bank of China Limited,
Prague Branch, odštěpný závod" certis="True"
+8270 bic="FAPOCZP1" bank="Fairplay Pay s.r.o."
+8280 bic="BEFKCZP1" bank="B-Efekt a.s."
+8293 bic="MRPSCZPP" bank="Mercurius partners s.r.o."
+8299 bic="BEORCZP2" bank="BESTPAY s.r.o."
+8500 bank="Ferratum Bank plc"
diff --git a/tests/test_cz_bankaccount.doctest
b/tests/test_cz_bankaccount.doctest
new file mode 100644
index 0000000..d140992
--- /dev/null
+++ b/tests/test_cz_bankaccount.doctest
@@ -0,0 +1,59 @@
+test_cz_bankaccount.doctest - more detailed doctests for stdnum.cz.bankaccount
+
+Copyright (C) 2022 Petr Přikryl
+
+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.cz.bankaccount
+module.
+
+>>> from stdnum.cz import bankaccount
+
+>>> bankaccount.validate('34278-0727558021/0100')
+'034278-0727558021/0100'
+>>> bankaccount.is_valid('4278-0727558021/0100') # missing initial digit
+False
+>>> bankaccount.to_bic('34278-0727558021/0100')
+'KOMBCZPP'
+>>> bankaccount.compact('1/0100')
+'1/0100'
+>>> bankaccount.compact('12/0100')
+'000000-0000000012/0100'
+>>> bankaccount.validate('1/0100')
+Traceback (most recent call last):
+ ...
+bankaccount.InvalidFormat: ...
+>>> bankaccount.validate('8021/0100')
+Traceback (most recent call last):
+ ...
+bankaccount.InvalidChecksum: ...
+>>> bankaccount.to_bic('0727558021/2260')
+
+
+These have been found online and should all be valid numbers.
+
+>>> numbers = '''
+...
+... 19-2000145399/0800
+... 178124-4159/0710
+... 19-34222621/0710
+... 280154417/0300
+... 0500021502/0800
+...
+... '''
+>>> [x for x in numbers.splitlines() if x and not bankaccount.is_valid(x)]
+[]
diff --git a/update/cz_banks.py b/update/cz_banks.py
new file mode 100755
index 0000000..fd7c976
--- /dev/null
+++ b/update/cz_banks.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+# update/cz_banks.py - script to download Bank list from Czech National Bank
+#
+# Copyright (C) 2022 Petr Přikryl
+#
+# 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 script downloads the list of banks with bank codes as used in the
+IBAN and BIC codes as published by the Czech National Bank."""
+
+import csv
+import os.path
+from io import StringIO
+
+import requests
+
+
+# The location of the CSV version of the bank identification codes. Also see
+# https://www.cnb.cz/cs/platebni-styk/ucty-kody-bank/
+download_url =
'https://www.cnb.cz/cs/platebni-styk/.galleries/ucty_kody_bank/download/kody_bank_CR.csv'
+
+
+def get_values(csv_reader):
+ """Return values (bank_number, bic, bank_name, certis) from the CSV."""
+ # skip first row (header)
+ try:
+ next(csv_reader)
+ except StopIteration:
+ pass # ignore empty CSV
+
+ for row in csv_reader:
+ yield row[0], row[2], row[1], row[3] == 'A'
+
+
+if __name__ == '__main__':
+ response = requests.get(download_url)
+ response.raise_for_status()
+ csv_reader = csv.reader(StringIO(response.content.decode('utf-8')),
delimiter=';')
+ print('# generated from %s downloaded from' %
os.path.basename(download_url))
+ print('# %s' % download_url)
+ for bank_number, bic, bank, certis in get_values(csv_reader):
+ info = '%s' % bank_number
+ if bic:
+ info += ' bic="%s"' % bic
+ if bank:
+ info += ' bank="%s"' % bank
+ if certis:
+ info += ' certis="%s"' % certis
+ print(info)
-----------------------------------------------------------------------
Summary of changes:
stdnum/cz/bankaccount.py | 133 ++++++++++++++++++++++++++++++++++++++
stdnum/cz/banks.dat | 59 +++++++++++++++++
tests/test_cz_bankaccount.doctest | 59 +++++++++++++++++
update/cz_banks.py | 64 ++++++++++++++++++
4 files changed, 315 insertions(+)
create mode 100644 stdnum/cz/bankaccount.py
create mode 100644 stdnum/cz/banks.dat
create mode 100644 tests/test_cz_bankaccount.doctest
create mode 100755 update/cz_banks.py
hooks/post-receive
--
python-stdnum
- python-stdnum branch master updated. 1.17-20-gc5595c7,
Commits of the python-stdnum project