diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb index b784c4f2d..c0fade776 100644 --- a/app/models/time_entry.rb +++ b/app/models/time_entry.rb @@ -180,7 +180,9 @@ class TimeEntry < ApplicationRecord errors.add :issue_id, :invalid if (issue_id && !issue) || (issue && project!=issue.project) || @invalid_issue_id errors.add :activity_id, :inclusion if activity_id_changed? && project && !project.activities.include?(activity) if spent_on && spent_on_changed? && user + max_days_for_past = [Setting.timelog_max_days_for_past.to_i, 0].max errors.add :base, I18n.t(:error_spent_on_future_date) if !Setting.timelog_accept_future_dates? && (spent_on > user.today) + errors.add :base, I18n.t(:error_spent_on_past_date, :max_days => max_days_for_past) if max_days_for_past < (user.today - spent_on) end end diff --git a/app/views/settings/_timelog.html.erb b/app/views/settings/_timelog.html.erb index c6efd966d..831ab9ac1 100644 --- a/app/views/settings/_timelog.html.erb +++ b/app/views/settings/_timelog.html.erb @@ -9,6 +9,8 @@

<%= setting_check_box :timelog_accept_0_hours %>

<%= setting_check_box :timelog_accept_future_dates %>

+ +

<%= setting_text_field :timelog_max_days_for_past, :size => 6 %>

diff --git a/config/locales/en.yml b/config/locales/en.yml index 1584f5ef2..2640947a7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -235,6 +235,7 @@ en: error_exceeds_maximum_hours_per_day: "Cannot log more than %{max_hours} hours on the same day (%{logged_hours} hours have already been logged)" error_can_not_delete_auth_source: "This authentication mode is in use and cannot be deleted." error_spent_on_future_date: "Cannot log time on a future date" + error_spent_on_past_date: "Cannot log time on a past date more than %{max_days} days ago." error_not_allowed_to_log_time_for_other_users: "You are not allowed to log time for other users" error_can_not_execute_macro_html: "Error executing the %{name} macro (%{error})" error_macro_does_not_accept_block: "This macro does not accept a block of text" @@ -519,6 +520,7 @@ en: setting_timelog_accept_0_hours: Accept time logs with 0 hours setting_timelog_max_hours_per_day: Maximum hours that can be logged per day and user setting_timelog_accept_future_dates: Accept time logs on future dates + setting_timelog_max_days_for_past: Accept time logs within the past N days setting_show_status_changes_in_mail_subject: Show status changes in issue mail notifications subject setting_project_list_defaults: Projects list defaults setting_twofa: Two-factor authentication diff --git a/config/settings.yml b/config/settings.yml index 19d3a33c7..5cae00509 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -347,5 +347,8 @@ timelog_max_hours_per_day: default: 999 timelog_accept_future_dates: default: 1 +timelog_max_days_for_past: + format: int + default: 36525 show_status_changes_in_mail_subject: default: 1 diff --git a/test/unit/time_entry_test.rb b/test/unit/time_entry_test.rb index 8722a86cd..b6c095992 100644 --- a/test/unit/time_entry_test.rb +++ b/test/unit/time_entry_test.rb @@ -171,6 +171,19 @@ class TimeEntryTest < ActiveSupport::TestCase end end + def test_should_restrict_past_dates + with_settings :timelog_max_days_for_past => '2' do + entry_two_days_ago = TimeEntry.generate + entry_two_days_ago.spent_on = User.current.today - 2 + assert entry_two_days_ago.save + + entry_three_days_ago = TimeEntry.generate + entry_three_days_ago.spent_on = User.current.today - 3 + assert !entry_three_days_ago.save + assert entry_three_days_ago.errors[:base].present? + end + end + def test_should_require_spent_on with_settings :timelog_accept_future_dates => '0' do entry = TimeEntry.find(1)