WIP in the new feature 'Account'

This commit is contained in:
JKuijperM 2026-02-01 13:02:14 +01:00
parent abd07919d4
commit e8c15c1eff
9 changed files with 141 additions and 108 deletions

View File

@ -1,5 +1,5 @@
from django import forms
from .models import Expense, Category, Tag
from .models import Expense, Category, Tag, Account
class ExpenseForm(forms.ModelForm):
@ -12,6 +12,7 @@ class ExpenseForm(forms.ModelForm):
if user:
self.fields['category'].queryset = Category.objects.filter(owner=user)
self.fields['tags'].queryset = Tag.objects.filter(owner=user)
self.fields['account'].queryset = Account.objects(owner=user, active=True)
class Meta:
model = Expense
@ -32,3 +33,9 @@ class TagForm(forms.ModelForm):
class Meta:
model = Tag
fields = ['name']
class AccountForm(forms.ModelForm):
class Meta:
model = Account
fields = ['name', 'initial_balance', 'active']

View File

@ -0,0 +1,65 @@
# Generated by Django 5.2.10 on 2026-01-30 20:12
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterModelOptions(
name='account',
options={'ordering': ['name']},
),
migrations.AlterUniqueTogether(
name='category',
unique_together=set(),
),
migrations.AddField(
model_name='account',
name='active',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='account',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='account',
name='initial_balance',
field=models.DecimalField(decimal_places=2, default=0, max_digits=12),
),
migrations.AddField(
model_name='category',
name='owner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='categories', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='account',
name='owner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='accounts', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='expense',
name='account',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='expenses.account'),
),
migrations.AlterField(
model_name='expense',
name='category',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='expenses.category'),
),
migrations.AlterUniqueTogether(
name='category',
unique_together={('name', 'parent', 'owner')},
),
]

View File

@ -1,21 +0,0 @@
# Generated by Django 5.2.10 on 2026-01-09 08:42
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterField(
model_name='category',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to=settings.AUTH_USER_MODEL),
),
]

View File

@ -1,39 +0,0 @@
# Generated by Django 5.2.10 on 2026-01-09 09:27
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0002_alter_category_parent'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterUniqueTogether(
name='category',
unique_together=set(),
),
migrations.AddField(
model_name='category',
name='owner',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='categories', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='category',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='expenses.category'),
),
migrations.AlterField(
model_name='expense',
name='category',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='expenses.category'),
),
migrations.AlterUniqueTogether(
name='category',
unique_together={('name', 'parent', 'owner')},
),
]

View File

@ -1,19 +0,0 @@
# Generated by Django 5.2.10 on 2026-01-09 09:50
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0003_alter_category_unique_together_category_owner_and_more'),
]
operations = [
migrations.AlterField(
model_name='expense',
name='category',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='expenses.category'),
),
]

View File

@ -1,21 +0,0 @@
# Generated by Django 5.2.10 on 2026-01-09 10:03
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('expenses', '0004_alter_expense_category'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterField(
model_name='category',
name='owner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='categories', to=settings.AUTH_USER_MODEL),
),
]

View File

@ -27,13 +27,24 @@ class Category(models.Model):
class Account(models.Model):
name = models.CharField(max_length=100)
owner = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="accounts",
)
name = models.CharField(max_length=100)
initial_balance = models.DecimalField(
max_digits=12,
decimal_places=2,
default=0
)
active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['name']
def __str__(self):
return self.name
@ -72,9 +83,7 @@ class Expense(models.Model):
account = models.ForeignKey(
Account,
on_delete=models.SET_NULL,
null=True,
blank=True,
on_delete=models.PROTECT,
related_name="expenses",
)

View File

@ -45,6 +45,17 @@
</select>
</label>
<select name="account">
<option value="">Cuenta</option>
{% for acc in accounts %}
<option value="{{ acc.id }}"
{% if selected_account == acc.id %}selected{% endif %}
>
{{ acc.name }}
</option>
{% endfor %}
</select>
<label for="tag">Filtrar por tags:</label>
<div class="active-tags">
{% for tag in tags_with_state %}
@ -77,6 +88,7 @@
<th>Fecha</th>
<th>Categoría</th>
<th>Importe</th>
<th>Cuenta</th>
<th>Etiquetas</th>
<th></th>
</tr>
@ -87,6 +99,7 @@
<td>{{ expense.date }}</td>
<td>{{ expense.category.name }}</td>
<td>{{ expense.amount }}</td>
<td>{{ expense.account.name }}</td>
<td>
{% for tag in expense.tags.all %}
<span class="tag">

View File

@ -1,7 +1,7 @@
from datetime import date
from operator import truediv
from .forms import ExpenseForm, TagForm
from .models import Category, Expense, Tag
from .models import Account, Category, Expense, Tag
# from dateutli.relativedelta import relativedelta
from django.db.models import Sum
@ -115,6 +115,7 @@ def expense_list(request):
year = _get_int(request.GET.get('year'))
month = _get_int(request.GET.get('month'))
category = _get_int(request.GET.get('category'))
account_id = _get_int(request.GET.get('account'))
tag_ids = request.GET.getlist('tag')
tag_ids = [int(t) for t in tag_ids]
@ -131,6 +132,9 @@ def expense_list(request):
if tag_ids:
expenses = expenses.filter(tags__id__in=tag_ids).distinct()
if account_id:
expenses = expense.filter(account_id=account_id)
selected_tags = tag_ids or []
expenses = expenses.order_by('-date')
@ -190,6 +194,8 @@ def expense_list(request):
'selected_tags': selected_tags,
'tags': Tag.objects.filter(owner=request.user),
'tags_with_state': tags_with_state,
'accounts': Account.object.filter(owner=request.user),
'selected_account': account_id,
},
)
@ -549,3 +555,36 @@ def tag_delete(request, pk):
'expenses/tag_confirm_delete.html',
{'tag': tag}
)
@login_required
def account_list(request):
accounts = Account.objects.filter(owner=request.user)
return render(
request,
'expenses/account_list.html',
{'account': accounts}
)
@login_required
def account_create(request):
if request.method == 'POST':
form = AccountForm(request.POST)
if form.is_valid():
account = form.save(commit=False)
account.owner = request.user
account.save()
return redirect('account_list')
else:
form = AccountForm()
return render(
request,
'expenses/account_form.html',
{'form': form}
)