Merge pull request 'dev' (#6) from dev into main

Reviewed-on: #6
This commit is contained in:
jkuijperm 2026-04-29 16:15:19 +00:00
commit 48d7fc576d
5 changed files with 129 additions and 38 deletions

View File

@ -13,6 +13,7 @@ class ExpenseForm(forms.ModelForm):
self.fields['category'].queryset = Category.objects.filter(owner=user)
self.fields['tags'].queryset = Tag.objects.filter(owner=user)
self.fields['account'].queryset = Account.objects.filter(owner=user, active=True)
self.fields['date'].input_formats = ['%Y-%m-%d']
class Meta:
model = Expense
@ -25,7 +26,9 @@ class ExpenseForm(forms.ModelForm):
'tags',
]
widgets = {
'date': forms.DateInput(attrs={'type': 'date'}),
'date': forms.DateInput(
format='%Y-%m-%d',
attrs={'type': 'date'}),
'widget': forms.CheckboxSelectMultiple(),
}
@ -46,7 +49,9 @@ class IncomeForm(forms.ModelForm):
model = Income
fields = ['account', 'name', 'amount', 'date']
widgets = {
'date': forms.DateInput(attrs={'type': 'date'})
'date': forms.DateInput(
format='%Y-%m-%d',
attrs={'type': 'date'})
}
def __init__(self, *args, **kwargs):
@ -59,7 +64,9 @@ class IncomeForm(forms.ModelForm):
class FuelEntryForm(forms.Form):
# Expense fields
date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
date = forms.DateField(widget=forms.DateInput(
format='%Y-%m-%d',
attrs={'type': 'date'}))
amount = forms.DecimalField(max_digits=10, decimal_places=2)
account = forms.ModelChoiceField(queryset=None)
@ -67,10 +74,12 @@ class FuelEntryForm(forms.Form):
odometer = forms.DecimalField(label='Current kilometers')
liters = forms.DecimalField(max_digits=8, decimal_places=2)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super().__init__(*args, **kwargs)
if user:
self.fields['account'].queryset = (
user.accounts.filter(active=True)
)

View File

@ -128,7 +128,11 @@
{% endfor %}
</td>
<td class="table-actions">
{% if expense.category.slug == 'gasolina' %}
<a href="{% url 'fuel_edit' expense.id %}">Editar</a>
{% else %}
<a href="{% url 'expense_edit' expense.id %}">Editar</a>
{% endif %}
<a href="{% url 'expense_delete' expense.id %}" class="danger">Eliminar</a>
</td>
</tr>
@ -146,15 +150,15 @@
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1{% if selected_year %}&year={{ selected_year }}{% endif %}{% if selected_month %}&month={{ selected_month }}{% endif %}{% if selected_category %}&category={{ selected_category }}{% endif %}{% if selected_tag %}&tag={{ selected_tag }}{% endif %}">&laquo; Primero</a>
<a href="?page={{ page_obj.previous_page_number }}{% if selected_year %}&year={{ selected_year }}{% endif %}{% if selected_month %}&month={{ selected_month }}{% endif %}{% if selected_category %}&category={{ selected_category }}{% endif %}{% if selected_tag %}&tag={{ selected_tag }}{% endif %}">Anterior</a>
<a href="?page=1{% if query_params %}&{{ query_params }}{% endif %}">&laquo; Primero</a>
<a href="?page={{ page_obj.previous_page_number }}{% if query_params %}&{{ query_params }}{% endif %}">Anterior</a>
{% endif %}
<span>Página {{ page_obj.number }} de {{ page_obj.paginator.num_pages }}</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}{% if selected_year %}&year={{ selected_year }}{% endif %}{% if selected_month %}&month={{ selected_month }}{% endif %}{% if selected_category %}&category={{ selected_category }}{% endif %}{% if selected_tag %}&tag={{ selected_tag }}{% endif %}">Siguiente</a>
<a href="?page={{ page_obj.paginator.num_pages }}{% if selected_year %}&year={{ selected_year }}{% endif %}{% if selected_month %}&month={{ selected_month }}{% endif %}{% if selected_category %}&category={{ selected_category }}{% endif %}{% if selected_tag %}&tag={{ selected_tag }}{% endif %}">Último &raquo;</a>
<a href="?page={{ page_obj.next_page_number }}{% if query_params %}&{{ query_params }}{% endif %}">Siguiente</a>
<a href="?page={{ page_obj.paginator.num_pages }}{% if query_params %}&{{ query_params }}{% endif %}">Último &raquo;</a>
{% endif %}
</span>
</div>

