Updated snapshot views as class-based views

This commit is contained in:
Edgar P. Burkhart 2022-12-28 12:18:20 +01:00
parent a43ed6c039
commit ecf8962562
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227
5 changed files with 113 additions and 149 deletions

View file

@ -203,9 +203,11 @@ class Snapshot(models.Model):
def save(self, *args, only_super=False, **kwargs): def save(self, *args, only_super=False, **kwargs):
if not only_super: if not only_super:
if Snapshot.objects.filter(id=self.id).exists():
_prever = Snapshot.objects.get(id=self.id) _prever = Snapshot.objects.get(id=self.id)
if _prever.file and _prever.file != self.file: if _prever.file and _prever.file != self.file:
pathlib.Path(_prever.file.path).unlink(missing_ok=True) pathlib.Path(_prever.file.path).unlink(missing_ok=True)
_prev = ( _prev = (
self.__class__.objects.order_by("-date") self.__class__.objects.order_by("-date")
.exclude(id=self.id) .exclude(id=self.id)
@ -266,6 +268,16 @@ class Snapshot(models.Model):
else: else:
super().delete(*args, **kwargs) super().delete(*args, **kwargs)
def get_absolute_url(self):
return reverse("snapshot", kwargs={"pk": self.pk})
def get_delete_url(self):
return reverse("del_snapshot", kwargs={"pk": self.pk})
@property
def adding(self):
return self._state.adding
@property @property
def sum(self): def sum(self):
if self.previous is None: if self.previous is None:

View file

@ -1,82 +0,0 @@
{% extends "main/base.html" %}
{% load static %}
{% load main_extras %}
{% load i18n %}
{% block link %}
{{ block.super }}
<link rel="stylesheet"
href="{% static 'main/css/form.css' %}"
type="text/css"/>
<link rel="stylesheet"
href="{% static 'main/css/table.css' %}"
type="text/css"/>
<link rel="stylesheet"
href="{% static 'main/css/chart.css' %}"
type="text/css"/>
{% endblock %}
{% block body %}
{% with sum=snapshot.sum %}
<h1>
{% if snapshot.previous is not None %}
{% if sum == snapshot.diff %}
<i class="fa fa-check green"></i>
{% else %}
<i class="fa fa-xmark red"></i>
{% endif %}
{% endif %}
{{ snapshot }}
</h1>
<form action="{% url 'snapshot' snapshot.id %}"
method="post"
enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
{% form_buttons snapshot %}
</form>
{% if categories %}
<h2>{% translate "Categories" %}</h2>
<div class="chart">
{% for cat in categories %}
<div class="name">
{% if cat.category %}
<i class="fa fa-{{ cat.category__icon }}"></i>
<a href="{% url 'category' cat.category %}">{{ cat.category__name }}</a>
{% else %}
<i class="fa fa-wallet"></i></i>
{% endif %}
</div>
<div class="value left">{{ cat.sum_m|pmvalue }}</div>
<div class="left">
<div class="bar bar_m"
style="width:{% widthratio cat.sum_m cat_lim_m 100 %}%"
title="{{ cat.sum_m }}"></div>
{% if cat.sum < 0 %}
<div class="bar tot"
style="width:{% widthratio cat.sum cat_lim_m 100 %}%"
title="{{ cat.sum }}">
<span>{{ cat.sum|pmvalue }}</span>
</div>
{% endif %}
</div>
<div class="right">
<div class="bar bar_p"
style="width:{% widthratio cat.sum_p cat_lim 100 %}%"
title="{{ cat.sum_p }}"></div>
{% if cat.sum >= 0 %}
<div class="bar tot"
style="width:{% widthratio cat.sum cat_lim 100 %}%"
title="{{ cat.sum }}">
<span>{{ cat.sum|pmvalue }}</span>
</div>
{% endif %}
</div>
<div class="value right">{{ cat.sum_p|pmvalue }}</div>
{% endfor %}
</div>
{% endif %}
{% if snapshot.transactions %}
<h2>{% translate "Transactions" %} ({{ sum|pmvalue }} / {{ snapshot.diff|pmvalue }})</h2>
{% transaction_table snapshot.transactions %}
{% endif %}
{% endwith %}
{% endblock %}

View file

@ -0,0 +1,79 @@
{% extends "main/base.html" %}
{% load static %}
{% load main_extras %}
{% load i18n %}
{% block link %}
{{ block.super }}
<link rel="stylesheet"
href="{% static 'main/css/form.css' %}"
type="text/css"/>
<link rel="stylesheet"
href="{% static 'main/css/table.css' %}"
type="text/css"/>
<link rel="stylesheet"
href="{% static 'main/css/chart.css' %}"
type="text/css"/>
{% endblock %}
{% block body %}
{% with snapshot=form.instance %}
<h1>
{% if snapshot.previous is not None %}
{% if snapshot.sum == snapshot.diff %}
<i class="fa fa-check green"></i>
{% else %}
<i class="fa fa-xmark red"></i>
{% endif %}
{% endif %}
{{ snapshot }}
</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
</form>
{% if categories %}
<h2>{% translate "Categories" %}</h2>
<div class="chart">
{% for cat in categories %}
<div class="name">
{% if cat.category %}
<i class="fa fa-{{ cat.category__icon }}"></i>
<a href="{% url 'category' cat.category %}">{{ cat.category__name }}</a>
{% else %}
<i class="fa fa-wallet"></i></i>
{% endif %}
</div>
<div class="value left">{{ cat.sum_m|pmvalue }}</div>
<div class="left">
<div class="bar bar_m"
style="width:{% widthratio cat.sum_m cat_lim_m 100 %}%"
title="{{ cat.sum_m }}"></div>
{% if cat.sum < 0 %}
<div class="bar tot"
style="width:{% widthratio cat.sum cat_lim_m 100 %}%"
title="{{ cat.sum }}">
<span>{{ cat.sum|pmvalue }}</span>
</div>
{% endif %}
</div>
<div class="right">
<div class="bar bar_p"
style="width:{% widthratio cat.sum_p cat_lim 100 %}%"
title="{{ cat.sum_p }}"></div>
{% if cat.sum >= 0 %}
<div class="bar tot"
style="width:{% widthratio cat.sum cat_lim 100 %}%"
title="{{ cat.sum }}">
<span>{{ cat.sum|pmvalue }}</span>
</div>
{% endif %}
</div>
<div class="value right">{{ cat.sum_p|pmvalue }}</div>
{% endfor %}
</div>
{% endif %}
{% if snapshot.transactions %}
<h2>{% translate "Transactions" %} ({{ snapshot.sum|pmvalue }} / {{ snapshot.diff|pmvalue }})</h2>
{% transaction_table snapshot.transactions %}
{% endif %}
{% endwith %}
{% endblock %}

View file

@ -14,6 +14,7 @@ urlpatterns = [
name="invoice", name="invoice",
), ),
path("category", views.CategoryCreateView.as_view(), name="category"), path("category", views.CategoryCreateView.as_view(), name="category"),
path("snapshot", views.SnapshotCreateView.as_view(), name="snapshot"),
path("transaction/<pk>", views.TransactionUpdateView.as_view(), name="transaction"), path("transaction/<pk>", views.TransactionUpdateView.as_view(), name="transaction"),
path( path(
"transaction/<transaction_pk>/invoice/<pk>", "transaction/<transaction_pk>/invoice/<pk>",
@ -21,6 +22,7 @@ urlpatterns = [
name="invoice", name="invoice",
), ),
path("category/<pk>", views.CategoryUpdateView.as_view(), name="category"), path("category/<pk>", views.CategoryUpdateView.as_view(), name="category"),
path("snapshot/<pk>", views.SnapshotUpdateView.as_view(), name="snapshot"),
path( path(
"transaction/<pk>/delete", "transaction/<pk>/delete",
views.TransactionDeleteView.as_view(), views.TransactionDeleteView.as_view(),
@ -34,9 +36,9 @@ urlpatterns = [
path( path(
"category/<pk>/delete", views.CategoryDeleteView.as_view(), name="del_category" "category/<pk>/delete", views.CategoryDeleteView.as_view(), name="del_category"
), ),
path("snapshot", views.snapshot, name="snapshot"), path(
path("snapshot/<uuid>", views.snapshot, name="snapshot"), "snapshot/<pk>/delete", views.SnapshotDeleteView.as_view(), name="del_snapshot"
path("snapshot/<uuid>/del", views.del_snapshot, name="del_snapshot"), ),
path("search", views.search, name="search_post"), path("search", views.search, name="search_post"),
path("search/<search>", views.SearchView.as_view(), name="search"), path("search/<search>", views.SearchView.as_view(), name="search"),
] ]

View file

@ -80,6 +80,11 @@ class CategoryCreateView(LoginRequiredMixin, CreateView):
form_class = CategoryForm form_class = CategoryForm
class SnapshotCreateView(LoginRequiredMixin, CreateView):
model = Snapshot
form_class = SnapshotForm
class TransactionUpdateView(LoginRequiredMixin, UpdateView): class TransactionUpdateView(LoginRequiredMixin, UpdateView):
model = Transaction model = Transaction
form_class = TransactionForm form_class = TransactionForm
@ -103,6 +108,11 @@ class CategoryUpdateView(LoginRequiredMixin, UpdateView):
form_class = CategoryForm form_class = CategoryForm
class SnapshotUpdateView(LoginRequiredMixin, UpdateView):
model = Snapshot
form_class = SnapshotForm
class TransactionDeleteView(LoginRequiredMixin, DeleteView): class TransactionDeleteView(LoginRequiredMixin, DeleteView):
model = Transaction model = Transaction
template_name = "main/confirm_delete.html" template_name = "main/confirm_delete.html"
@ -128,67 +138,10 @@ class CategoryDeleteView(LoginRequiredMixin, DeleteView):
success_url = reverse_lazy("index") success_url = reverse_lazy("index")
@login_required class SnapshotDeleteView(LoginRequiredMixin, DeleteView):
def snapshot(request, uuid=None): model = Snapshot
if request.method == "GET": template_name = "main/confirm_delete.html"
if uuid is None: success_url = reverse_lazy("index")
_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)
@login_required @login_required