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 django import forms
from .models import Expense, Category, Tag from .models import Expense, Category, Tag, Account
class ExpenseForm(forms.ModelForm): class ExpenseForm(forms.ModelForm):
@ -12,6 +12,7 @@ class ExpenseForm(forms.ModelForm):
if user: if user:
self.fields['category'].queryset = Category.objects.filter(owner=user) self.fields['category'].queryset = Category.objects.filter(owner=user)
self.fields['tags'].queryset = Tag.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: class Meta:
model = Expense model = Expense
@ -32,3 +33,9 @@ class TagForm(forms.ModelForm):
class Meta: class Meta:
model = Tag model = Tag
fields = ['name'] 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): class Account(models.Model):
name = models.CharField(max_length=100)
owner = models.ForeignKey( owner = models.ForeignKey(
settings.AUTH_USER_MODEL, settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name="accounts", 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): def __str__(self):
return self.name return self.name
@ -72,9 +83,7 @@ class Expense(models.Model):
account = models.ForeignKey( account = models.ForeignKey(
Account, Account,
on_delete=models.SET_NULL, on_delete=models.PROTECT,
null=True,
blank=True,
related_name="expenses", related_name="expenses",
) )

View File

@ -45,6 +45,17 @@
</select> </select>
</label> </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> <label for="tag">Filtrar por tags:</label>
<div class="active-tags"> <div class="active-tags">
{% for tag in tags_with_state %} {% for tag in tags_with_state %}
@ -77,6 +88,7 @@
<th>Fecha</th> <th>Fecha</th>
<th>Categoría</th> <th>Categoría</th>
<th>Importe</th> <th>Importe</th>
<th>Cuenta</th>
<th>Etiquetas</th> <th>Etiquetas</th>
<th></th> <th></th>
</tr> </tr>
@ -87,6 +99,7 @@
<td>{{ expense.date }}</td> <td>{{ expense.date }}</td>
<td>{{ expense.category.name }}</td> <td>{{ expense.category.name }}</td>
<td>{{ expense.amount }}</td> <td>{{ expense.amount }}</td>
<td>{{ expense.account.name }}</td>
<td> <td>
{% for tag in expense.tags.all %} {% for tag in expense.tags.all %}
<span class="tag"> <span class="tag">

View File

@ -1,7 +1,7 @@
from datetime import date from datetime import date
from operator import truediv from operator import truediv
from .forms import ExpenseForm, TagForm from .forms import ExpenseForm, TagForm
from .models import Category, Expense, Tag from .models import Account, Category, Expense, Tag
# from dateutli.relativedelta import relativedelta # from dateutli.relativedelta import relativedelta
from django.db.models import Sum from django.db.models import Sum
@ -115,6 +115,7 @@ def expense_list(request):
year = _get_int(request.GET.get('year')) year = _get_int(request.GET.get('year'))
month = _get_int(request.GET.get('month')) month = _get_int(request.GET.get('month'))
category = _get_int(request.GET.get('category')) category = _get_int(request.GET.get('category'))
account_id = _get_int(request.GET.get('account'))
tag_ids = request.GET.getlist('tag') tag_ids = request.GET.getlist('tag')
tag_ids = [int(t) for t in tag_ids] tag_ids = [int(t) for t in tag_ids]
@ -131,6 +132,9 @@ def expense_list(request):
if tag_ids: if tag_ids:
expenses = expenses.filter(tags__id__in=tag_ids).distinct() expenses = expenses.filter(tags__id__in=tag_ids).distinct()
if account_id:
expenses = expense.filter(account_id=account_id)
selected_tags = tag_ids or [] selected_tags = tag_ids or []
expenses = expenses.order_by('-date') expenses = expenses.order_by('-date')
@ -190,6 +194,8 @@ def expense_list(request):
'selected_tags': selected_tags, 'selected_tags': selected_tags,
'tags': Tag.objects.filter(owner=request.user), 'tags': Tag.objects.filter(owner=request.user),
'tags_with_state': tags_with_state, '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', 'expenses/tag_confirm_delete.html',
{'tag': tag} {'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}
)