finance/ktoblzcheck-data: Update bank data
Bank data is valid from 2025-12-08 until 2025-03-08. MFH: 2026Q1
This commit is contained in:
@@ -34,10 +34,10 @@ PLIST_SUB= BANKDATA_START_DATE=${BANKDATA_START_DATE}
|
||||
KBCD_DATE= 20250515
|
||||
# Custom: This is the date when the bank data is officially recocognized and
|
||||
# supported.
|
||||
BANKDATA_START_DATE= 20250609
|
||||
BANKDATA_START_DATE= 20251208
|
||||
# Custom: This is the date when the bank data is officially void and can no
|
||||
# longer be relied upon.
|
||||
BANKDATA_END_DATE= 20250907
|
||||
BANKDATA_END_DATE= 20260308
|
||||
|
||||
post-extract:
|
||||
# Out of an abundance of caution, remove the pre-built DBs and shipped SEPA data.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
TIMESTAMP = 1751008153
|
||||
TIMESTAMP = 1767925106
|
||||
SHA256 (ktoblzcheck-data-20250515.tar.gz) = 307479cd3c487ba6d6c4f5966634a6023c1f29d4386b93a5e96cea7541bebe4c
|
||||
SIZE (ktoblzcheck-data-20250515.tar.gz) = 267821
|
||||
SHA256 (ktoblzcheck-bankdata-20250609.tar.gz) = 36d9a5ea5c3e7b1183d8fe2f24658d7e50ac3686b14573b17f9f46cf04388065
|
||||
SIZE (ktoblzcheck-bankdata-20250609.tar.gz) = 510238
|
||||
SHA256 (ktoblzcheck-bankdata-20251208.tar.gz) = 8cfbe82f18461aa182fcc7201a9337ae34c93dd652df874f9018adc7ef1463eb
|
||||
SIZE (ktoblzcheck-bankdata-20251208.tar.gz) = 425612
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
- Adapt to SIX Group converting their bankdata to CSV (semicolon separated).
|
||||
- Don't use codecs.open(); deprecated in Python 3.14.
|
||||
|
||||
--- src/switzerland.py.orig 2025-05-15 11:18:20 UTC
|
||||
+++ src/switzerland.py
|
||||
@@ -24,12 +24,11 @@ KMyMoney
|
||||
@author: Christian David
|
||||
"""
|
||||
|
||||
-import sqlite3
|
||||
-import codecs
|
||||
import argparse
|
||||
-import os
|
||||
+import csv
|
||||
+import sqlite3
|
||||
|
||||
-def createTable():
|
||||
+def create_table():
|
||||
""" Create table structure
|
||||
"""
|
||||
cursor = db.cursor()
|
||||
@@ -45,59 +44,65 @@ def createTable():
|
||||
)
|
||||
db.commit()
|
||||
|
||||
-
|
||||
-def processFile(fileName):
|
||||
+def process_file(filename):
|
||||
""" Fills the database with institutions saved in fileName
|
||||
"""
|
||||
+ with open(filename, 'r', newline='') as institutes_file:
|
||||
+ reader = list(csv.reader(institutes_file, delimiter=';'))
|
||||
+ rows = reader[1:]
|
||||
|
||||
- rowsInserted = 0
|
||||
- cursor = db.cursor()
|
||||
- cursor.execute("BEGIN")
|
||||
+ bank_map = {row[0]: {"bic": row[14], "name": f"{row[8]} ({row[12]})"} for row in rows}
|
||||
|
||||
- def existCode(bankCode, bic):
|
||||
- cursor.execute("SELECT bankcode,bic FROM institutions WHERE bankcode = ? and bic = ?",(bankCode,bic,))
|
||||
- row_exist = cursor.fetchone()
|
||||
- if row_exist is None:
|
||||
- return False
|
||||
+ to_insert = []
|
||||
+ for row in rows:
|
||||
+ bankcode = row[0].zfill(5)
|
||||
|
||||
- return True
|
||||
+ # Non-concatenated "parent" entries
|
||||
+ if row[2] == 'N':
|
||||
+ bic = row[14]
|
||||
+ name = f"{row[8]} ({row[12]})"
|
||||
+ # Some bankcodes are concatenated onto other bankcodes without the BIC or other
|
||||
+ # institution info on their line, so we must get these from the parent entry
|
||||
+ else:
|
||||
+ parent_bankcode = row[3]
|
||||
+ parent_info = bank_map.get(parent_bankcode)
|
||||
+ if parent_info:
|
||||
+ bic = parent_info["bic"]
|
||||
+ name = parent_info["name"]
|
||||
+ else:
|
||||
+ continue
|
||||
|
||||
- def submitInstitute(bankCode, bankName, bic):
|
||||
- if(not existCode(bankCode, bic)):
|
||||
- try:
|
||||
- cursor.execute("INSERT INTO institutions (bankcode, bic, name) VALUES(?,?,?)", (bankCode, bic, bankName))
|
||||
- except sqlite3.Error as e:
|
||||
- print("Error: {0} while inserting {1} ({2})".format(e.args[0], bankCode, bic))
|
||||
+ to_insert.append((bankcode, bic, name))
|
||||
|
||||
- institutesFile = codecs.open(fileName, "r", encoding=args.encoding)
|
||||
- for institute in institutesFile:
|
||||
- bic = institute[284:295].strip()
|
||||
- if len(bic) > 0:
|
||||
- bcNumber = "{:0>5}".format(institute[2:7].strip() if institute[11:16] == " " else institute[11:16].strip())
|
||||
- name = "%s (%s)" % (institute[54:114].strip(), institute[194:229].strip())
|
||||
- submitInstitute(bcNumber, name, bic)
|
||||
- rowsInserted += 1
|
||||
+ cursor = db.cursor()
|
||||
+ cursor.execute("BEGIN")
|
||||
+ try:
|
||||
+ cursor.executemany(
|
||||
+ "INSERT OR IGNORE INTO institutions (bankcode, bic, name) VALUES (?, ?, ?)",
|
||||
+ to_insert
|
||||
+ )
|
||||
+ db.commit()
|
||||
+ return cursor.rowcount
|
||||
+ except sqlite3.Error as e:
|
||||
+ db.rollback()
|
||||
+ print(f"Database error: {e}")
|
||||
+ return 0
|
||||
|
||||
- db.commit()
|
||||
- return rowsInserted
|
||||
-
|
||||
-
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description="Creates a SQLite database for KMyMoney with information about IBAN and BICs based on a swiss BC-Bankenstamm file."
|
||||
- " You can get the BC-Bankenstamm file from https://www.six-group.com/interbank-clearing/de/home/bank-master-data/download-bc-bank-master.html"
|
||||
+ " You can get the BC-Bankenstamm file from https://api.six-group.com/api/epcd/bankmaster/v2/public/downloads/bcbankenstamm"
|
||||
)
|
||||
|
||||
parser.add_argument(dest='file', help='File to load')
|
||||
parser.add_argument('-o', '--output', default="bankdata.ch.db", help='SQLite database to open/generate')
|
||||
- parser.add_argument('-e', '--encoding', default="iso 8859-15", help='Charset of file')
|
||||
args = parser.parse_args()
|
||||
|
||||
- print("Read data from \"{0}\" with \"{1}\" encoding".format(args.file, args.encoding))
|
||||
+ print(f'Read data from "{args.file}"')
|
||||
db = sqlite3.connect(args.output)
|
||||
|
||||
- createTable()
|
||||
- institutions = processFile(args.file)
|
||||
- print("Inserted {0} institutions into database \"{1}\"".format(institutions, args.output))
|
||||
+ create_table()
|
||||
+ institutions = process_file(args.file)
|
||||
+ print(f'Inserted {institutions} institutions into database "{args.output}"')
|
||||
|
||||
cursor = db.cursor()
|
||||
cursor.execute("ANALYZE institutions")
|
||||
Reference in New Issue
Block a user