From 9c59b349c2c0432624625731cc14e8c8b610a65e Mon Sep 17 00:00:00 2001 From: fleaz Date: Wed, 4 Mar 2020 23:36:49 +0100 Subject: [PATCH] Initial --- .gitignore | 3 ++ Pipfile | 13 +++++ Pipfile.lock | 43 +++++++++++++++++ categories.py | 43 +++++++++++++++++ create.py | 19 ++++++++ import.py | 45 ++++++++++++++++++ models.py | 39 +++++++++++++++ restart.sh | 6 +++ sort.py | 40 ++++++++++++++++ transactions.csv | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 371 insertions(+) create mode 100644 .gitignore create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100644 categories.py create mode 100644 create.py create mode 100644 import.py create mode 100644 models.py create mode 100755 restart.sh create mode 100644 sort.py create mode 100644 transactions.csv diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..50af006 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.pyc +app.db +app.db diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..02f3dd0 --- /dev/null +++ b/Pipfile @@ -0,0 +1,13 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +sqlalchemy = "*" +prompt-toolkit = "*" + +[requires] +python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..dcb2a65 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,43 @@ +{ + "_meta": { + "hash": { + "sha256": "3abcef8be3462b1da61e99b34940773733b8cf76fc3ef77890b2d05098144f49" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.8" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "prompt-toolkit": { + "hashes": [ + "sha256:a402e9bf468b63314e37460b68ba68243d55b2f8c4d0192f85a019af3945050e", + "sha256:c93e53af97f630f12f5f62a3274e79527936ed466f038953dfa379d4941f651a" + ], + "index": "pypi", + "version": "==3.0.3" + }, + "sqlalchemy": { + "hashes": [ + "sha256:64a7b71846db6423807e96820993fa12a03b89127d278290ca25c0b11ed7b4fb" + ], + "index": "pypi", + "version": "==1.3.13" + }, + "wcwidth": { + "hashes": [ + "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603", + "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8" + ], + "version": "==0.1.8" + } + }, + "develop": {} +} diff --git a/categories.py b/categories.py new file mode 100644 index 0000000..03c70fd --- /dev/null +++ b/categories.py @@ -0,0 +1,43 @@ +#! /usr/bin/env python3 +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.ext.declarative import declarative_base +from models import * +import sys + +from prompt_toolkit.completion import FuzzyWordCompleter +from prompt_toolkit.shortcuts import prompt + +engine = create_engine("sqlite:///app.db") +Base = declarative_base() + +Session = sessionmaker(bind=engine) +session = Session() + +# categories = session.query(Category).all() + + +def create_category(name, parent=None): + c = session.query(Category).filter(Category.name == name).first() + if not c: + c = Category(name=name, parent_id=parent) + session.add(c) + session.commit() + return c.id + + +def add_category(name): + parts = name.split(":") + if len(parts) == 1: + create_category(name) + else: + for i in range(len(parts) - 1): + parent = parts[i] + child = parts[i + 1] + parent_id = create_category(parent) + create_category(child, parent=parent_id) + + +names = ["Ausgaben", "Einnahmen", "Ausgaben:Miete", "Einnahmen:Gehalt", "Ausgaben:Nahrung"] +for c in names: + add_category(c) diff --git a/create.py b/create.py new file mode 100644 index 0000000..664120d --- /dev/null +++ b/create.py @@ -0,0 +1,19 @@ +#! /usr/bin/env python3 +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.ext.declarative import declarative_base + +engine = create_engine("sqlite:///app.db") +Base = declarative_base() + +Session = sessionmaker(bind=engine) +session = Session() + +from models import * + +Base.metadata.create_all(engine) + +for name in ["Haus", "Maus", "Spielzeug"]: + c = Category(name=name) + session.add(c) +session.commit() diff --git a/import.py b/import.py new file mode 100644 index 0000000..3a54497 --- /dev/null +++ b/import.py @@ -0,0 +1,45 @@ +#! /usr/bin/env python3 +import csv +from datetime import datetime +from sqlalchemy import create_engine, desc +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from models import Transaction +import sys + + +def convert_amount(s): + s = s.replace(",", "") + return int(float(s) * 100) + + +engine = create_engine("sqlite:///app.db") +Base = declarative_base() + +Session = sessionmaker(bind=engine) +session = Session() + +latest = session.query(Transaction).order_by(desc(Transaction.date)).first() + +with open("transactions.csv") as fh: + fh.readline() # Get rid of first line + csv_reader = csv.reader(fh, delimiter=";") + count = 0 + for line in csv_reader: + date = datetime.strptime(line[0], "%Y-%m-%d") + amount = line[2] + iban = line[4] + name = line[5] + description = line[6] + + if latest and date < latest.date: + print("Found transaction older than then oldest transction in the DB. Aborting") + sys.exit(1) + + t = Transaction(date=date, name=name, iban=iban, amount=convert_amount(amount) * 100) + session.add(t) + session.commit() + count += 1 + print(".", end="", flush=True) +print() +print(f"Imported {count} transactions") diff --git a/models.py b/models.py new file mode 100644 index 0000000..c93d45e --- /dev/null +++ b/models.py @@ -0,0 +1,39 @@ +#! /usr/bin/env python3 +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy import Column, Integer, String, DateTime, ForeignKey +from sqlalchemy.orm import relationship, backref + +Base = declarative_base() + + +class Transaction(Base): + __tablename__ = "Transaction" + id = Column(Integer, primary_key=True) + name = Column(String) + date = Column(DateTime) + iban = Column(String) + amount = Column(Integer) + description = Column(String) + category_id = Column(Integer, ForeignKey("Category.id")) + + +class Category(Base): + __tablename__ = "Category" + id = Column(Integer, primary_key=True) + name = Column(String) + transactions = relationship("Category") + parent_id = Column(Integer, ForeignKey("Category.id")) + children = relationship("Category", backref=backref("parent", remote_side=[id])) + + def __repr__(self): + return f"" + + def is_child(self): + # we are a child if we have zero children + return len(self.children) == 0 + + def full_name(self): + if not self.parent: + return self.name + else: + return f"{self.parent.full_name()}:{self.name}" diff --git a/restart.sh b/restart.sh new file mode 100755 index 0000000..46d24ce --- /dev/null +++ b/restart.sh @@ -0,0 +1,6 @@ +#! /bin/bash +rm -rf app.db +python create.py +python categories.py +python import.py +python sort.py diff --git a/sort.py b/sort.py new file mode 100644 index 0000000..798abbc --- /dev/null +++ b/sort.py @@ -0,0 +1,40 @@ +#! /usr/bin/env python3 +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.ext.declarative import declarative_base +from models import * +import sys + +from prompt_toolkit.completion import FuzzyWordCompleter +from prompt_toolkit.shortcuts import prompt + +engine = create_engine("sqlite:///app.db") +Base = declarative_base() + +Session = sessionmaker(bind=engine) +session = Session() + +categories = session.query(Category).all() +category_lookup = [{c.full_name: c.id} for c in categories] +category_names = FuzzyWordCompleter([c.full_name() for c in categories]) + +unsorted = session.query(Transaction).filter(Transaction.category_id == None).all() +print("Found {} unsorted transcations".format(len(unsorted))) + + +for t in unsorted: + print(" Name: {}".format(t.name)) + print(" VWZ: {}".format(t.description)) + print("Betrag: {}€".format(t.amount / 100)) + try: + select = prompt("Category: ", completer=category_names, complete_while_typing=True) + except KeyboardInterrupt: + print("Goodbye") + sys.exit(0) + cat_id = category_lookup.get(select, None) + if cat_id: + t.category_id = cat_id + session.add(t) + session.commit() + + print("-" * 20) diff --git a/transactions.csv b/transactions.csv new file mode 100644 index 0000000..2db3074 --- /dev/null +++ b/transactions.csv @@ -0,0 +1,120 @@ +"Date";"Interest Date";"Amount";"Account";"Counterparty";"Name";"Description" +"2019-08-01";"2019-08-01";"10.27";"NL33BUNQ2035704715";"DE27100110012624718836";"Thomas Schulze";"Auslagen codemonauts" +"2019-08-01";"2019-08-01";"0.04";"NL33BUNQ2035704715";"NL93BUNQ2036147313";"bunq";"Interest payment" +"2019-08-01";"2019-08-02";"-30.00";"NL33BUNQ2035704715";"DE97830654080004031172";"Verein zur Förderung Freier Netze in Mittelhessen e.V";"ZSH LKW, fleaz" +"2019-08-01";"2019-08-01";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-01";"2019-08-02";"-288.46";"NL33BUNQ2035704715";"DE88508635130004470516";"MANFRED KLIEFKEN-SCHMIDT";"Breidenstein Felix, Mieter, Im Biengarten 10, 64297 Eberstadt" +"2019-08-01";"2019-08-01";"-1.54";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-02";"2019-08-02";"-11.64";"NL33BUNQ2035704715";"";"REWE Darmstadt Hei";"REWE Darmstadt Hei Darmstadt, DE" +"2019-08-02";"2019-08-02";"-0.36";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-03";"2019-08-03";"-50.00";"NL33BUNQ2035704715";"";"POSTBANK BERGER STR. 4";"POSTBANK BERGER STR. 4 FRANKFURT, DE" +"2019-08-03";"2019-08-03";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-04";"2019-08-04";"-11.26";"NL33BUNQ2035704715";"";"McDonalds 1736";"McDonalds 1736 Pfungstadt, DE" +"2019-08-04";"2019-08-04";"-0.74";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-04";"2019-08-04";"-2.89";"NL33BUNQ2035704715";"";"McDonalds 1736";"McDonalds 1736 Pfungstadt, DE" +"2019-08-04";"2019-08-04";"-1.11";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-05";"2019-08-05";"7.90";"NL33BUNQ2035704715";"DE27100110012624718836";"Thomas Schulze";"Currywurst" +"2019-08-05";"2019-09-01";"-5.41";"NL33BUNQ2035704715";"";"REWE Frankfurt/Bor";"REWE Frankfurt/Bor Frankfurt am, DE" +"2019-08-05";"2019-08-05";"-0.59";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-06";"2019-08-06";"-100.00";"NL33BUNQ2035704715";"";"HANAU 28";"HANAU 28 Hanau >, DE" +"2019-08-06";"2019-08-06";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-07";"2019-08-07";"10.00";"NL33BUNQ2035704715";"NL67BUNQ2036142834";"bunq";"bunq Reward" +"2019-08-11";"2019-08-11";"-12.35";"NL33BUNQ2035704715";"";"Hanau Hbf";"Hanau Hbf Hanau, DE" +"2019-08-11";"2019-08-11";"-1.65";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-12";"2019-08-12";"-11.01";"NL33BUNQ2035704715";"";"REWE Frankfurt/Nor";"REWE Frankfurt/Nor Frankfurt, DE" +"2019-08-12";"2019-08-12";"-0.99";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-12";"2019-08-13";"-300.00";"NL33BUNQ2035704715";"DE22120300001019770922";"Felix Breidenstein";"" +"2019-08-12";"2019-08-12";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-12";"2019-09-01";"-8.70";"NL33BUNQ2035704715";"";"PAYPAL";"PAYPAL 35314369001, DE" +"2019-08-12";"2019-08-12";"-1.30";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-12";"2019-09-01";"-429.00";"NL33BUNQ2035704715";"";"PAYPAL *SECONDITSTO";"PAYPAL *SECONDITSTO 35314369001, DE" +"2019-08-12";"2019-08-12";"-1.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-12";"2019-09-01";"-62.08";"NL33BUNQ2035704715";"";"KAUFLAND PFUNGSTADT 22";"KAUFLAND PFUNGSTADT 22 PFUNGSTADT, DE" +"2019-08-12";"2019-08-12";"-1.92";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-13";"2019-08-13";"-3.96";"NL33BUNQ2035704715";"";"REWE Frankfurt/Bor";"REWE Frankfurt/Bor Frankfurt am, DE" +"2019-08-13";"2019-08-13";"-0.04";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-13";"2019-09-01";"-1.50";"NL33BUNQ2035704715";"";"PP*9778CODE";"PP*9778CODE 35314369001, DE" +"2019-08-13";"2019-08-13";"-0.50";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-13";"2019-09-01";"-29.74";"NL33BUNQ2035704715";"";"ONLINE";"ONLINE PARIS, FR" +"2019-08-13";"2019-09-01";"-0.89";"NL33BUNQ2035704715";"";"AWS EMEA";"AWS EMEA aws.amazon.co, LU 1.00 USD, 1 USD = 0.89000 EUR" +"2019-08-13";"2019-08-14";"-12.89";"NL33BUNQ2035704715";"DE87300308801908262006";"Amazon Payments Europe S.C.A.";"49991379690543" +"2019-08-13";"2019-08-13";"-1.11";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-13";"2019-08-14";"-9.16";"NL33BUNQ2035704715";"DE87300308801908262006";"Amazon Payments Europe S.C.A.";"22140883725963" +"2019-08-13";"2019-08-13";"-0.84";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-13";"2019-08-14";"-28.99";"NL33BUNQ2035704715";"DE87300308801908262006";"Amazon Payments Europe S.C.A.";"87385356146263" +"2019-08-13";"2019-08-13";"-1.01";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-14";"2019-08-14";"-5.07";"NL33BUNQ2035704715";"";"REWE Frankfurt/Bor";"REWE Frankfurt/Bor Frankfurt am, DE" +"2019-08-14";"2019-08-14";"-0.93";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-14";"2019-08-14";"-31.45";"NL33BUNQ2035704715";"";"BAUHAUS 574";"BAUHAUS 574 DARMSTADT, DE" +"2019-08-14";"2019-08-14";"-0.55";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-14";"2019-08-14";"-26.86";"NL33BUNQ2035704715";"";"TOTAL Service Station";"TOTAL Service Station DARMSTADT, DE" +"2019-08-14";"2019-08-14";"-1.14";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-14";"2019-08-14";"-50.00";"NL33BUNQ2035704715";"";"SPARKASSE DARMSTADT";"SPARKASSE DARMSTADT 010-GAA-FY, DE" +"2019-08-14";"2019-08-14";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-14";"2019-09-01";"1.50";"NL33BUNQ2035704715";"";"PP*9778CODE";"Refund: PP*9778CODE (35314369001, 000)" +"2019-08-15";"2019-08-15";"-64.16";"NL33BUNQ2035704715";"";"KAUFLAND PFUNGSTADT 22";"KAUFLAND PFUNGSTADT 22 PFUNGSTADT, DE" +"2019-08-15";"2019-08-15";"-1.84";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-16";"2019-08-16";"-19.46";"NL33BUNQ2035704715";"";"REWE Darmstadt Rue";"REWE Darmstadt Rue Darmstadt, DE" +"2019-08-16";"2019-08-16";"-0.54";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-17";"2019-08-15";"-25.49";"NL33BUNQ2035704715";"DE87300500000008996811";"Drillisch Online GmbH";"C3079895 U293132603 B360994149 WINSIM B2C.DE" +"2019-08-17";"2019-08-17";"-0.51";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-17";"2019-08-17";"-11.17";"NL33BUNQ2035704715";"";"REWE Darmstadt Hei";"REWE Darmstadt Hei Darmstadt, DE" +"2019-08-17";"2019-08-17";"-0.83";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-18";"2019-08-16";"-2.96";"NL33BUNQ2035704715";"DE44701600000000142108";"Hetzner Online GmbH";"Rechnungsnr.: R0009973290 - Kundennr.: K0717063016" +"2019-08-18";"2019-08-18";"-1.04";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-18";"2019-09-01";"-21.90";"NL33BUNQ2035704715";"";"Lieferando.de";"Lieferando.de Amsterdam, NL" +"2019-08-18";"2019-08-18";"-0.10";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-19";"2019-08-19";"-2.90";"NL33BUNQ2035704715";"";"Filialagentur der Dits";"Filialagentur der Dits Darmstadt, DE" +"2019-08-19";"2019-08-19";"-1.10";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-19";"2019-08-19";"-10.22";"NL33BUNQ2035704715";"";"REWE 597 Darmstadt Bah";"REWE 597 Darmstadt Bah Darmstadt, DE" +"2019-08-19";"2019-08-19";"-1.78";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-19";"2019-09-01";"-5.73";"NL33BUNQ2035704715";"";"KAUFLAND PFUNGSTADT 22";"KAUFLAND PFUNGSTADT 22 PFUNGSTADT, DE" +"2019-08-19";"2019-08-19";"-0.27";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-20";"2019-09-01";"-11.14";"NL33BUNQ2035704715";"";"REWE Darmstadt Hei";"REWE Darmstadt Hei Darmstadt, DE" +"2019-08-20";"2019-08-20";"-0.86";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-20";"2019-09-01";"-13.37";"NL33BUNQ2035704715";"";"KAUFLAND PFUNGSTADT 22";"KAUFLAND PFUNGSTADT 22 PFUNGSTADT, DE" +"2019-08-20";"2019-08-20";"-0.63";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-21";"2019-08-21";"-100.00";"NL33BUNQ2035704715";"";"Berliner Volksbank eG";"Berliner Volksbank eG Zehdenick, DE" +"2019-08-21";"2019-08-21";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-22";"2019-09-01";"-9.99";"NL33BUNQ2035704715";"";"PAYPAL *MKUEHL";"PAYPAL *MKUEHL 35314369001, DE" +"2019-08-22";"2019-08-22";"-0.01";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-22";"2019-09-01";"-6.43";"NL33BUNQ2035704715";"";"REWE (KT) Pfungstadt";"REWE (KT) Pfungstadt Pfungstadt, DE" +"2019-08-22";"2019-08-22";"-1.57";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-23";"2019-09-01";"-6.18";"NL33BUNQ2035704715";"";"PAYPAL *MM TRADING";"PAYPAL *MM TRADING 35314369001, DE" +"2019-08-23";"2019-08-23";"-1.82";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-23";"2019-09-01";"-4.40";"NL33BUNQ2035704715";"";"PAYPAL *CHENYITIAN2";"PAYPAL *CHENYITIAN2 35314369001, DE" +"2019-08-23";"2019-08-23";"-1.60";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-23";"2019-09-01";"-18.76";"NL33BUNQ2035704715";"";"KAUFLAND PFUNGSTADT 22";"KAUFLAND PFUNGSTADT 22 PFUNGSTADT, DE" +"2019-08-23";"2019-08-23";"-1.24";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-25";"2019-09-01";"-11.99";"NL33BUNQ2035704715";"";"PAYPAL *NETFLIX.COM";"PAYPAL *NETFLIX.COM 35314369001, LU" +"2019-08-25";"2019-08-25";"-0.01";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-25";"2019-08-23";"-32.52";"NL33BUNQ2035704715";"DE27510900000044145103";"book-n-drive mobilitaetssysteme GmbH";"10269521908141 Ihre Rechnung vom 14.08.19" +"2019-08-25";"2019-08-25";"-1.48";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-28";"2019-09-01";"-7.34";"NL33BUNQ2035704715";"";"REWE Frankfurt/Bor";"REWE Frankfurt/Bor Frankfurt am, DE" +"2019-08-28";"2019-08-28";"-0.66";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-28";"2019-09-01";"-7.49";"NL33BUNQ2035704715";"";"BAUHAUS 574";"BAUHAUS 574 DARMSTADT, DE" +"2019-08-28";"2019-08-28";"-0.51";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-29";"2019-09-01";"-6.00";"NL33BUNQ2035704715";"";"PAYPAL *FREDERIKSTE";"PAYPAL *FREDERIKSTE 35314369001, DE" +"2019-08-29";"2019-08-29";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-08-30";"25.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-08-30";"-20.00";"NL33BUNQ2035704715";"";"REISEB FFM-HBF GLEIS 1";"REISEB FFM-HBF GLEIS 1 FRANKFURT, DE" +"2019-08-30";"2019-08-30";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-09-01";"-5.90";"NL33BUNQ2035704715";"";"PAYPAL *ZHUTINGMAOY";"PAYPAL *ZHUTINGMAOY 35314369001, DE" +"2019-08-30";"2019-08-30";"-0.10";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-09-01";"-6.29";"NL33BUNQ2035704715";"";"PAYPAL *MM TRADING";"PAYPAL *MM TRADING 35314369001, DE" +"2019-08-30";"2019-08-30";"-1.71";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-08-30";"1,956.14";"NL33BUNQ2035704715";"NL84BUNQ2035424534";"codemonauts UG (haftungsbeschränkt)";"Gehalt 08/2019" +"2019-08-30";"2019-08-30";"-300.00";"NL33BUNQ2035704715";"DE22120300001019770922";"Felix Breidenstein";"" +"2019-08-30";"2019-08-30";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-08-30";"-25.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix";"" +"2019-08-30";"2019-09-01";"-49.17";"NL33BUNQ2035704715";"";"AMAZON DE MARKETPLACE";"AMAZON DE MARKETPLACE WWW.AMAZON.DE, LU" +"2019-08-30";"2019-08-30";"-0.83";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-09-01";"-11.29";"NL33BUNQ2035704715";"";"PP*HUMBLEBUNDL HUMBLEB";"PP*HUMBLEBUNDL HUMBLEB 4029357733, US" +"2019-08-30";"2019-08-30";"-0.71";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-08-30";"9.40";"NL33BUNQ2035704715";"DE27100110012624718836";"Thomas Schulze";"Auslagen codemonauts" +"2019-08-30";"2019-08-30";"-90.00";"NL33BUNQ2035704715";"";"SPARKASSE DARMSTADT";"SPARKASSE DARMSTADT 015-GAA-F2, DE" +"2019-08-30";"2019-08-30";"-2.00";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-30";"2019-09-01";"-18.51";"NL33BUNQ2035704715";"";"REWE Darmstadt Hei";"REWE Darmstadt Hei Darmstadt, DE" +"2019-08-30";"2019-08-30";"-1.49";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";"" +"2019-08-31";"2019-09-01";"-9.99";"NL33BUNQ2035704715";"";"PAYPAL *SPOTIFY";"PAYPAL *SPOTIFY 35314369001, GB" +"2019-08-31";"2019-08-31";"-0.01";"NL33BUNQ2035704715";"NL82BUNQ2035817226";"Felix Breidenstein";""