Add account creation and selection
This commit is contained in:
parent
667c6d3da1
commit
f2df88d091
5 changed files with 219 additions and 68 deletions
|
@ -0,0 +1,80 @@
|
|||
# Generated by Django 4.1.4 on 2022-12-29 18:32
|
||||
|
||||
import uuid
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
("main", "0012_alter_snapshot_date"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Account",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
(
|
||||
"name",
|
||||
models.CharField(
|
||||
default="Account", max_length=64, verbose_name="Nom"
|
||||
),
|
||||
),
|
||||
(
|
||||
"icon",
|
||||
models.CharField(
|
||||
default="folder", max_length=64, verbose_name="Icône"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
editable=False,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="Utilisateur",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Account",
|
||||
"verbose_name_plural": "Accounts",
|
||||
"ordering": ["name"],
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="snapshot",
|
||||
name="account",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="main.account",
|
||||
verbose_name="Account",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="transaction",
|
||||
name="account",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="main.account",
|
||||
verbose_name="Account",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -2,12 +2,12 @@ import pathlib
|
|||
import uuid
|
||||
from datetime import date
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.validators import FileExtensionValidator
|
||||
from django.db import models
|
||||
from django.forms import ModelForm
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
|
||||
class UserModel(models.Model):
|
||||
|
@ -19,7 +19,57 @@ class UserModel(models.Model):
|
|||
abstract = True
|
||||
|
||||
|
||||
class Category(UserModel):
|
||||
class CustomModel(UserModel):
|
||||
@property
|
||||
def adding(self):
|
||||
return self._state.adding
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class Account(CustomModel):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
name = models.CharField(max_length=64, default=_("Account"), verbose_name=_("Name"))
|
||||
icon = models.CharField(max_length=64, default="folder", verbose_name=_("Icon"))
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("account", kwargs={"pk": self.pk})
|
||||
|
||||
def get_delete_url(self):
|
||||
return reverse("del_account", kwargs={"pk": self.pk})
|
||||
|
||||
@property
|
||||
def transactions(self):
|
||||
return Transaction.objects.filter(account=self)
|
||||
|
||||
@property
|
||||
def snapshots(self):
|
||||
return Snapshot.objects.filter(account=self)
|
||||
|
||||
class Meta:
|
||||
ordering = ["name"]
|
||||
verbose_name = _("Account")
|
||||
verbose_name_plural = _("Accounts")
|
||||
|
||||
|
||||
class AccountModel(CustomModel):
|
||||
account = models.ForeignKey(
|
||||
Account,
|
||||
on_delete=models.SET_NULL,
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name=_("Account"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class Category(CustomModel):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
name = models.CharField(
|
||||
max_length=64, default=_("Category"), verbose_name=_("Name")
|
||||
|
@ -36,10 +86,6 @@ class Category(UserModel):
|
|||
def get_delete_url(self):
|
||||
return reverse("del_category", kwargs={"pk": self.pk})
|
||||
|
||||
@property
|
||||
def adding(self):
|
||||
return self._state.adding
|
||||
|
||||
@property
|
||||
def transactions(self):
|
||||
return Transaction.objects.filter(category=self)
|
||||
|
@ -50,15 +96,7 @@ class Category(UserModel):
|
|||
verbose_name_plural = _("Categories")
|
||||
|
||||
|
||||
class CategoryForm(ModelForm):
|
||||
template_name = "main/form/base.html"
|
||||
|
||||
class Meta:
|
||||
model = Category
|
||||
fields = ["name", "icon", "budget"]
|
||||
|
||||
|
||||
class Transaction(UserModel):
|
||||
class Transaction(AccountModel):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
name = models.CharField(
|
||||
max_length=256, default=_("Transaction"), verbose_name=_("Name")
|
||||
|
@ -92,10 +130,6 @@ class Transaction(UserModel):
|
|||
def get_delete_url(self):
|
||||
return reverse("del_transaction", kwargs={"pk": self.pk})
|
||||
|
||||
@property
|
||||
def adding(self):
|
||||
return self._state.adding
|
||||
|
||||
@property
|
||||
def invoices(self):
|
||||
return Invoice.objects.filter(transaction=self)
|
||||
|
@ -110,28 +144,11 @@ class Transaction(UserModel):
|
|||
verbose_name_plural = _("Transactions")
|
||||
|
||||
|
||||
class TransactionForm(ModelForm):
|
||||
template_name = "main/form/base.html"
|
||||
|
||||
class Meta:
|
||||
model = Transaction
|
||||
fields = [
|
||||
"date",
|
||||
"name",
|
||||
"value",
|
||||
"trader",
|
||||
"category",
|
||||
"real_date",
|
||||
"payment",
|
||||
"description",
|
||||
]
|
||||
|
||||
|
||||
def invoice_path(instance, filename):
|
||||
return pathlib.Path("invoices", str(instance.id)).with_suffix(".pdf")
|
||||
|
||||
|
||||
class Invoice(UserModel):
|
||||
class Invoice(CustomModel):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
name = models.CharField(
|
||||
max_length=256, default=_("Invoice"), verbose_name=_("Name")
|
||||
|
@ -165,29 +182,16 @@ class Invoice(UserModel):
|
|||
"del_invoice", kwargs={"transaction_pk": self.transaction.pk, "pk": self.pk}
|
||||
)
|
||||
|
||||
@property
|
||||
def adding(self):
|
||||
return self._state.adding
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Invoice")
|
||||
verbose_name_plural = _("Invoices")
|
||||
|
||||
|
||||
class InvoiceForm(ModelForm):
|
||||
template_name = "main/form/base.html"
|
||||
prefix = "invoice"
|
||||
|
||||
class Meta:
|
||||
model = Invoice
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
def snapshot_path(instance, filename):
|
||||
return pathlib.Path("snapshots", str(instance.id)).with_suffix(".pdf")
|
||||
|
||||
|
||||
class Snapshot(UserModel):
|
||||
class Snapshot(AccountModel):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
date = models.DateField(default=date.today, verbose_name=_("Date"))
|
||||
value = models.DecimalField(
|
||||
|
@ -284,10 +288,6 @@ class Snapshot(UserModel):
|
|||
def get_delete_url(self):
|
||||
return reverse("del_snapshot", kwargs={"pk": self.pk})
|
||||
|
||||
@property
|
||||
def adding(self):
|
||||
return self._state.adding
|
||||
|
||||
@property
|
||||
def sum(self):
|
||||
if self.previous is None:
|
||||
|
@ -327,9 +327,37 @@ class Snapshot(UserModel):
|
|||
verbose_name_plural = _("Snapshots")
|
||||
|
||||
|
||||
class SnapshotForm(ModelForm):
|
||||
class NummiForm(ModelForm):
|
||||
template_name = "main/form/base.html"
|
||||
|
||||
|
||||
class AccountForm(NummiForm):
|
||||
class Meta:
|
||||
model = Account
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class CategoryForm(NummiForm):
|
||||
class Meta:
|
||||
model = Category
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class TransactionForm(NummiForm):
|
||||
class Meta:
|
||||
model = Transaction
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class InvoiceForm(NummiForm):
|
||||
prefix = "invoice"
|
||||
|
||||
class Meta:
|
||||
model = Invoice
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class SnapshotForm(NummiForm):
|
||||
class Meta:
|
||||
model = Snapshot
|
||||
fields = ["date", "value", "file"]
|
||||
fields = "__all__"
|
||||
|
|
22
nummi/main/templates/main/account_form.html
Normal file
22
nummi/main/templates/main/account_form.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
{% 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"/>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<h1>
|
||||
<i class="fa fa-{{ form.instance.icon }}"></i> {{ form.instance }}
|
||||
</h1>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -7,6 +7,7 @@ urlpatterns = [
|
|||
path("login", views.LoginView.as_view(), name="login"),
|
||||
path("logout", views.LogoutView.as_view(), name="logout"),
|
||||
path("transactions", views.TransactionListView.as_view(), name="transactions"),
|
||||
path("account", views.AccountCreateView.as_view(), name="account"),
|
||||
path("transaction", views.TransactionCreateView.as_view(), name="transaction"),
|
||||
path(
|
||||
"transaction/<transaction_pk>/invoice",
|
||||
|
@ -15,6 +16,7 @@ urlpatterns = [
|
|||
),
|
||||
path("category", views.CategoryCreateView.as_view(), name="category"),
|
||||
path("snapshot", views.SnapshotCreateView.as_view(), name="snapshot"),
|
||||
path("account/<pk>", views.AccountUpdateView.as_view(), name="account"),
|
||||
path("transaction/<pk>", views.TransactionUpdateView.as_view(), name="transaction"),
|
||||
path(
|
||||
"transaction/<transaction_pk>/invoice/<pk>",
|
||||
|
@ -23,6 +25,11 @@ urlpatterns = [
|
|||
),
|
||||
path("category/<pk>", views.CategoryUpdateView.as_view(), name="category"),
|
||||
path("snapshot/<pk>", views.SnapshotUpdateView.as_view(), name="snapshot"),
|
||||
path(
|
||||
"account/<pk>/delete",
|
||||
views.AccountDeleteView.as_view(),
|
||||
name="del_account",
|
||||
),
|
||||
path(
|
||||
"transaction/<pk>/delete",
|
||||
views.TransactionDeleteView.as_view(),
|
||||
|
|
|
@ -19,6 +19,8 @@ from django.views.generic import (
|
|||
from django.views.generic.edit import ProcessFormView
|
||||
|
||||
from .models import (
|
||||
Account,
|
||||
AccountForm,
|
||||
Category,
|
||||
CategoryForm,
|
||||
Invoice,
|
||||
|
@ -52,6 +54,11 @@ class UserCreateView(LoginRequiredMixin, CreateView):
|
|||
return super().form_valid(form)
|
||||
|
||||
|
||||
class NummiDeleteView(UserMixin, DeleteView):
|
||||
template_name = "main/confirm_delete.html"
|
||||
success_url = reverse_lazy("index")
|
||||
|
||||
|
||||
class LoginView(auth_views.LoginView):
|
||||
template_name = "main/login.html"
|
||||
next_page = "index"
|
||||
|
@ -68,6 +75,11 @@ class TransactionListView(UserMixin, ListView):
|
|||
context_object_name = "transactions"
|
||||
|
||||
|
||||
class AccountCreateView(UserCreateView):
|
||||
model = Account
|
||||
form_class = AccountForm
|
||||
|
||||
|
||||
class TransactionCreateView(UserCreateView):
|
||||
model = Transaction
|
||||
form_class = TransactionForm
|
||||
|
@ -98,6 +110,11 @@ class SnapshotCreateView(UserCreateView):
|
|||
form_class = SnapshotForm
|
||||
|
||||
|
||||
class AccountUpdateView(UserMixin, UpdateView):
|
||||
model = Account
|
||||
form_class = AccountForm
|
||||
|
||||
|
||||
class TransactionUpdateView(UserMixin, UpdateView):
|
||||
model = Transaction
|
||||
form_class = TransactionForm
|
||||
|
@ -132,15 +149,16 @@ class SnapshotUpdateView(UserMixin, UpdateView):
|
|||
form_class = SnapshotForm
|
||||
|
||||
|
||||
class TransactionDeleteView(UserMixin, DeleteView):
|
||||
class AccountDeleteView(NummiDeleteView):
|
||||
model = Account
|
||||
|
||||
|
||||
class TransactionDeleteView(NummiDeleteView):
|
||||
model = Transaction
|
||||
template_name = "main/confirm_delete.html"
|
||||
success_url = reverse_lazy("index")
|
||||
|
||||
|
||||
class InvoiceDeleteView(UserMixin, DeleteView):
|
||||
class InvoiceDeleteView(NummiDeleteView):
|
||||
model = Invoice
|
||||
template_name = "main/confirm_delete.html"
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy("transaction", kwargs={"pk": self.object.transaction.pk})
|
||||
|
@ -151,16 +169,12 @@ class InvoiceDeleteView(UserMixin, DeleteView):
|
|||
)
|
||||
|
||||
|
||||
class CategoryDeleteView(UserMixin, DeleteView):
|
||||
class CategoryDeleteView(NummiDeleteView):
|
||||
model = Category
|
||||
template_name = "main/confirm_delete.html"
|
||||
success_url = reverse_lazy("index")
|
||||
|
||||
|
||||
class SnapshotDeleteView(UserMixin, DeleteView):
|
||||
class SnapshotDeleteView(NummiDeleteView):
|
||||
model = Snapshot
|
||||
template_name = "main/confirm_delete.html"
|
||||
success_url = reverse_lazy("index")
|
||||
|
||||
|
||||
class SearchView(UserMixin, ListView, ProcessFormView):
|
||||
|
|
Loading…
Reference in a new issue