WIP in the new feature 'Account'
This commit is contained in:
parent
abd07919d4
commit
e8c15c1eff
@ -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
|
||||
@ -31,4 +32,10 @@ class ExpenseForm(forms.ModelForm):
|
||||
class TagForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Tag
|
||||
fields = ['name']
|
||||
fields = ['name']
|
||||
|
||||
class AccountForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Account
|
||||
fields = ['name', 'initial_balance', 'active']
|
||||
@ -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')},
|
||||
),
|
||||
]
|
||||
@ -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),
|
||||
),
|
||||
]
|
||||
@ -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')},
|
||||
),
|
||||
]
|
||||
@ -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'),
|
||||
),
|
||||
]
|
||||
@ -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),
|
||||
),
|
||||
]
|
||||
@ -26,14 +26,25 @@ class Category(models.Model):
|
||||
return self.name
|
||||
|
||||
|
||||
class Account(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
class Account(models.Model):
|
||||
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",
|
||||
)
|
||||
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user