diff --git a/README.md b/README.md index b59bff8..67a58d2 100644 --- a/README.md +++ b/README.md @@ -18,5 +18,8 @@ Beim ersten Start wird die Datenbank mit einigen Beispielkonten angelegt. * Gewinn- und Verlustrechnung * Bilanz * Umsatzsteuervoranmeldung +* Modernes, responsives Frontend mit Vue unter `/vue_app` + +Das Layout verwendet ein Bootswatch-Theme, wodurch die Anwendung auch auf Handy und Tablet gut aussieht. Die Umsetzung dient nur als Demonstration und ist nicht für den produktiven Einsatz geeignet. diff --git a/app/routes.py b/app/routes.py index 3353bd0..ca6b62f 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,4 +1,4 @@ -from flask import render_template, request, redirect, url_for +from flask import render_template, request, redirect, url_for, jsonify from . import app, db from .models import Account, Entry @@ -6,6 +6,10 @@ def index(): return render_template('index.html') +@app.route('/vue_app') +def vue_app(): + return render_template('vue_app.html') + @app.route('/accounts') def accounts(): accounts = Account.query.order_by(Account.number).all() @@ -26,6 +30,37 @@ def entries(): entries = Entry.query.order_by(Entry.entry_date.desc()).all() return render_template('entries.html', entries=entries, accounts=accounts) +@app.route('/api/accounts') +def api_accounts(): + accounts = Account.query.order_by(Account.number).all() + return jsonify([{'id': a.id, 'number': a.number, 'name': a.name, 'type': a.type} for a in accounts]) + +@app.route('/api/entries', methods=['GET', 'POST']) +def api_entries(): + if request.method == 'POST': + data = request.get_json() + entry = Entry( + debit_id=data['debit_id'], + credit_id=data['credit_id'], + amount=data['amount'], + description=data.get('description', '') + ) + db.session.add(entry) + db.session.commit() + return jsonify({'status': 'success'}) + entries = Entry.query.order_by(Entry.entry_date.desc()).all() + result = [] + for e in entries: + result.append({ + 'id': e.id, + 'entry_date': e.entry_date.isoformat(), + 'description': e.description, + 'debit': {'id': e.debit.id, 'number': e.debit.number, 'name': e.debit.name}, + 'credit': {'id': e.credit.id, 'number': e.credit.number, 'name': e.credit.name}, + 'amount': e.amount + }) + return jsonify(result) + @app.route('/profit_loss') def profit_loss(): income_accounts = Account.query.filter(Account.type=='income').all() diff --git a/app/static/js/app.js b/app/static/js/app.js new file mode 100644 index 0000000..1c881c1 --- /dev/null +++ b/app/static/js/app.js @@ -0,0 +1,38 @@ +const { createApp } = Vue; + +createApp({ + data() { + return { + accounts: [], + entries: [], + newEntry: { + debit_id: '', + credit_id: '', + amount: '', + description: '' + } + }; + }, + methods: { + fetchAccounts() { + axios.get('/api/accounts').then(res => { + this.accounts = res.data; + }); + }, + fetchEntries() { + axios.get('/api/entries').then(res => { + this.entries = res.data; + }); + }, + addEntry() { + axios.post('/api/entries', this.newEntry).then(() => { + this.fetchEntries(); + this.newEntry = { debit_id: '', credit_id: '', amount: '', description: '' }; + }); + } + }, + mounted() { + this.fetchAccounts(); + this.fetchEntries(); + } +}).mount('#app'); diff --git a/app/templates/accounts.html b/app/templates/accounts.html index 0365208..0e16def 100644 --- a/app/templates/accounts.html +++ b/app/templates/accounts.html @@ -1,10 +1,14 @@ {% extends 'base.html' %} {% block content %} -

Konten

- - -{% for acc in accounts %} - -{% endfor %} +

Konten

+
NummerNameTyp
{{ acc.number }}{{ acc.name }}{{ acc.type }}
+ + + + + {% for acc in accounts %} + + {% endfor %} +
NummerNameTyp
{{ acc.number }}{{ acc.name }}{{ acc.type }}
{% endblock %} diff --git a/app/templates/balance.html b/app/templates/balance.html index 1f89a43..a39ec6f 100644 --- a/app/templates/balance.html +++ b/app/templates/balance.html @@ -1,18 +1,22 @@ {% extends 'base.html' %} {% block content %} -

Bilanz

- - -{% for left, right in rows %} - - - - - - -{% endfor %} - - - +

Bilanz

+
AktivaBetragPassivaBetrag
{{ left.name if left else '' }}{{ '%.2f'|format(left.amount) if left else '' }}{{ right.name if right else '' }}{{ '%.2f'|format(right.amount) if right else '' }}
Summe Aktiva{{ '%.2f'|format(asset_total) }}Summe Passiva{{ '%.2f'|format(liability_total) }}
Eigenkapital{{ '%.2f'|format(equity) }}
+ + + + + {% for left, right in rows %} + + + + + + + {% endfor %} + + + +
AktivaBetragPassivaBetrag
{{ left.name if left else '' }}{{ '%.2f'|format(left.amount) if left else '' }}{{ right.name if right else '' }}{{ '%.2f'|format(right.amount) if right else '' }}
Summe Aktiva{{ '%.2f'|format(asset_total) }}Summe Passiva{{ '%.2f'|format(liability_total) }}
Eigenkapital{{ '%.2f'|format(equity) }}
{% endblock %} diff --git a/app/templates/base.html b/app/templates/base.html index eb057ef..df1a0b4 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -2,18 +2,32 @@ + Buchhaltung + -