summaryrefslogtreecommitdiff
path: root/app/views/expenses.py
blob: 893c36702c579814c46d151a14a54d5b46033b78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from ..flask_extend import Blueprint
from flask import request

import datetime, decimal
from sqlalchemy import sql, func

from ..model import db, Category, SingleExpense, CatExpense, MonthExpense

from ..forms import ExpenseForm
from ..utils import templated, redirect

mod = Blueprint('expenses', __name__)

def expense_form(obj=None):
    form = ExpenseForm(obj=obj)
    form.category.query = Category.query.order_by(Category.name)
    return form

def calc_month_exp(year, month):
    ssum = func.sum(SingleExpense.expense)
    query = SingleExpense.of_month(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]

    return MonthExpense(datetime.date(year, month, 1), exps)

def pie_stuff(exp):
    expenses = {}
    for c in exp.catexps:
        expenses[c.cat.name] = float(c.expense)

    for c in Category.query.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)
    return (exp, dict(pie))

@mod.app_template_filter()
def prev_date(exp):
    if exp.date.month == 1:
        return exp.date.replace(year = exp.date.year - 1, month = 12)
    else:
        return exp.date.replace(month = exp.date.month - 1)

@mod.app_template_filter()
def next_date(exp):
    if exp.date.month == 12:
        return exp.date.replace(year = exp.date.year + 1, month = 1)
    else:
        return exp.date.replace(month = exp.date.month + 1)

@mod.app_template_test("last_date")
def is_last(exp):
    return exp.date >= datetime.date.today().replace(day = 1)

@mod.route("/<int(fixed_digits=4):year>/<int(fixed_digits=2):month>")
@templated(".show")
def show_date(year, month):
    c = calc_month_exp(year, month)
    return { 'exps' : [c] }

mod.add_url_rule("/<path:p>", endpoint = "show_date_str", build_only = True)

@mod.route("/")
@templated()
def show():
    d = datetime.date.today()
            
    first, pfirst = calc_month_and_pie(d.year, d.month)
    if d.month == 1:
        second, psecond = calc_month_and_pie(d.year - 1, 12)
    else:
        second, psecond = calc_month_and_pie(d.year, d.month - 1)

    return { 'exps' : [first, second], 'pies': [pfirst, psecond] }

@mod.route("/edit/<int:id>", methods=("GET", "POST"))
@templated()
def edit(id):
    exp = SingleExpense.get(id)
    form = expense_form(exp)

    if request.method == "POST":
        if "deleteB" in request.form:
            db.session.delete(exp)

        elif form.validate(): # change
            form.populate_obj(exp)

        else:
            return { 'form': form }

        db.session.commit()
        return redirect("index")

    return { 'form': form }

@mod.route("/add/", methods=("GET", "POST"))
@templated()
def add():
    form = expense_form()

    if form.validate_on_submit():
        exp = SingleExpense()

        form.populate_obj(exp)

        db.session.add(exp)
        db.session.commit()

        return redirect(".add")

    return { 'form': form }