From 9ebba26b0b6bea8fda81e1e9e01fccdeec12f158 Mon Sep 17 00:00:00 2001 From: nsde Date: Mon, 9 Oct 2023 00:29:33 +0200 Subject: [PATCH] /finances improvements --- .vscode/settings.json | 1 + web/account.py | 1 - web/finances.py | 64 ++++++++++++++++++++++++++++++------- web/templates/finances.html | 44 +++++++++++++++++++------ web/templates/index.html | 6 ++-- 5 files changed, 91 insertions(+), 25 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8e3871d..56451a4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "**/__pycache__": true, "**/.vscode": true, "**/*.map": true, + "**/*.css.map": true, "static/css/base.css": true, "static/css/home.css": true, "static/css/navbar.css": true, diff --git a/web/account.py b/web/account.py index 8ecc703..fa8de60 100755 --- a/web/account.py +++ b/web/account.py @@ -17,7 +17,6 @@ REDIRECT_URI = 'https://nova-oss.com/callback/discord' # REDIRECT_URI = 'http://localhost:2211/callback/discord' SCOPES = ['identify'] -@functools.lru_cache(maxsize=128) def get_user(discord_id: int) -> dict: res = requests.get( url=f'http://localhost:2333/users?discord_id={discord_id}', diff --git a/web/finances.py b/web/finances.py index b8998b5..c86c2b8 100755 --- a/web/finances.py +++ b/web/finances.py @@ -4,6 +4,7 @@ import time import json import flask import requests +import pandas as pd from dotenv import load_dotenv @@ -26,29 +27,70 @@ def register(app): try: data = get_finances() except Exception: - return flask.Response('Error fetching finances from database. This might be cause the data is still being processed. Sorry.', status=500) + return flask.Response('Error fetching finances from database. This might be cause the data is still being processed. Please allow up to a few minutes.', status=500) + + donations = data['donations'] + expenses = data['expenses'] finances = { 'last_update': data['timestamp'], - 'donations_total': round(sum([i['amount_usd'] for i in data['donations']])), - 'donations_num': len(data['donations']), - 'donations_avg': round(sum([i['amount_usd'] for i in data['donations']]) / len(data['donations']), 2), - 'donations_max': round(max([i['amount_usd'] for i in data['donations']])), - 'most_used_donation_currency': max(data['donations'], key=lambda x: x['amount_usd'])['currency'], + 'donations_total': round(sum([i['amount_usd'] for i in donations])), + 'donations_num': len(donations), + 'donations_avg': round(sum([i['amount_usd'] for i in donations]) / len(donations), 2), + 'donations_max': round(max([i['amount_usd'] for i in donations])), + 'most_used_donation_currency': max(donations, key=lambda x: x['amount_usd'])['currency'], - 'expenses_total': round(sum([i['amount_usd'] for i in data['expenses']])), - 'expenses_wages': round(sum([i['amount_usd'] for i in data['expenses'] if i['type'] == 'wage'])), - 'most_used_expense_currency': max(data['expenses'], key=lambda x: x['amount_usd'])['currency'], + 'expenses_total': round(sum([i['amount_usd'] for i in expenses])), + 'expenses_wages': round(sum([i['amount_usd'] for i in expenses if i['type'] == 'wage'])), + 'most_used_expense_currency': max(expenses, key=lambda x: x['amount_usd'])['currency'], } - return flask.render_template('finances.html', finances=finances) + transaction_table = [] + + transactions = [{'change': '+', **donation} for donation in donations] + [{'change': '-', **expense} for expense in expenses] + transactions = sorted(transactions, key=lambda x: x['timestamp'], reverse=True) + + for transaction in transactions: + description = '' + + if transaction['change'] == '+': + description = f'Discord/{transaction["user"]}' + + if transaction['change'] == '-': + description = f'{transaction["reason"]} -> {transaction["to"]}' + + if transaction['currency'] in ['USD', 'EUR', 'GBP', 'CAD', 'AUD', 'NZD', 'CHF', 'JPY', 'CNY', 'HKD', 'SGD']: + transaction['proof'] = '' + + if transaction['change'] == '-': + transaction['amount_usd'] = -transaction['amount_usd'] + + amount = f'{round(transaction["amount_usd"])}' + + transaction_table.append({ + 'Amount (USD)': amount, + 'Currency': transaction['currency'], + 'Type': transaction.get('type', 'donation'), + 'Description': description, + 'Timestamp': time.strftime('%Y-%m-%d %H:%M', time.localtime(transaction['timestamp'])), + 'Proof': transaction['proof'], + }) + + # convert transaction_table to html + transaction_table = pd.DataFrame(transaction_table).to_html( + index=False, + classes=['table', 'table-striped', 'table-hover'], + table_id='transactionTable' + ) + + return flask.render_template('finances.html', finances=finances, transaction_table=transaction_table) @app.route('/finances/json') def finances_download(): try: data = get_finances() except Exception: - return flask.Response('Error fetching finances from database. This might be cause the data is still being processed. Sorry.', status=500) + return flask.Response('Error fetching finances from database. This might be cause the data is still being processed. Please allow up to a few minutes.', status=500) virtual_file = io.StringIO() json.dump(data, virtual_file, indent=4) diff --git a/web/templates/finances.html b/web/templates/finances.html index c32d60f..499754b 100644 --- a/web/templates/finances.html +++ b/web/templates/finances.html @@ -24,23 +24,47 @@ - - -

Expenses

- - - + +

Balance

+ + +

Transactions

+ {{ transaction_table | safe }} + + + + + {% include 'common/end.html' %} \ No newline at end of file diff --git a/web/templates/index.html b/web/templates/index.html index a0c26d0..b8db60f 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -7,12 +7,12 @@ -