From cb458cf472ca6121c9b20c3b00d5588410efc6fd Mon Sep 17 00:00:00 2001 From: "Edgar P. Burkhart" Date: Sun, 22 May 2022 10:06:44 +0200 Subject: [PATCH] Add snapshot form --- nummi/main/migrations/0001_initial.py | 114 +++++++++++++----- .../migrations/0002_delete_subcategory.py | 16 --- ...003_category_parent_alter_category_name.py | 29 ----- ...ter_category_options_category_full_name.py | 23 ---- .../0005_alter_category_full_name.py | 18 --- ...ory_options_transaction_trader_and_more.py | 67 ---------- ...ions_alter_transaction_options_and_more.py | 56 --------- ...08_alter_category_options_category_icon.py | 22 ---- nummi/main/migrations/0009_snapshot.py | 44 ------- .../0010_alter_snapshot_previous.py | 25 ---- ...snapshot_options_snapshot_diff_and_more.py | 30 ----- nummi/main/models.py | 7 ++ nummi/main/templates/main/base.html | 4 + nummi/main/templates/main/index.html | 4 +- nummi/main/templates/main/snapshot.html | 26 ++++ nummi/main/urls.py | 4 + nummi/main/views.py | 42 +++++-- 17 files changed, 159 insertions(+), 372 deletions(-) delete mode 100644 nummi/main/migrations/0002_delete_subcategory.py delete mode 100644 nummi/main/migrations/0003_category_parent_alter_category_name.py delete mode 100644 nummi/main/migrations/0004_alter_category_options_category_full_name.py delete mode 100644 nummi/main/migrations/0005_alter_category_full_name.py delete mode 100644 nummi/main/migrations/0006_alter_category_options_transaction_trader_and_more.py delete mode 100644 nummi/main/migrations/0007_alter_category_options_alter_transaction_options_and_more.py delete mode 100644 nummi/main/migrations/0008_alter_category_options_category_icon.py delete mode 100644 nummi/main/migrations/0009_snapshot.py delete mode 100644 nummi/main/migrations/0010_alter_snapshot_previous.py delete mode 100644 nummi/main/migrations/0011_alter_snapshot_options_snapshot_diff_and_more.py create mode 100644 nummi/main/templates/main/snapshot.html diff --git a/nummi/main/migrations/0001_initial.py b/nummi/main/migrations/0001_initial.py index 1da39e1..7685e49 100644 --- a/nummi/main/migrations/0001_initial.py +++ b/nummi/main/migrations/0001_initial.py @@ -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",), - ), ] diff --git a/nummi/main/migrations/0002_delete_subcategory.py b/nummi/main/migrations/0002_delete_subcategory.py deleted file mode 100644 index 4a772ac..0000000 --- a/nummi/main/migrations/0002_delete_subcategory.py +++ /dev/null @@ -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", - ), - ] diff --git a/nummi/main/migrations/0003_category_parent_alter_category_name.py b/nummi/main/migrations/0003_category_parent_alter_category_name.py deleted file mode 100644 index cede3ea..0000000 --- a/nummi/main/migrations/0003_category_parent_alter_category_name.py +++ /dev/null @@ -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), - ), - ] diff --git a/nummi/main/migrations/0004_alter_category_options_category_full_name.py b/nummi/main/migrations/0004_alter_category_options_category_full_name.py deleted file mode 100644 index 1af43dd..0000000 --- a/nummi/main/migrations/0004_alter_category_options_category_full_name.py +++ /dev/null @@ -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, - ), - ] diff --git a/nummi/main/migrations/0005_alter_category_full_name.py b/nummi/main/migrations/0005_alter_category_full_name.py deleted file mode 100644 index af9449f..0000000 --- a/nummi/main/migrations/0005_alter_category_full_name.py +++ /dev/null @@ -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), - ), - ] diff --git a/nummi/main/migrations/0006_alter_category_options_transaction_trader_and_more.py b/nummi/main/migrations/0006_alter_category_options_transaction_trader_and_more.py deleted file mode 100644 index 9056ef4..0000000 --- a/nummi/main/migrations/0006_alter_category_options_transaction_trader_and_more.py +++ /dev/null @@ -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), - ), - ] diff --git a/nummi/main/migrations/0007_alter_category_options_alter_transaction_options_and_more.py b/nummi/main/migrations/0007_alter_category_options_alter_transaction_options_and_more.py deleted file mode 100644 index f4baaee..0000000 --- a/nummi/main/migrations/0007_alter_category_options_alter_transaction_options_and_more.py +++ /dev/null @@ -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), - ), - ] diff --git a/nummi/main/migrations/0008_alter_category_options_category_icon.py b/nummi/main/migrations/0008_alter_category_options_category_icon.py deleted file mode 100644 index 3c570ed..0000000 --- a/nummi/main/migrations/0008_alter_category_options_category_icon.py +++ /dev/null @@ -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), - ), - ] diff --git a/nummi/main/migrations/0009_snapshot.py b/nummi/main/migrations/0009_snapshot.py deleted file mode 100644 index f572375..0000000 --- a/nummi/main/migrations/0009_snapshot.py +++ /dev/null @@ -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", - ), - ), - ], - ), - ] diff --git a/nummi/main/migrations/0010_alter_snapshot_previous.py b/nummi/main/migrations/0010_alter_snapshot_previous.py deleted file mode 100644 index 53393fd..0000000 --- a/nummi/main/migrations/0010_alter_snapshot_previous.py +++ /dev/null @@ -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", - ), - ), - ] diff --git a/nummi/main/migrations/0011_alter_snapshot_options_snapshot_diff_and_more.py b/nummi/main/migrations/0011_alter_snapshot_options_snapshot_diff_and_more.py deleted file mode 100644 index 7a48363..0000000 --- a/nummi/main/migrations/0011_alter_snapshot_options_snapshot_diff_and_more.py +++ /dev/null @@ -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), - ), - ] diff --git a/nummi/main/models.py b/nummi/main/models.py index 5f14876..c12dca4 100644 --- a/nummi/main/models.py +++ b/nummi/main/models.py @@ -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"] diff --git a/nummi/main/templates/main/base.html b/nummi/main/templates/main/base.html index c23f3e0..cfc0531 100644 --- a/nummi/main/templates/main/base.html +++ b/nummi/main/templates/main/base.html @@ -29,6 +29,10 @@ class="{% if request.resolver_match.url_name == "category" %} cur{% endif %}"> Add category + + Add snapshot + Log Out diff --git a/nummi/main/templates/main/index.html b/nummi/main/templates/main/index.html index 8413e89..cc61b65 100644 --- a/nummi/main/templates/main/index.html +++ b/nummi/main/templates/main/index.html @@ -55,7 +55,9 @@ {% for snap in snapshots %}
- {{ snap.date|date:"Y-m-d" }} + + {{ snap.date|date:"Y-m-d" }} + {{ snap.value|floatformat:"2g" }} € {{ snap.diff|floatformat:"2g"|pm }} € {% with sum=snap.sum %} diff --git a/nummi/main/templates/main/snapshot.html b/nummi/main/templates/main/snapshot.html new file mode 100644 index 0000000..b6d60aa --- /dev/null +++ b/nummi/main/templates/main/snapshot.html @@ -0,0 +1,26 @@ +{% extends "main/base.html" %} +{% load static %} + +{% block link %} +{{ block.super }} + +{% endblock %} + +{% block body %} +

{{ snapshot }}

+ +
+ {% csrf_token %} + {% for field in form %} + {{ field.errors }} + + {{ field }} + {% endfor %} +
+ + + +
+
+ +{% endblock %} diff --git a/nummi/main/urls.py b/nummi/main/urls.py index 4114aaf..384ab79 100644 --- a/nummi/main/urls.py +++ b/nummi/main/urls.py @@ -21,4 +21,8 @@ urlpatterns = [ path("category", views.category, name="category"), path("category/", views.category, name="category"), path("category//update", views.update_category, name="update_category"), + path("snapshot", views.snapshot, name="snapshot"), + path("snapshot/", views.snapshot, name="snapshot"), + path("snapshot/update/", views.update_snapshot, name="update_snapshot"), + path("snapshot//del", views.del_snapshot, name="del_snapshot"), ] diff --git a/nummi/main/views.py b/nummi/main/views.py index f348143..0489190 100644 --- a/nummi/main/views.py +++ b/nummi/main/views.py @@ -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)