Add snapshot form
This commit is contained in:
parent
4b784a553b
commit
cb458cf472
17 changed files with 159 additions and 372 deletions
|
@ -1,7 +1,10 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-20 12:24
|
||||
# Generated by Django 4.0.4 on 2022-05-22 07:45
|
||||
|
||||
import datetime
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import re
|
||||
import uuid
|
||||
|
||||
|
||||
|
@ -24,8 +27,25 @@ class Migration(migrations.Migration):
|
|||
serialize=False,
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=256)),
|
||||
(
|
||||
"name",
|
||||
models.CharField(
|
||||
default="New Category",
|
||||
max_length=64,
|
||||
validators=[
|
||||
django.core.validators.RegexValidator(
|
||||
re.compile("^[-\\w]+\\Z"),
|
||||
"Enter a valid “slug” consisting of Unicode letters, numbers, underscores, or hyphens.",
|
||||
"invalid",
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
("icon", models.CharField(default="folder", max_length=64)),
|
||||
],
|
||||
options={
|
||||
"ordering": ["name"],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Transaction",
|
||||
|
@ -39,10 +59,14 @@ class Migration(migrations.Migration):
|
|||
serialize=False,
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=256)),
|
||||
("description", models.TextField()),
|
||||
("value", models.DecimalField(decimal_places=2, max_digits=12)),
|
||||
("date", models.DateField()),
|
||||
("name", models.CharField(default="New Transaction", max_length=256)),
|
||||
("description", models.TextField(blank=True, null=True)),
|
||||
(
|
||||
"value",
|
||||
models.DecimalField(decimal_places=2, default=0, max_digits=12),
|
||||
),
|
||||
("date", models.DateField(default=datetime.date.today)),
|
||||
("trader", models.CharField(blank=True, max_length=128, null=True)),
|
||||
(
|
||||
"category",
|
||||
models.ForeignKey(
|
||||
|
@ -53,6 +77,47 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"ordering": ["-date"],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Snapshot",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("date", models.DateField(default=datetime.date.today, unique=True)),
|
||||
(
|
||||
"value",
|
||||
models.DecimalField(decimal_places=2, default=0, max_digits=12),
|
||||
),
|
||||
(
|
||||
"diff",
|
||||
models.DecimalField(
|
||||
decimal_places=2, default=0, editable=False, max_digits=12
|
||||
),
|
||||
),
|
||||
(
|
||||
"previous",
|
||||
models.OneToOneField(
|
||||
blank=True,
|
||||
editable=False,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="main.snapshot",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"ordering": ["-date"],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Invoice",
|
||||
|
@ -66,8 +131,16 @@ class Migration(migrations.Migration):
|
|||
serialize=False,
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=256)),
|
||||
("file", models.FileField(upload_to="invoices/")),
|
||||
("name", models.CharField(default="New Invoice", max_length=256)),
|
||||
(
|
||||
"file",
|
||||
models.FileField(
|
||||
upload_to="invoices/",
|
||||
validators=[
|
||||
django.core.validators.FileExtensionValidator(["pdf"])
|
||||
],
|
||||
),
|
||||
),
|
||||
(
|
||||
"transaction",
|
||||
models.ForeignKey(
|
||||
|
@ -77,29 +150,4 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="SubCategory",
|
||||
fields=[
|
||||
(
|
||||
"category_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="main.category",
|
||||
),
|
||||
),
|
||||
(
|
||||
"parent",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="category_parent",
|
||||
to="main.category",
|
||||
),
|
||||
),
|
||||
],
|
||||
bases=("main.category",),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-20 12:30
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name="SubCategory",
|
||||
),
|
||||
]
|
|
@ -1,29 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-20 13:33
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0002_delete_subcategory"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="category",
|
||||
name="parent",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="main.category",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="category",
|
||||
name="name",
|
||||
field=models.CharField(max_length=64),
|
||||
),
|
||||
]
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-20 14:17
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0003_category_parent_alter_category_name"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="category",
|
||||
options={"ordering": ["-parent_id", "name"]},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="category",
|
||||
name="full_name",
|
||||
field=models.CharField(default="", max_length=512),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-20 14:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0004_alter_category_options_category_full_name"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="category",
|
||||
name="full_name",
|
||||
field=models.CharField(default="", editable=False, max_length=512),
|
||||
),
|
||||
]
|
|
@ -1,67 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-20 16:06
|
||||
|
||||
import datetime
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
import re
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0005_alter_category_full_name"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="category",
|
||||
options={"ordering": ["full_name"]},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="transaction",
|
||||
name="trader",
|
||||
field=models.CharField(blank=True, max_length=128, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="category",
|
||||
name="name",
|
||||
field=models.CharField(
|
||||
max_length=64,
|
||||
validators=[
|
||||
django.core.validators.RegexValidator(
|
||||
re.compile("^[-\\w]+\\Z"),
|
||||
"Enter a valid “slug” consisting of Unicode letters, numbers, underscores, or hyphens.",
|
||||
"invalid",
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="invoice",
|
||||
name="file",
|
||||
field=models.FileField(
|
||||
upload_to="invoices/",
|
||||
validators=[django.core.validators.FileExtensionValidator(["pdf"])],
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="transaction",
|
||||
name="date",
|
||||
field=models.DateField(default=datetime.date.today),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="transaction",
|
||||
name="description",
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="transaction",
|
||||
name="name",
|
||||
field=models.CharField(default="Transaction", max_length=256),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="transaction",
|
||||
name="value",
|
||||
field=models.DecimalField(decimal_places=2, default=0, max_digits=12),
|
||||
),
|
||||
]
|
|
@ -1,56 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-20 19:25
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
import re
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0006_alter_category_options_transaction_trader_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="category",
|
||||
options={},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name="transaction",
|
||||
options={"ordering": ["-date"]},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="category",
|
||||
name="full_name",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="category",
|
||||
name="parent",
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="category",
|
||||
name="name",
|
||||
field=models.CharField(
|
||||
default="New Category",
|
||||
max_length=64,
|
||||
validators=[
|
||||
django.core.validators.RegexValidator(
|
||||
re.compile("^[-\\w]+\\Z"),
|
||||
"Enter a valid “slug” consisting of Unicode letters, numbers, underscores, or hyphens.",
|
||||
"invalid",
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="invoice",
|
||||
name="name",
|
||||
field=models.CharField(default="New Invoice", max_length=256),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="transaction",
|
||||
name="name",
|
||||
field=models.CharField(default="New Transaction", max_length=256),
|
||||
),
|
||||
]
|
|
@ -1,22 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-20 20:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0007_alter_category_options_alter_transaction_options_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="category",
|
||||
options={"ordering": ["name"]},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="category",
|
||||
name="icon",
|
||||
field=models.CharField(default="folder", max_length=64),
|
||||
),
|
||||
]
|
|
@ -1,44 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-21 18:40
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0008_alter_category_options_category_icon"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Snapshot",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("date", models.DateField(default=datetime.date.today)),
|
||||
(
|
||||
"value",
|
||||
models.DecimalField(decimal_places=2, default=0, max_digits=12),
|
||||
),
|
||||
(
|
||||
"previous",
|
||||
models.OneToOneField(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="main.snapshot",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -1,25 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-21 18:44
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0009_snapshot"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="snapshot",
|
||||
name="previous",
|
||||
field=models.OneToOneField(
|
||||
blank=True,
|
||||
editable=False,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="main.snapshot",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -1,30 +0,0 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-22 06:43
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("main", "0010_alter_snapshot_previous"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="snapshot",
|
||||
options={"ordering": ["-date"]},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="snapshot",
|
||||
name="diff",
|
||||
field=models.DecimalField(
|
||||
decimal_places=2, default=0, editable=False, max_digits=12
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="snapshot",
|
||||
name="date",
|
||||
field=models.DateField(default=datetime.date.today, unique=True),
|
||||
),
|
||||
]
|
|
@ -94,6 +94,7 @@ class Snapshot(models.Model):
|
|||
if not only_super:
|
||||
_prev = (
|
||||
self.__class__.objects.order_by("-date")
|
||||
.exclude(id=self.id)
|
||||
.filter(date__lt=self.date)
|
||||
.first()
|
||||
)
|
||||
|
@ -139,3 +140,9 @@ class Snapshot(models.Model):
|
|||
|
||||
class Meta:
|
||||
ordering = ["-date"]
|
||||
|
||||
|
||||
class SnapshotForm(ModelForm):
|
||||
class Meta:
|
||||
model = Snapshot
|
||||
fields = ["date", "value"]
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
class="{% if request.resolver_match.url_name == "category" %} cur{% endif %}">
|
||||
Add category
|
||||
</a>
|
||||
<a href="{% url 'snapshot' %}"
|
||||
class="{% if request.resolver_match.url_name == "snapshot" %} cur{% endif %}">
|
||||
Add snapshot
|
||||
</a>
|
||||
<a href="{% url 'logout' %}"
|
||||
class="logout">
|
||||
Log Out
|
||||
|
|
|
@ -55,7 +55,9 @@
|
|||
</div>
|
||||
{% for snap in snapshots %}
|
||||
<div class="snapshot {% cycle 'w' 'g' %}">
|
||||
<span class="date num center">{{ snap.date|date:"Y-m-d" }}</span>
|
||||
<span class="date num center">
|
||||
<a href="{% url 'snapshot' snap.date %}">{{ snap.date|date:"Y-m-d" }}</a>
|
||||
</span>
|
||||
<span class="value num right">{{ snap.value|floatformat:"2g" }} €</span>
|
||||
<span class="diff num right">{{ snap.diff|floatformat:"2g"|pm }} €</span>
|
||||
{% with sum=snap.sum %}
|
||||
|
|
26
nummi/main/templates/main/snapshot.html
Normal file
26
nummi/main/templates/main/snapshot.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
{% extends "main/base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block link %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" href="{% static 'main/css/form.css' %}" type="text/css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>{{ snapshot }}</h1>
|
||||
|
||||
<form action="{% url 'update_snapshot' snapshot.id %}" method="post">
|
||||
{% csrf_token %}
|
||||
{% for field in form %}
|
||||
{{ field.errors }}
|
||||
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
<div class="buttons">
|
||||
<a href="{% url 'del_snapshot' snapshot.date %}"><input type="button" value="Delete" /></a>
|
||||
<input type="reset" />
|
||||
<input type="submit" value="Save Snapshot" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
|
@ -21,4 +21,8 @@ urlpatterns = [
|
|||
path("category", views.category, name="category"),
|
||||
path("category/<uuid>", views.category, name="category"),
|
||||
path("category/<uuid>/update", views.update_category, name="update_category"),
|
||||
path("snapshot", views.snapshot, name="snapshot"),
|
||||
path("snapshot/<date>", views.snapshot, name="snapshot"),
|
||||
path("snapshot/update/<uuid>", views.update_snapshot, name="update_snapshot"),
|
||||
path("snapshot/<date>/del", views.del_snapshot, name="del_snapshot"),
|
||||
]
|
||||
|
|
|
@ -11,6 +11,7 @@ from .models import (
|
|||
Category,
|
||||
CategoryForm,
|
||||
Snapshot,
|
||||
SnapshotForm,
|
||||
)
|
||||
|
||||
|
||||
|
@ -59,10 +60,7 @@ def transaction(request, uuid=None):
|
|||
|
||||
@login_required
|
||||
def update_transaction(request, uuid):
|
||||
try:
|
||||
_transaction = Transaction.objects.get(id=uuid)
|
||||
except Transaction.DoesNotExist:
|
||||
_transaction = Transaction(id=uuid)
|
||||
_transaction, _ = Transaction.objects.get_or_create(id=uuid)
|
||||
_form = TransactionForm(request.POST, instance=_transaction)
|
||||
_form.save()
|
||||
return redirect(transaction, uuid=uuid)
|
||||
|
@ -112,10 +110,38 @@ def category(request, uuid=None):
|
|||
|
||||
@login_required
|
||||
def update_category(request, uuid):
|
||||
try:
|
||||
_category = Category.objects.get(id=uuid)
|
||||
except Category.DoesNotExist:
|
||||
_category = Category(id=uuid)
|
||||
_category, _ = Category.objects.get_or_create(id=uuid)
|
||||
_form = CategoryForm(request.POST, instance=_category)
|
||||
_form.save()
|
||||
return redirect(category, uuid=uuid)
|
||||
|
||||
|
||||
@login_required
|
||||
def snapshot(request, date=None):
|
||||
if date is None:
|
||||
_snapshot = Snapshot()
|
||||
else:
|
||||
_snapshot = get_object_or_404(Snapshot, date=date)
|
||||
return render(
|
||||
request,
|
||||
"main/snapshot.html",
|
||||
{
|
||||
"snapshot": _snapshot,
|
||||
"form": SnapshotForm(instance=_snapshot),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
def update_snapshot(request, uuid):
|
||||
_snapshot, _ = Snapshot.objects.get_or_create(id=uuid)
|
||||
_form = SnapshotForm(request.POST, instance=_snapshot)
|
||||
_form.save()
|
||||
return redirect(snapshot, date=_snapshot.date)
|
||||
|
||||
|
||||
@login_required
|
||||
def del_snapshot(request, date):
|
||||
_snapshot = get_object_or_404(Snapshot, date=date)
|
||||
_snapshot.delete()
|
||||
return redirect(index)
|
||||
|
|
Loading…
Reference in a new issue