budget-bear/app.py
Sara Montecino 3d048feb9a WIP
2024-02-13 23:05:17 -08:00

170 lines
5.3 KiB
Python
Executable File

from datetime import datetime
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
@app.before_request
def before_request():
database.instance.connect()
@app.after_request
def after_request(response):
database.instance.close()
return response
@app.route("/")
def home():
puppies = ['hollie', 'grace', 'loki']
return render_template('index.html', puppies=puppies)
@app.route("/users")
def users():
args = request.args.to_dict()
if 'username' not in args:
abort(400)
username = args['username'].strip()
try:
return model_to_dict(database.User.get(database.User.username == username))
except peewee.DoesNotExist:
abort(404)
except:
abort(500)
@app.route("/transactions", methods=["GET", "POST"])
def transactions():
if request.method == "GET":
args = request.args.to_dict()
if 'user_id' not in args:
abort(400)
user_id = args['user_id'].strip()
try:
july_2022 = datetime(2022, 7, 1, 0)
transactions = database.Transaction.select().where(
(database.Transaction.user == user_id) &
(database.Transaction.transaction_date > july_2022)
)
return [model_to_dict(t) for t in transactions]
except peewee.DoesNotExist:
abort(404)
except:
abort(500)
if request.method == "POST":
body = request.get_json()
try:
user = database.User.get(database.User.uuid == body['user_id'])
category = database.TransactionCategory.get(database.TransactionCategory.name == body['category'])
database.Transaction.create(
user=user,
subcategory=category,
transaction_date=body['transaction_date'],
description=body['description'],
amount=body['amount'],
type=body['type'],
notes=body['notes']
)
return ('', 200)
except peewee.DoesNotExist:
abort(404)
except KeyError:
abort(400)
# Default if no method is hit
abort(400)
@app.route("/transactions/<uuid>", methods=["PUT"])
def transaction(uuid=None):
if request.method == "PUT":
if not uuid:
abort(400)
body = request.get_json()
if 'category' not in body or 'notes' not in body:
abort(400)
try:
category = database.TransactionCategory.get(database.TransactionCategory.name == body['category'])
transaction = database.Transaction.get(database.Transaction.primary_key == uuid)
transaction.subcategory = category
transaction.notes = body['notes']
transaction.save()
return ('', 200)
except peewee.DoesNotExist:
abort(404)
except:
abort(500)
# 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":
try:
raw_categories = database.TransactionCategory.select()
categories = {}
for category in raw_categories:
if not category.parent:
categories[category.name] = []
for category in raw_categories:
if category.parent:
categories[category.parent.name].append(category.name)
return categories
except peewee.DoesNotExist:
abort(404)
except:
abort(500)
if request.method == "POST":
body = request.get_json()
try:
if 'parent' in body:
parent = database.TransactionCategory.get(database.TransactionCategory.name == body['parent'])
database.TransactionCategory.create(name=body['name'], parent=parent)
else:
database.TransactionCategory.create(name=body['name'])
return ('', 200)
except peewee.DoesNotExist:
abort(404)
except:
abort(500)
# Should never get here.
abort(500)
app.run()