diff --git a/expenses_manager/expenses/static/expenses/css/base.css b/expenses_manager/expenses/static/expenses/css/base.css index 5031c8c..6593c5a 100644 --- a/expenses_manager/expenses/static/expenses/css/base.css +++ b/expenses_manager/expenses/static/expenses/css/base.css @@ -396,7 +396,8 @@ button[type="submit"]:hover, gap: 0.5rem; } -.filters-main select { +.filters-main select, +.filters-main input[type="date"] { padding: 0.5rem 0.7rem; font-family: inherit; font-size: 0.95rem; @@ -406,11 +407,18 @@ button[type="submit"]:hover, border-radius: 6px; } -.filters-main select:focus { +.filters-main select:focus, +.filters-main input[type="date"]:focus { outline: 2px solid var(--color-focus-ring); outline-offset: 1px; } +.range-notice { + margin-top: 0.5rem; + font-size: 0.9rem; + color: var(--color-text-muted); +} + .filters-advanced { margin-top: 0.5rem; } diff --git a/expenses_manager/expenses/templates/expenses/_date_range.html b/expenses_manager/expenses/templates/expenses/_date_range.html new file mode 100644 index 0000000..16c6f82 --- /dev/null +++ b/expenses_manager/expenses/templates/expenses/_date_range.html @@ -0,0 +1,12 @@ +{% comment %} +Campos del rango de fechas libre. Se incluye dentro de un
. +Espera date_from y date_to en el contexto. +{% endcomment %} + + + + + + diff --git a/expenses_manager/expenses/templates/expenses/expense_list.html b/expenses_manager/expenses/templates/expenses/expense_list.html index d31d670..b484fa0 100644 --- a/expenses_manager/expenses/templates/expenses/expense_list.html +++ b/expenses_manager/expenses/templates/expenses/expense_list.html @@ -47,10 +47,20 @@ {% endfor %} + {% include "expenses/_date_range.html" %} + Limpiar + {% if range_active %} +

+ Mostrando el rango de fechas seleccionado; los filtros de año y mes no + se aplican. + Quitar el rango +

+ {% endif %} +
hasta) se ignoran LAS DOS fechas: devolver + una lista vacía sin explicación es peor que ignorar un filtro mal puesto. + """ + date_from = _get_date(request.GET.get("date_from")) + date_to = _get_date(request.GET.get("date_to")) + + if date_from and date_to and date_from > date_to: + return None, None + + return date_from, date_to + + def _safe_next(request): next_url = request.POST.get("next") or request.GET.get("next") @@ -336,11 +367,21 @@ def expense_list(request): if (t_id:= _get_int(t)) is not None ] - if year: - expenses = expenses.filter(date__year=year) + date_from, date_to = _resolve_date_range(request) + range_active = bool(date_from or date_to) - if month: - expenses = expenses.filter(date__month=month) + # Un solo criterio de periodo a la vez: si hay rango, manda el rango y los + # selectores de año y mes no se aplican (la plantilla lo avisa). + if range_active: + if date_from: + expenses = expenses.filter(date__gte=date_from) + if date_to: + expenses = expenses.filter(date__lte=date_to) + else: + if year: + expenses = expenses.filter(date__year=year) + if month: + expenses = expenses.filter(date__month=month) if category: expenses = expenses.filter(category_id=category) @@ -407,6 +448,9 @@ def expense_list(request): "page_obj": page_obj, "selected_year": year, "selected_month": month, + "date_from": date_from, + "date_to": date_to, + "range_active": range_active, "selected_category": category, "categories": categories, "year_list": [y.year for y in year_list],