from . import Blueprint, db, \ current_user, login_required, \ templated, redirect, request from ..model import Category, SingleExpense, CatExpense, MonthExpense from ..forms import ExpenseForm import datetime, decimal from sqlalchemy import sql, func mod = Blueprint('expenses', __name__) def expense_form(obj=None): form = ExpenseForm(obj=obj) form.category.query = Category.of(current_user).order_by(Category.name) return form def calc_month_exp(year, 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] return MonthExpense(current_user, 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.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) 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("//") @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("/", endpoint = "show_date_str", build_only = True) @mod.route("/") @login_required @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/", methods=("GET", "POST")) @login_required @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")) @login_required @templated() def add(): form = expense_form() if form.validate_on_submit(): exp = SingleExpense() form.populate_obj(exp) exp.user = current_user db.session.add(exp) db.session.commit() return redirect(".add") return { 'form': form }