170 lines
5.3 KiB
Python
Executable File
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() |