From 60cbf9da2e7bc6d929e3df3af0256b5b81b0505c Mon Sep 17 00:00:00 2001 From: fleaz Date: Tue, 17 Mar 2020 00:12:44 +0100 Subject: [PATCH] Started to use click as a cli --- .gitignore | 3 ++ Pipfile | 3 ++ Pipfile.lock | 69 ++++++++++++++++++++++--- create.py | 7 +-- import.py | 45 ---------------- importer.py | 47 +++++++++++++++++ main.py | 13 +++++ restart.sh | 3 +- serve.py | 17 +++++- sort.py | 61 ++++++++++++---------- transactions.csv | 120 ------------------------------------------- views/categories.tpl | 5 +- 12 files changed, 181 insertions(+), 212 deletions(-) delete mode 100644 import.py create mode 100644 importer.py create mode 100755 main.py delete mode 100644 transactions.csv diff --git a/.gitignore b/.gitignore index 50af006..28c20f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ *.pyc app.db app.db +*.sta +*.csv +*.TXT diff --git a/Pipfile b/Pipfile index 1499eb6..81b4abd 100644 --- a/Pipfile +++ b/Pipfile @@ -4,11 +4,14 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] +flake8 = "*" [packages] sqlalchemy = "*" prompt-toolkit = "*" bottle = "*" +mt-940 = "*" +click = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index fbd3b37..cc6f4f2 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e8dc56266a4018b0bdb774d18144085e717b5a9792bedfc7cb1325c78a641c19" + "sha256": "25b9941c75b9e81082b3302534b779bedf7a24979213c97e7da0524201b2f333" }, "pipfile-spec": 6, "requires": { @@ -24,20 +24,36 @@ "index": "pypi", "version": "==0.12.18" }, - "prompt-toolkit": { + "click": { "hashes": [ - "sha256:a402e9bf468b63314e37460b68ba68243d55b2f8c4d0192f85a019af3945050e", - "sha256:c93e53af97f630f12f5f62a3274e79527936ed466f038953dfa379d4941f651a" + "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", + "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" ], "index": "pypi", - "version": "==3.0.3" + "version": "==7.1.1" + }, + "mt-940": { + "hashes": [ + "sha256:95e55584908c7d51b8a08cfb55d72297f06385e40c9baf9258cdaaf26811aafa", + "sha256:fad1a00df51ede762d7d5e4d019de9ad86357d7556862b259ce7fba400ac2d6e" + ], + "index": "pypi", + "version": "==4.20.0" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:859e1b205b6cf6a51fa57fa34202e45365cf58f8338f0ee9f4e84a4165b37d5b", + "sha256:ebe6b1b08c888b84c50d7f93dee21a09af39860144ff6130aadbd61ae8d29783" + ], + "index": "pypi", + "version": "==3.0.4" }, "sqlalchemy": { "hashes": [ - "sha256:64a7b71846db6423807e96820993fa12a03b89127d278290ca25c0b11ed7b4fb" + "sha256:c4cca4aed606297afbe90d4306b49ad3a4cd36feb3f87e4bfd655c57fd9ef445" ], "index": "pypi", - "version": "==1.3.13" + "version": "==1.3.15" }, "wcwidth": { "hashes": [ @@ -47,5 +63,42 @@ "version": "==0.1.8" } }, - "develop": {} + "develop": { + "entrypoints": { + "hashes": [ + "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", + "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" + ], + "version": "==0.3" + }, + "flake8": { + "hashes": [ + "sha256:45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb", + "sha256:49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca" + ], + "index": "pypi", + "version": "==3.7.9" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "version": "==2.5.0" + }, + "pyflakes": { + "hashes": [ + "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", + "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" + ], + "version": "==2.1.1" + } + } } diff --git a/create.py b/create.py index 664120d..2b1ecbf 100644 --- a/create.py +++ b/create.py @@ -11,9 +11,4 @@ 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() +Base.metadata.create_all(engine) \ No newline at end of file diff --git a/import.py b/import.py deleted file mode 100644 index aa27fab..0000000 --- a/import.py +++ /dev/null @@ -1,45 +0,0 @@ -#! /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), description=description) - session.add(t) - session.commit() - count += 1 - print(".", end="", flush=True) -print() -print(f"Imported {count} transactions") diff --git a/importer.py b/importer.py new file mode 100644 index 0000000..6964a00 --- /dev/null +++ b/importer.py @@ -0,0 +1,47 @@ +#! /usr/bin/env python3 +import mt940 +import click +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(t): + return int(t.amount * 100) + +@click.command(name='import') +@click.argument('filename', type=click.Path(exists=True)) +def command(filename): + click.echo(click.format_filename(filename)) + 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() + + transactions = mt940.parse("2020-01.TXT") + count = 0 + for t in transactions: + data = t.data + + date = data['date'] + amount = convert_amount(data['amount']) + iban = data['applicant_iban'] + name = data['applicant_name'] + description = data['purpose'] + + if latest and data['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=amount, description=description) + session.add(t) + session.commit() + count += 1 + print(".", end="", flush=True) + print() + print(f"Imported {count} transactions") diff --git a/main.py b/main.py new file mode 100755 index 0000000..4cb0f7c --- /dev/null +++ b/main.py @@ -0,0 +1,13 @@ +#! /usr/bin/env python3 +import click +import sort, importer, serve + +@click.group() +def cli(): + pass + +if __name__ == '__main__': + cli.add_command(sort.command) + cli.add_command(importer.command) + cli.add_command(serve.command) + cli() \ No newline at end of file diff --git a/restart.sh b/restart.sh index 46d24ce..6724d84 100755 --- a/restart.sh +++ b/restart.sh @@ -2,5 +2,4 @@ rm -rf app.db python create.py python categories.py -python import.py -python sort.py +python importer.py diff --git a/serve.py b/serve.py index 45ffb07..02b667a 100644 --- a/serve.py +++ b/serve.py @@ -1,9 +1,10 @@ #! /usr/bin/env python3 -from bottle import route, run, template +from bottle import route, run, template, redirect from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from models import * +import click engine = create_engine("sqlite:///app.db") Base = declarative_base() @@ -32,9 +33,21 @@ def category(name): return template('category', category=c,transactions=transactions) +@route('/category//delete') +def category(name): + c = session.query(Category).filter(Category.name==name).first() + if c: + session.delete(c) + session.commit() + + return redirect("/categories") + @route('/transactions') def transactions(): transactions = session.query(Transaction).all() return template('transactions', transactions=transactions) -run(host='localhost', port=8080, reloader=True) + +@click.command(name='serve') +def command(): + run(host='localhost', port=8080, reloader=True,debug=True) diff --git a/sort.py b/sort.py index f38bda8..9429866 100644 --- a/sort.py +++ b/sort.py @@ -5,40 +5,45 @@ from sqlalchemy.ext.declarative import declarative_base from models import * from categories import add_category import sys +import click 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() +@click.command(name='sort') +def command(): + engine = create_engine("sqlite:///app.db") + Base = declarative_base() -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]) + Session = sessionmaker(bind=engine) + session = Session() -unsorted = session.query(Transaction).filter(Transaction.category_id == None).all() -print("Found {} unsorted transcations".format(len(unsorted))) + 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() + else: + print(f"Creating new category '{select}'") + add_category(select) + + print("-" * 20) -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() - else: - print(f"Creating new category '{select}'") - add_category(select) - - print("-" * 20) diff --git a/transactions.csv b/transactions.csv deleted file mode 100644 index 2db3074..0000000 --- a/transactions.csv +++ /dev/null @@ -1,120 +0,0 @@ -"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";"" diff --git a/views/categories.tpl b/views/categories.tpl index 88e1671..ce6b69f 100644 --- a/views/categories.tpl +++ b/views/categories.tpl @@ -3,6 +3,9 @@ List of categories: