Add validation and flash message for invalid date range in Reports

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-11-23 10:45:52 +00:00
parent 062f8783de
commit 4e5b0957bf
4 changed files with 56 additions and 0 deletions

View File

@@ -11,6 +11,13 @@ class ReportsController < ApplicationController
@start_date = parse_date_param(:start_date) || default_start_date
@end_date = parse_date_param(:end_date) || default_end_date
# Validate and fix date range if end_date is before start_date
if @start_date > @end_date
# Swap the dates to maintain user's intended date range
@start_date, @end_date = @end_date, @start_date
flash.now[:alert] = t("reports.invalid_date_range")
end
# Build the period
@period = Period.custom(start_date: @start_date, end_date: @end_date)
@previous_period = build_previous_period
@@ -41,6 +48,12 @@ class ReportsController < ApplicationController
@period_type = params[:period_type]&.to_sym || :monthly
@start_date = parse_date_param(:start_date) || default_start_date
@end_date = parse_date_param(:end_date) || default_end_date
# Validate and fix date range if end_date is before start_date
if @start_date > @end_date
@start_date, @end_date = @end_date, @start_date
end
@period = Period.custom(start_date: @start_date, end_date: @end_date)
# Build monthly breakdown data for export

View File

@@ -9,6 +9,13 @@
</p>
</div>
<%# Flash messages %>
<% if flash[:alert].present? %>
<div class="p-3 rounded-lg bg-destructive-surface text-sm text-destructive">
<%= flash[:alert] %>
</div>
<% end %>
<%# Period Navigation Tabs %>
<div class="flex items-center gap-2 overflow-x-auto pb-2">
<%= render DS::Link.new(

View File

@@ -15,6 +15,7 @@ en:
from: From
to: To
showing_period: "Showing data from %{start} to %{end}"
invalid_date_range: "End date cannot be before start date. The dates have been swapped."
summary:
total_income: Total Income
total_expenses: Total Expenses

View File

@@ -92,6 +92,24 @@ class ReportsControllerTest < ActionDispatch::IntegrationTest
assert_response :ok # Should not crash, uses defaults
end
test "index swaps dates when end_date is before start_date" do
start_date = Date.current
end_date = 1.month.ago.to_date
get reports_path(
period_type: :custom,
start_date: start_date.to_s,
end_date: end_date.to_s
)
assert_response :ok
# Should show flash message about invalid date range
assert flash[:alert].present?, "Flash alert should be present"
assert_match /End date cannot be before start date/, flash[:alert]
# Should display the swapped date range
assert_select ".text-sm.text-secondary", text: /Showing data from #{Regexp.escape(end_date.strftime("%b %-d, %Y"))} to #{Regexp.escape(start_date.strftime("%b %-d, %Y"))}/
end
test "spending patterns returns data when expense transactions exist" do
# Create expense category
expense_category = @family.categories.create!(
@@ -185,4 +203,21 @@ class ReportsControllerTest < ActionDispatch::IntegrationTest
assert_response :ok, "Export should work with session auth. Response: #{@response.body}"
assert_equal "text/csv", @response.media_type
end
test "export transactions swaps dates when end_date is before start_date" do
start_date = Date.current
end_date = 1.month.ago.to_date
get export_transactions_reports_path(
format: :csv,
period_type: :custom,
start_date: start_date.to_s,
end_date: end_date.to_s
)
assert_response :ok
assert_equal "text/csv", @response.media_type
# Verify the CSV content is generated (should not crash)
assert_not_nil @response.body
end
end