nummi/nummi/main/views.py

201 lines
5.8 KiB
Python

from django.contrib.auth import views as auth_views
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator
from django.db import models
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.views.generic import ListView
from .models import (
Category,
CategoryForm,
Invoice,
InvoiceForm,
Snapshot,
SnapshotForm,
Transaction,
TransactionForm,
)
@login_required
def index(request):
_transactions = Transaction.objects.all()[:10]
_categories = Category.objects.all()
_snapshots = Snapshot.objects.all()
context = {
"transactions": _transactions,
"categories": _categories,
"snapshots": _snapshots,
}
return render(request, "main/index.html", context)
class LoginView(auth_views.LoginView):
template_name = "main/login.html"
next_page = "index"
class LogoutView(auth_views.LogoutView):
next_page = "login"
class TransactionListView(LoginRequiredMixin, ListView):
paginate_by = 64
model = Transaction
template_name = "main/transactions.html"
context_object_name = "transactions"
@login_required
def transaction(request, uuid=None):
_form = None
_inv_form = None
if request.method == "GET":
if uuid is None:
_transaction = Transaction()
else:
_transaction = get_object_or_404(Transaction, id=uuid)
elif request.method == "POST":
if request.POST["form"] == "transaction":
_transaction, _ = Transaction.objects.get_or_create(id=uuid)
_form = TransactionForm(request.POST, instance=_transaction)
if _form.is_valid():
_form.save()
_inv_form = InvoiceForm(instance=Invoice(transaction=_transaction))
elif request.POST["form"] == "invoice":
_transaction = get_object_or_404(Transaction, id=uuid)
_invoice = Invoice(transaction=_transaction)
_inv_form = InvoiceForm(request.POST, request.FILES, instance=_invoice)
if _inv_form.is_valid():
_inv_form.save()
return render(
request,
"main/transaction.html",
{
"transaction": _transaction,
"form": _form or TransactionForm(instance=_transaction),
"invoice_form": _inv_form
or InvoiceForm(instance=Invoice(transaction=_transaction)),
},
)
@login_required
def del_transaction(request, uuid):
_transaction = get_object_or_404(Transaction, id=uuid)
_transaction.delete()
return redirect(index)
@login_required
def invoice(request, uuid):
_invoice = get_object_or_404(Invoice, id=uuid)
with _invoice.file.open() as _file:
return HttpResponse(_file.read(), content_type="application/pdf")
@login_required
def del_invoice(request, uuid, invoice_id):
_invoice = get_object_or_404(Invoice, id=invoice_id)
_invoice.delete()
return redirect(transaction, uuid=uuid)
@login_required
def category(request, uuid=None):
if request.method == "GET":
if uuid is None:
_category = Category()
else:
_category = get_object_or_404(Category, id=uuid)
_form = CategoryForm(instance=_category)
elif request.method == "POST":
_category, _ = Category.objects.get_or_create(id=uuid)
_form = CategoryForm(request.POST, instance=_category)
if _form.is_valid():
_form.save()
return render(
request,
"main/category.html",
{
"category": _category,
"form": _form,
"transactions": Transaction.objects.filter(category=_category),
"adding": _category._state.adding,
},
)
@login_required
def del_category(request, uuid):
_category = get_object_or_404(Category, id=uuid)
_category.delete()
return redirect(index)
@login_required
def snapshot(request, uuid=None):
if request.method == "GET":
if uuid is None:
_snapshot = Snapshot()
else:
_snapshot = get_object_or_404(Snapshot, id=uuid)
context = {
"snapshot": _snapshot,
"form": SnapshotForm(instance=_snapshot),
}
elif request.method == "POST":
try:
_snapshot = Snapshot.objects.get(id=uuid)
except Snapshot.DoesNotExist:
_snapshot = Snapshot(id=uuid)
_form = SnapshotForm(request.POST, request.FILES, instance=_snapshot)
if _form.is_valid():
_form.save()
return redirect(snapshot, uuid=uuid)
context = {
"snapshot": _snapshot,
"form": _form,
}
if _snapshot.transactions:
context["categories"] = (
_snapshot.transactions.filter(category__budget=True)
.values("category", "category__name", "category__icon")
.annotate(
sum=models.Sum("value"),
sum_m=models.Sum("value", filter=models.Q(value__lt=0)),
sum_p=models.Sum("value", filter=models.Q(value__gt=0)),
)
.order_by("-sum")
)
context["cat_lim"] = max(
map(
lambda x: abs(x) if x else 0,
context["categories"]
.aggregate(
max=models.Max("sum_p"),
min=models.Min("sum_m"),
)
.values(),
)
)
context["cat_lim_m"] = -context["cat_lim"]
return render(
request,
"main/snapshot.html",
context,
)
@login_required
def del_snapshot(request, uuid):
_snapshot = get_object_or_404(Snapshot, id=uuid)
_snapshot.delete()
return redirect(index)