summaryrefslogtreecommitdiff
path: root/app/views/expenses.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/views/expenses.py')
-rw-r--r--app/views/expenses.py62
1 files changed, 46 insertions, 16 deletions
diff --git a/app/views/expenses.py b/app/views/expenses.py
index 870b45f..23cd42e 100644
--- a/app/views/expenses.py
+++ b/app/views/expenses.py
@@ -9,12 +9,15 @@ from ..model import Category, SingleExpense, CatExpense, MonthExpense
from .. import forms as F
import datetime
-from sqlalchemy import sql, func
+from sqlalchemy import func
from functools import partial
assert_authorisation = partial(assert_authorisation, SingleExpense.get)
mod = Blueprint('expenses', __name__)
+#
+# Form
+#
class ExpenseForm(F.Form):
date = F.DateField(u'Datum', F.req,
format="%d.%m.%Y",
@@ -30,38 +33,52 @@ class ExpenseForm(F.Form):
get_label='name')
def __init__(self, obj = None):
- super(F.Form, self).__init__(obj = obj)
+ super(ExpenseForm, self).__init__(obj = obj)
self.category.query = Category.of(current_user).order_by(Category.name)
+#
+# Utilities
+#
def calc_month_exp(year, month):
+ """Returns the `MonthExpense` for the given month."""
ssum = func.sum(SingleExpense.expense)
query = SingleExpense.of_month(current_user, month, year)
result = query.group_by(SingleExpense.category_id).\
values(SingleExpense.category_id, ssum)
- exps = [CatExpense(Category.query.get(c), s, query.filter(SingleExpense.category_id == c)) for c,s in result]
+ exps = [CatExpense(Category.get(c), s, query.filter(SingleExpense.category_id == c)) for c,s in result]
return MonthExpense(current_user, datetime.date(year, month, 1), exps)
-def pie_stuff(exp):
+
+def pie_data(exp):
+ """Generates the dictionary needed to show the pie diagram.
+ The resulting dict is category → sum of expenses.
+ """
expenses = {}
for c in exp.catexps:
- expenses[c.cat.name] = float(c.expense)
+ expenses[c.cat.name] = float(c.sum)
for c in Category.of(current_user).order_by(Category.name).all():
yield (c.name, expenses.get(c.name, 0.0))
+
def calc_month_and_pie(year, month):
exp = calc_month_exp(year,month)
- pie = pie_stuff(exp)
+ pie = pie_data(exp)
return (exp, dict(pie))
+
def entry_flash(msg, exp):
+ """When changing/adding an entry, a message is shown."""
url = url_for('.edit', id = exp.id)
link = u"<a href=\"%s\">%s</a>" % (url, exp.description)
flash(Markup(msg % link))
+#
+# Template additions
+#
@mod.app_template_filter()
def prev_date(exp):
if exp.date.month == 1:
@@ -69,6 +86,7 @@ def prev_date(exp):
else:
return exp.date.replace(month = exp.date.month - 1)
+
@mod.app_template_filter()
def next_date(exp):
if exp.date.month == 12:
@@ -76,23 +94,19 @@ def next_date(exp):
else:
return exp.date.replace(month = exp.date.month + 1)
+
@mod.app_template_test('last_date')
def is_last(exp):
return exp.date >= today().replace(day = 1)
-@mod.route('/<int(fixed_digits=4):year>/<int(fixed_digits=2):month>')
-@login_required
-@templated('.show')
-def show_date(year, month):
- c,p = calc_month_and_pie(year, month)
- return { 'exps' : [c], 'pies' : [p] }
-
-mod.add_url_rule('/<path:p>', endpoint = 'show_date_str', build_only = True)
-
+#
+# Views
+#
@mod.route('/')
@login_required
@templated
def show():
+ """Show this and the last month."""
d = today()
first, pfirst = calc_month_and_pie(d.year, d.month)
@@ -103,11 +117,25 @@ def show():
return { 'exps' : [first, second], 'pies': [pfirst, psecond] }
+
+@mod.route('/<int(fixed_digits=4):year>/<int(fixed_digits=2):month>')
+@login_required
+@templated('.show')
+def show_date(year, month):
+ """Show the expenses of the specified month."""
+ c,p = calc_month_and_pie(year, month)
+ return { 'exps' : [c], 'pies' : [p] }
+
+# shortcut to allow calling the above route, when year/month is a string
+mod.add_url_rule('/<path:p>', endpoint = 'show_date_str', build_only = True)
+
+
@mod.route('/edit/<int:id>', methods=('GET', 'POST'))
@login_required
@assert_authorisation('id')
@templated
def edit(id):
+ """Edit a single expense, given by `id`."""
exp = SingleExpense.get(id)
form = ExpenseForm(exp)
@@ -127,10 +155,12 @@ def edit(id):
return { 'form': form }
-@mod.route('/add/', methods=('GET', 'POST'))
+
+@mod.route('/add', methods=('GET', 'POST'))
@login_required
@templated
def add():
+ """Add a new expense."""
form = ExpenseForm()
if form.validate_on_submit():