View File

@ -1,21 +1,37 @@
{% extends "expenses/base.html" %}
{% block title %}
{% if editing %}
Editar repostaje
{% else %}
Nuevo repostaje
{% endif %}
{% endblock %}
{% block content %}
<h1>
{% if editing %}
Editar repostaje
{% else %}
Nuevo repostaje
{% endif %}
</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">
{% if editing %}
Guardar repostaje
{% else %}
Crear repostaje
{% endif %}
</button>
</form>
{% if editing %}
<a href="{% url 'expense_list' %}">Volver</a>
{% else %}
<a href="{% url 'fuel_list' %}">Volver</a>
{% endif %}
{% endblock %}

View File

@ -22,5 +22,6 @@ urlpatterns = [
path('incomes/<int:pk>/delete/', views.income_delete, name='income_delete'),
path('fuel/', views.fuel_list, name='fuel_list'),
path('fuel/create/', views.fuel_create, name='fuel_create'),
path('fuel/<int:pk>/edit/', views.fuel_edit, name='fuel_edit'),
path('categories/', views.category_list, name='category_list'),
]

View File

@ -1,6 +1,7 @@
from operator import truediv
from datetime import date, datetime
from django.contrib import messages
from django.template import context
from .models import Account, Category, Expense, FuelEntry, Tag, Income
from .forms import ExpenseForm, IncomeForm, TagForm, AccountForm, FuelEntryForm, CategoryForm
# from dateutli.relativedelta import relativedelta
@ -158,6 +159,9 @@ def expense_list(request):
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
query_params = request.GET.copy()
query_params.pop('page', None)
# tags with state
tags_with_state = []
@ -203,7 +207,8 @@ def expense_list(request):
'tags_with_state': tags_with_state,
'accounts': Account.objects.filter(owner=request.user),
'selected_account': account_id,
'advanced_filters_open' : advanced_filters_open
'advanced_filters_open' : advanced_filters_open,
'query_params': query_params.urlencode(),
},
)
@ -232,13 +237,19 @@ def expense_create(request):
@login_required
def expense_edit(request, pk):
# sourcery skip: assign-if-exp, merge-else-if-into-elif
expense = get_object_or_404(
Expense,
pk=pk,
owner=request.user,
)
if request.method == "POST":
form = ExpenseForm(request.POST or None, instance=expense, user=request.user)
form = ExpenseForm(
request.POST or None,
instance=expense,
user=request.user)
if form.is_valid():
expense = form.save()
messages.success(request, 'Gasto actualizado')
@ -248,8 +259,10 @@ def expense_edit(request, pk):
return render(
request,
'expenses/expense_form.html',
{'active_menu': 'expenses','form': form}
'expenses/expense_form.html', {
'active_menu': 'expenses',
'form': form,
}
)
@ -785,11 +798,7 @@ def fuel_list(request):
current_year = datetime.now().year
if selected_year:
selected_year = int(selected_year)
else:
selected_year = current_year
selected_year = int(selected_year) if selected_year else current_year
fuels = FuelEntry.objects.filter(
expense__owner=request.user,
expense__date__year=selected_year
@ -839,6 +848,58 @@ def fuel_list(request):
}
)
@login_required
def fuel_edit(request, pk):
expense = get_object_or_404(
Expense,
pk=pk,
owner=request.user,
)
fuel = get_object_or_404(FuelEntry, expense=expense)
if request.method == "POST":
form = FuelEntryForm(
request.POST,
user=request.user
)
if form.is_valid():
# Update expense
expense.date = form.cleaned_data['date']
expense.amount = form.cleaned_data['amount']
expense.account = form.cleaned_data['account']
expense.description = 'Repostaje'
expense.save()
# Update FuelEntry
fuel.odometer = form.cleaned_data['odometer']
fuel.liters = form.cleaned_data['liters']
fuel.save()
return redirect('expense_list')
else:
fuel = expense.fuel_data
# Initialize manually
form = FuelEntryForm(
initial={
'date': expense.date,
'amount': expense.amount,
'account': expense.account,
'odometer': fuel.odometer,
'liters': fuel.liters
},
user=request.user
)
return render(
request, 'fuel/create.html', {
'active_menu': 'expenses',
'form': form,
'editing': True,
}
)
@login_required
def category_list(request):
categories = Category.objects.filter(