import csv from datetime import timedelta from django.http import HttpResponse from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.utils import timezone from .models import Category, Expense, FixedExpenseConcept from .forms import ExpenseForm @login_required def dashboard(request): form = ExpenseForm() context = {"form": form} return render(request, "pages/expenses/dashboard.html", context) @login_required def add_expense(request): if request.method == "POST": form = ExpenseForm(request.POST) if form.is_valid(): form.save() return redirect("expenses:expense_success") context = {"form": form} return render(request, "pages/expenses/dashboard.html", context) return redirect("expenses:dashboard") @login_required def expense_success(request): return render(request, "pages/expenses/expense_success.html") @login_required def week_view(request): from collections import OrderedDict from decimal import Decimal today = timezone.localdate() offset = int(request.GET.get("offset", 0)) monday = today - timedelta(days=today.weekday()) + timedelta(weeks=offset) sunday = monday + timedelta(days=6) expenses = Expense.objects.filter( created_at__date__gte=monday, created_at__date__lte=sunday, ).select_related("category", "subcategory") categories_data = OrderedDict() total = Decimal("0") for expense in expenses: cat = expense.category if cat.id not in categories_data: categories_data[cat.id] = { "category": cat, "expenses": [], "subcategory_totals": OrderedDict(), "total": Decimal("0"), } entry = categories_data[cat.id] entry["expenses"].append(expense) entry["total"] += expense.amount total += expense.amount sub = expense.subcategory if sub.id not in entry["subcategory_totals"]: entry["subcategory_totals"][sub.id] = { "subcategory": sub, "total": Decimal("0"), } entry["subcategory_totals"][sub.id]["total"] += expense.amount is_current_week = offset == 0 context = { "categories_data": categories_data.values(), "total": total, "monday": monday, "sunday": sunday, "offset": offset, "prev_offset": offset - 1, "next_offset": offset + 1, "is_current_week": is_current_week, } return render(request, "pages/expenses/week.html", context) @login_required def settings_view(request): categories = Category.objects.all().prefetch_related("subcategories") fixed_expenses = FixedExpenseConcept.objects.all() context = {"categories": categories, "fixed_expenses": fixed_expenses} return render(request, "pages/expenses/settings.html", context) @login_required def export_csv(request): response = HttpResponse(content_type="text/csv") response["Content-Disposition"] = 'attachment; filename="kakebo_expenses.csv"' response.write("\ufeff") # BOM for Excel UTF-8 writer = csv.writer(response, delimiter=";") writer.writerow(["Date", "Concept", "Amount", "Category", "Subcategory"]) expenses = Expense.objects.all().select_related("category", "subcategory") for expense in expenses: writer.writerow( [ expense.created_at.strftime("%Y-%m-%d"), expense.concept, str(expense.amount), expense.category.name, expense.subcategory.name, ] ) return response