dev #6

Merged
jkuijperm merged 4 commits from dev into main 2026-04-29 16:15:20 +00:00
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['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.filter(owner=user, active=True) self.fields['account'].queryset = Account.objects.filter(owner=user, active=True)
self.fields['date'].input_formats = ['%Y-%m-%d']
class Meta: class Meta:
model = Expense model = Expense
@ -25,7 +26,9 @@ class ExpenseForm(forms.ModelForm):
'tags', 'tags',
] ]
widgets = { widgets = {
'date': forms.DateInput(attrs={'type': 'date'}), 'date': forms.DateInput(
format='%Y-%m-%d',
attrs={'type': 'date'}),
'widget': forms.CheckboxSelectMultiple(), 'widget': forms.CheckboxSelectMultiple(),
} }
@ -46,7 +49,9 @@ class IncomeForm(forms.ModelForm):
model = Income model = Income
fields = ['account', 'name', 'amount', 'date'] fields = ['account', 'name', 'amount', 'date']
widgets = { widgets = {
'date': forms.DateInput(attrs={'type': 'date'}) 'date': forms.DateInput(
format='%Y-%m-%d',
attrs={'type': 'date'})
} }
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -59,7 +64,9 @@ class IncomeForm(forms.ModelForm):
class FuelEntryForm(forms.Form): class FuelEntryForm(forms.Form):
# Expense fields # 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) amount = forms.DecimalField(max_digits=10, decimal_places=2)
account = forms.ModelChoiceField(queryset=None) account = forms.ModelChoiceField(queryset=None)
@ -67,13 +74,15 @@ class FuelEntryForm(forms.Form):
odometer = forms.DecimalField(label='Current kilometers') odometer = forms.DecimalField(label='Current kilometers')
liters = forms.DecimalField(max_digits=8, decimal_places=2) liters = forms.DecimalField(max_digits=8, decimal_places=2)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
user = kwargs.pop('user') user = kwargs.pop('user')
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['account'].queryset = ( if user:
user.accounts.filter(active=True) self.fields['account'].queryset = (
) user.accounts.filter(active=True)
)
class CategoryForm(forms.ModelForm): class CategoryForm(forms.ModelForm):
class Meta: class Meta:

View File

@ -128,7 +128,11 @@
{% endfor %} {% endfor %}
</td> </td>
<td class="table-actions"> <td class="table-actions">
<a href="{% url 'expense_edit' expense.id %}">Editar</a> {% 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> <a href="{% url 'expense_delete' expense.id %}" class="danger">Eliminar</a>
</td> </td>
</tr> </tr>
@ -146,15 +150,15 @@
<div class="pagination"> <div class="pagination">
<span class="step-links"> <span class="step-links">
{% if page_obj.has_previous %} {% 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=1{% if query_params %}&{{ query_params }}{% 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={{ page_obj.previous_page_number }}{% if query_params %}&{{ query_params }}{% endif %}">Anterior</a>
{% endif %} {% endif %}
<span>Página {{ page_obj.number }} de {{ page_obj.paginator.num_pages }}</span> <span>Página {{ page_obj.number }} de {{ page_obj.paginator.num_pages }}</span>
{% if page_obj.has_next %} {% 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.next_page_number }}{% if query_params %}&{{ query_params }}{% 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.paginator.num_pages }}{% if query_params %}&{{ query_params }}{% endif %}">Último &raquo;</a>
{% endif %} {% endif %}
</span> </span>
</div> </div>

View File

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

View File

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

View File

@ -1,6 +1,7 @@
from operator import truediv from operator import truediv
from datetime import date, datetime from datetime import date, datetime
from django.contrib import messages from django.contrib import messages
from django.template import context
from .models import Account, Category, Expense, FuelEntry, Tag, Income from .models import Account, Category, Expense, FuelEntry, Tag, Income
from .forms import ExpenseForm, IncomeForm, TagForm, AccountForm, FuelEntryForm, CategoryForm from .forms import ExpenseForm, IncomeForm, TagForm, AccountForm, FuelEntryForm, CategoryForm
# from dateutli.relativedelta import relativedelta # from dateutli.relativedelta import relativedelta
@ -158,6 +159,9 @@ def expense_list(request):
page_number = request.GET.get('page') page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number) page_obj = paginator.get_page(page_number)
query_params = request.GET.copy()
query_params.pop('page', None)
# tags with state # tags with state
tags_with_state = [] tags_with_state = []
@ -203,7 +207,8 @@ def expense_list(request):
'tags_with_state': tags_with_state, 'tags_with_state': tags_with_state,
'accounts': Account.objects.filter(owner=request.user), 'accounts': Account.objects.filter(owner=request.user),
'selected_account': account_id, '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 @login_required
def expense_edit(request, pk): def expense_edit(request, pk):
# sourcery skip: assign-if-exp, merge-else-if-into-elif
expense = get_object_or_404( expense = get_object_or_404(
Expense, Expense,
pk=pk, pk=pk,
owner=request.user, owner=request.user,
) )
if request.method == "POST": 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(): if form.is_valid():
expense = form.save() expense = form.save()
messages.success(request, 'Gasto actualizado') messages.success(request, 'Gasto actualizado')
@ -248,8 +259,10 @@ def expense_edit(request, pk):
return render( return render(
request, request,
'expenses/expense_form.html', 'expenses/expense_form.html', {
{'active_menu': 'expenses','form': form} 'active_menu': 'expenses',
'form': form,
}
) )
@ -785,11 +798,7 @@ def fuel_list(request):
current_year = datetime.now().year current_year = datetime.now().year
if selected_year: selected_year = int(selected_year) if selected_year else current_year
selected_year = int(selected_year)
else:
selected_year = current_year
fuels = FuelEntry.objects.filter( fuels = FuelEntry.objects.filter(
expense__owner=request.user, expense__owner=request.user,
expense__date__year=selected_year 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 @login_required
def category_list(request): def category_list(request):
categories = Category.objects.filter( categories = Category.objects.filter(