From ca4be9dcc7b7821cdd8cd353b93d91e6b0fcbf2c Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 21 Mar 2026 18:09:35 +0000 Subject: [PATCH] Fix HTTP 500 when 'Use as today' date is after end date When the user sets a 'Use as today' (start_date) value beyond the last_day of the displayed time span, the UserWorkload model crashes with a NoMethodError because 'today' falls outside the time_span and hours_for_issue[today] returns nil. Cap @today to @last_day in the controller before passing it to UserWorkload. Show a flash warning when the capping occurs so the user is informed. Fixes #40 https://claude.ai/code/session_01BSqVnAYvK1kCejeMnp4MqM --- app/controllers/workloads_controller.rb | 7 ++++++ config/locales/de.yml | 1 + config/locales/en.yml | 1 + test/functional/workloads_controller_test.rb | 26 ++++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/app/controllers/workloads_controller.rb b/app/controllers/workloads_controller.rb index 93e96d6..9040eee 100644 --- a/app/controllers/workloads_controller.rb +++ b/app/controllers/workloads_controller.rb @@ -32,6 +32,12 @@ def index # Make sure that last_day is at most 12 months after first_day to prevent # long running times @last_day = [(@first_day >> 12) - 1, @last_day].min + + # Make sure that today is not after last_day to prevent a crash in the + # workload calculation (today would be outside the time span) + @today_capped = @today > @last_day + @today = [@today, @last_day].min + @time_span_to_display = @first_day..@last_day if @date_check @@ -56,6 +62,7 @@ def index respond_to do |format| format.html do flash.now[:error] = l(:error_date_setting) unless @date_check + flash.now[:warning] = l(:warning_today_capped_to_last_day) if @today_capped render action: :index end diff --git a/config/locales/de.yml b/config/locales/de.yml index 0aee4b8..5a28ec0 100755 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -100,6 +100,7 @@ de: workload_unscheduled_issues_num: 'Anzahl ungeplanter Tickets:' workload_unscheduled_issues_hours: 'Stunden aus ungeplanten Tickets:' error_date_setting: 'Überprüfen Sie Ihre Eingabe! Das Enddatum (bis) liegt vor dem Startdatum (von).' + warning_today_capped_to_last_day: 'Das "Als Heute verwenden"-Datum lag nach dem Enddatum und wurde auf das Enddatum gesetzt.' error_encoding_setting: 'Zeichenkodierung nicht erlaubt. Gültige Werte: %{value}.' label_workload_calculation: Workloadberechnung label_include_parent_tasks: Hauptaufgaben einbeziehen diff --git a/config/locales/en.yml b/config/locales/en.yml index 670b832..b111ff9 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -100,6 +100,7 @@ en: workload_unscheduled_issues_num: 'Number of unscheduled issues:' workload_unscheduled_issues_hours: 'Hours of unscheduled issues:' error_date_setting: 'Please check your data! The end date is before the start date.' + warning_today_capped_to_last_day: 'The "Use as today" date was after the end date and has been set to the end date.' error_encoding_setting: 'Character encoding not allowed. Valid values: %{value}.' label_workload_calculation: Workload calculation label_include_parent_tasks: Include parent tasks diff --git a/test/functional/workloads_controller_test.rb b/test/functional/workloads_controller_test.rb index 644d6e6..c039a85 100644 --- a/test/functional/workloads_controller_test.rb +++ b/test/functional/workloads_controller_test.rb @@ -70,5 +70,31 @@ class WorkloadsControllerTest < ActionDispatch::IntegrationTest get workloads_path(workload: { start_date: 'not-a-date' }) assert_response :success end + + test 'should get index without error when start_date is after last_day' do + manager = roles :roles_001 + manager.add_permission! :view_all_workloads + log_user('jsmith', 'jsmith') + + get workloads_path(workload: { + first_day: '2026-01-01', + last_day: '2026-01-31', + start_date: '2026-06-01' + }) + assert_response :success + end + + test 'should show warning when start_date is after last_day' do + manager = roles :roles_001 + manager.add_permission! :view_all_workloads + log_user('jsmith', 'jsmith') + + get workloads_path(workload: { + first_day: '2026-01-01', + last_day: '2026-01-31', + start_date: '2026-06-01' + }) + assert flash[:warning].present? + end end end