diff --git a/app.py b/app.py index da6dd6c..62ba242 100755 --- a/app.py +++ b/app.py @@ -1,10 +1,11 @@ from datetime import datetime -from flask import Flask, render_template, request, abort +from flask import Flask, render_template, request, abort, jsonify import peewee from playhouse.shortcuts import model_to_dict import database +import util app = Flask(__name__) app.config["DEBUG"] = True @@ -105,6 +106,31 @@ def transaction(uuid=None): # Default if no method is hit abort(400) +@app.route("/transactions/visualize", methods=["GET"]) +def visualize_transactions(): + args = request.args.to_dict() + required_args = ['user_id', 'period', 'date'] # Example date format: '2023-01-25' + if not all(arg in args for arg in required_args): + abort(400, "Missing required query parameters: user_id, period, date") + + user_id = args['user_id'].strip() + period = args['period'].strip() + try: + date = datetime.strptime(args['date'], '%Y-%m-%d') + except ValueError: + abort(400, "Invalid date format, use YYYY-MM-DD") + + try: + start_date, end_date = util.get_start_end_dates(period, date) + result = util.aggregate_transactions_by_category(user_id, start_date, end_date) + return jsonify(result) + except ValueError as e: + abort(400, str(e)) + except peewee.DoesNotExist: + abort(404) + except Exception as e: + abort(500, str(e)) + @app.route("/categories", methods=["GET", "POST"]) def categories(): if request.method == "GET": diff --git a/sql_queries.txt b/sql_queries.txt new file mode 100644 index 0000000..de66758 --- /dev/null +++ b/sql_queries.txt @@ -0,0 +1,9 @@ +SELECT + category.name, + SUM(transaction.amount) AS total +FROM "main"."transaction" as transaction +JOIN "main"."transactioncategory" as category ON transaction.subcategory = category.primary_key +WHERE transaction.user = 'faab09bcdcc44038907d054ca990a7f4' + AND transaction.transaction_date >= '2022-10-01' + AND transaction.transaction_date < '2022-11-01' +GROUP BY category.name; diff --git a/util.py b/util.py new file mode 100755 index 0000000..da0e5fe --- /dev/null +++ b/util.py @@ -0,0 +1,33 @@ +from datetime import timedelta +from peewee import fn +import database + +def get_start_end_dates(period, date): + if period == 'daily': + start_date = date + end_date = date + timedelta(days=1) + elif period == 'weekly': + start_date = date - timedelta(days=date.weekday()) + end_date = start_date + timedelta(days=7) + elif period == 'monthly': + start_date = date.replace(day=1) + next_month = start_date + timedelta(days=32) + end_date = next_month.replace(day=1) + elif period == 'yearly': + start_date = date.replace(day=1, month=1) + end_date = start_date.replace(year=start_date.year + 1) + else: + raise ValueError("Invalid period specified") + + return start_date, end_date + +def aggregate_transactions_by_category(user_id, start_date, end_date): + query = (database.Transaction + .select(database.TransactionCategory.name, fn.SUM(database.Transaction.amount).alias('total')) + .join(database.TransactionCategory, on=(database.Transaction.subcategory == database.TransactionCategory.primary_key)) + .where( + (database.Transaction.user == user_id) & + (database.Transaction.transaction_date >= start_date) & + (database.Transaction.transaction_date < end_date)) + .group_by(database.TransactionCategory.name)) + return [{transaction.subcategory.name: transaction.total} for transaction in query] \ No newline at end of file