Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-ports
Path: blob/main/finance/ktoblzcheck-data/files/patch-src_switzerland.py
27950 views
1
- Adapt to SIX Group converting their bankdata to CSV (semicolon separated).
2
- Don't use codecs.open(); deprecated in Python 3.14.
3
4
--- src/switzerland.py.orig 2025-05-15 11:18:20 UTC
5
+++ src/switzerland.py
6
@@ -24,12 +24,11 @@ KMyMoney
7
@author: Christian David
8
"""
9
10
-import sqlite3
11
-import codecs
12
import argparse
13
-import os
14
+import csv
15
+import sqlite3
16
17
-def createTable():
18
+def create_table():
19
""" Create table structure
20
"""
21
cursor = db.cursor()
22
@@ -45,59 +44,65 @@ def createTable():
23
)
24
db.commit()
25
26
-
27
-def processFile(fileName):
28
+def process_file(filename):
29
""" Fills the database with institutions saved in fileName
30
"""
31
+ with open(filename, 'r', newline='') as institutes_file:
32
+ reader = list(csv.reader(institutes_file, delimiter=';'))
33
+ rows = reader[1:]
34
35
- rowsInserted = 0
36
- cursor = db.cursor()
37
- cursor.execute("BEGIN")
38
+ bank_map = {row[0]: {"bic": row[14], "name": f"{row[8]} ({row[12]})"} for row in rows}
39
40
- def existCode(bankCode, bic):
41
- cursor.execute("SELECT bankcode,bic FROM institutions WHERE bankcode = ? and bic = ?",(bankCode,bic,))
42
- row_exist = cursor.fetchone()
43
- if row_exist is None:
44
- return False
45
+ to_insert = []
46
+ for row in rows:
47
+ bankcode = row[0].zfill(5)
48
49
- return True
50
+ # Non-concatenated "parent" entries
51
+ if row[2] == 'N':
52
+ bic = row[14]
53
+ name = f"{row[8]} ({row[12]})"
54
+ # Some bankcodes are concatenated onto other bankcodes without the BIC or other
55
+ # institution info on their line, so we must get these from the parent entry
56
+ else:
57
+ parent_bankcode = row[3]
58
+ parent_info = bank_map.get(parent_bankcode)
59
+ if parent_info:
60
+ bic = parent_info["bic"]
61
+ name = parent_info["name"]
62
+ else:
63
+ continue
64
65
- def submitInstitute(bankCode, bankName, bic):
66
- if(not existCode(bankCode, bic)):
67
- try:
68
- cursor.execute("INSERT INTO institutions (bankcode, bic, name) VALUES(?,?,?)", (bankCode, bic, bankName))
69
- except sqlite3.Error as e:
70
- print("Error: {0} while inserting {1} ({2})".format(e.args[0], bankCode, bic))
71
+ to_insert.append((bankcode, bic, name))
72
73
- institutesFile = codecs.open(fileName, "r", encoding=args.encoding)
74
- for institute in institutesFile:
75
- bic = institute[284:295].strip()
76
- if len(bic) > 0:
77
- bcNumber = "{:0>5}".format(institute[2:7].strip() if institute[11:16] == " " else institute[11:16].strip())
78
- name = "%s (%s)" % (institute[54:114].strip(), institute[194:229].strip())
79
- submitInstitute(bcNumber, name, bic)
80
- rowsInserted += 1
81
+ cursor = db.cursor()
82
+ cursor.execute("BEGIN")
83
+ try:
84
+ cursor.executemany(
85
+ "INSERT OR IGNORE INTO institutions (bankcode, bic, name) VALUES (?, ?, ?)",
86
+ to_insert
87
+ )
88
+ db.commit()
89
+ return cursor.rowcount
90
+ except sqlite3.Error as e:
91
+ db.rollback()
92
+ print(f"Database error: {e}")
93
+ return 0
94
95
- db.commit()
96
- return rowsInserted
97
-
98
-
99
if __name__ == '__main__':
100
parser = argparse.ArgumentParser(description="Creates a SQLite database for KMyMoney with information about IBAN and BICs based on a swiss BC-Bankenstamm file."
101
- " 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"
102
+ " You can get the BC-Bankenstamm file from https://api.six-group.com/api/epcd/bankmaster/v2/public/downloads/bcbankenstamm"
103
)
104
105
parser.add_argument(dest='file', help='File to load')
106
parser.add_argument('-o', '--output', default="bankdata.ch.db", help='SQLite database to open/generate')
107
- parser.add_argument('-e', '--encoding', default="iso 8859-15", help='Charset of file')
108
args = parser.parse_args()
109
110
- print("Read data from \"{0}\" with \"{1}\" encoding".format(args.file, args.encoding))
111
+ print(f'Read data from "{args.file}"')
112
db = sqlite3.connect(args.output)
113
114
- createTable()
115
- institutions = processFile(args.file)
116
- print("Inserted {0} institutions into database \"{1}\"".format(institutions, args.output))
117
+ create_table()
118
+ institutions = process_file(args.file)
119
+ print(f'Inserted {institutions} institutions into database "{args.output}"')
120
121
cursor = db.cursor()
122
cursor.execute("ANALYZE institutions")
123
124