Project

General

Profile

Feature #13244 » 0001-Setting-to-restrict-adding-editing-deleting-log-time.patch

Marius BĂLTEANU, 2024-08-13 21:37

View differences:

app/models/time_entry.rb
159 159
    errors.add :activity_id, :inclusion if activity_id_changed? && project && !project.activities.include?(activity)
160 160
    if spent_on_changed? && user
161 161
      errors.add :base, I18n.t(:error_spent_on_future_date) if !Setting.timelog_accept_future_dates? && (spent_on > user.today)
162
      errors.add :base, I18n.t(:error_spent_on_old_date, :days => Setting.timelog_lock_days_older_than.to_i) if date_is_locked_for_user?
162 163
    end
163 164
  end
164 165

  
......
186 187

  
187 188
  # Returns true if the time entry can be edited by usr, otherwise false
188 189
  def editable_by?(usr)
189
    visible?(usr) && (
190
    visible?(usr) && !date_is_locked_for_user? && (
190 191
      (usr == user && usr.allowed_to?(:edit_own_time_entries, project)) || usr.allowed_to?(:edit_time_entries, project)
191 192
    )
192 193
  end
......
231 232
      0.0
232 233
    end
233 234
  end
235

  
236
  # Returns true if time entry is logged on a locked date and the user doesn't have the permission
237
  # to manage time entries on locked dates
238
  def date_is_locked_for_user?
239
    if user && spent_on
240
      number_of_days = Setting.timelog_lock_days_older_than.to_i
241
      ((user.today - spent_on).to_i > number_of_days) && !User.current.allowed_to?(:manage_time_entries_on_locked_dates, self.project)
242
    end
243
  end
234 244
end
app/views/settings/_timelog.html.erb
9 9
<p><%= setting_check_box :timelog_accept_0_hours %></p>
10 10

  
11 11
<p><%= setting_check_box :timelog_accept_future_dates %></p>
12

  
13
<p><%= setting_text_field :timelog_lock_days_older_than, :size => 6 %> <%= l(:label_day_plural) %></p>
14

  
12 15
</div>
13 16

  
14 17
<fieldset class="box">
config/locales/en.yml
233 233
  error_can_not_delete_auth_source: "This authentication mode is in use and cannot be deleted."
234 234
  error_spent_on_future_date: "Cannot log time on a future date"
235 235
  error_not_allowed_to_log_time_for_other_users: "You are not allowed to log time for other users"
236
  error_spent_on_old_date: "Cannot log time on a date older than %{days} days"
236 237

  
237 238
  mail_subject_lost_password: "Your %{value} password"
238 239
  mail_body_lost_password: 'To change your password, click on the following link:'
......
494 495
  setting_timelog_accept_future_dates: Accept time logs on future dates
495 496
  setting_show_status_changes_in_mail_subject: Show status changes in issue mail notifications subject
496 497
  setting_project_list_defaults: Projects list defaults
498
  setting_timelog_lock_days_older_than: Lock (add/edit/delete time logs) dates older than
497 499

  
498 500
  permission_add_project: Create project
499 501
  permission_add_subprojects: Create subprojects
config/settings.yml
337 337
  default: 1
338 338
show_status_changes_in_mail_subject:
339 339
  default: 1
340
timelog_lock_days_older_than:
341
  format: int
342
  default: 9999
lib/redmine.rb
133 133
    map.permission :manage_project_activities, {:projects => :settings, :project_enumerations => [:update, :destroy]}, :require => :member
134 134
    map.permission :log_time_for_other_users, :require => :member
135 135
    map.permission :import_time_entries, {}
136
    map.permission :manage_time_entries_on_locked_dates, {}, :require => :loggedin
137
    map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
136 138
  end
137 139

  
138 140
  map.project_module :news do |map|
test/fixtures/roles.yml
37 37
    - :edit_time_entries
38 38
    - :delete_time_entries
39 39
    - :import_time_entries
40
    - :manage_time_entries_on_locked_dates
40 41
    - :view_news
41 42
    - :manage_news
42 43
    - :comment_news
......
95 96
    - :log_time
96 97
    - :view_time_entries
97 98
    - :edit_own_time_entries
99
    - :manage_time_entries_on_locked_dates
98 100
    - :view_news
99 101
    - :manage_news
100 102
    - :comment_news
......
141 143
    - :view_calendar
142 144
    - :log_time
143 145
    - :view_time_entries
146
    - :manage_time_entries_on_locked_dates
144 147
    - :view_news
145 148
    - :manage_news
146 149
    - :comment_news
......
179 182
    - :view_calendar
180 183
    - :log_time
181 184
    - :view_time_entries
185
    - :manage_time_entries_on_locked_dates
182 186
    - :view_news
183 187
    - :comment_news
184 188
    - :view_documents
......
206 210
    - :view_gantt
207 211
    - :view_calendar
208 212
    - :view_time_entries
213
    - :manage_time_entries_on_locked_dates
209 214
    - :view_news
210 215
    - :view_documents
211 216
    - :view_wiki_pages
test/unit/time_entry_test.rb
127 127

  
128 128
  def test_should_accept_future_dates
129 129
    entry = TimeEntry.generate
130
    entry.spent_on = Date.tomorrow
130 131
    entry.spent_on = User.current.today + 1
131 132

  
132 133
    assert entry.save
......
135 136
  def test_should_not_accept_future_dates_if_disabled
136 137
    with_settings :timelog_accept_future_dates => '0' do
137 138
      entry = TimeEntry.generate
139
      entry.spent_on = Date.tomorrow
138 140
      entry.spent_on = User.current.today + 1
139 141

  
140 142
      assert !entry.save
......
142 144
    end
143 145
  end
144 146

  
147
  def test_should_allow_time_entries_on_locked_dates_for_users_with_permission
148
    User.current = User.find(2)
149

  
150
    with_settings :timelog_lock_days_older_than => '5' do
151
      entry = TimeEntry.generate(:project => Project.find(1))
152
      entry.spent_on = Date.today - 6
153

  
154
      assert entry.save
155
    end
156
  end
157

  
158
  def test_should_not_allow_time_entries_on_locked_dates_for_users_without_permission
159
    User.current = User.find(2)
160
    Role.find(1).remove_permission!(:manage_time_entries_on_locked_dates)
161

  
162
    with_settings :timelog_lock_days_older_than => '5' do
163
      entry = TimeEntry.generate(:project => Project.find(1))
164
      entry.spent_on = Date.today - 6
165

  
166
      assert !entry.save
167
      assert entry.errors[:base].present?
168
    end
169
  end
170

  
171
  def test_editable_by_should_return_true_for_time_entry_on_locked_date_and_user_with_permission
172
      user = User.find(2)
173
      User.current = user
174
      time_entry = TimeEntry.find(1)
175

  
176
      with_settings :timelog_lock_days_older_than => '5' do
177
        assert time_entry.editable_by?(user)
178
    end
179
  end
180

  
181
  def test_editable_by_should_return_false_for_time_entry_on_locked_date_and_user_without_permission
182
      user = User.find(2)
183
      User.current = user
184
      Role.find(1).remove_permission!(:manage_time_entries_on_locked_dates)
185
      time_entry = TimeEntry.find(1)
186

  
187
      with_settings :timelog_lock_days_older_than => '5' do
188
        assert !time_entry.editable_by?(user)
189
    end
190
  end
191

  
145 192
  def test_spent_on_with_blank
146 193
    c = TimeEntry.new
147 194
    c.spent_on = ''
(8-8/8)