Project

General

Profile

Feature #13596 » 0001-Adds-setting-to-allow-timelog-on-closed-issues.patch

Marius BĂLTEANU, 2024-12-11 20:58

View differences:

app/controllers/context_menus_controller.rb
33 33

  
34 34
    @can = {
35 35
      :edit => @issues.all?(&:attributes_editable?),
36
      :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
36
      :log_time => @issue&.time_loggable?,
37 37
      :copy => User.current.allowed_to?(:copy_issues, @projects) && Issue.allowed_target_projects.any?,
38 38
      :add_watchers => User.current.allowed_to?(:add_issue_watchers, @projects),
39 39
      :delete => @issues.all?(&:deletable?),
app/models/issue.rb
188 188
    end
189 189
  end
190 190

  
191
  # Returns true if user or current user is allowed to log time on the issue
192
  def time_loggable?(user=User.current)
193
    user.allowed_to?(:log_time, project) && (!Setting.timelog_accept_future_dates? || !closed?)
194
  end
195

  
191 196
  # Returns true if user or current user is allowed to edit or add notes to the issue
192 197
  def editable?(user=User.current)
193 198
    attributes_editable?(user) || notes_addable?(user)
app/models/time_entry.rb
182 182
    if spent_on && spent_on_changed? && user
183 183
      errors.add :base, I18n.t(:error_spent_on_future_date) if !Setting.timelog_accept_future_dates? && (spent_on > user.today)
184 184
    end
185
    if !Setting.timelog_accept_closed_issues? && issue&.closed? && issue&.was_closed?
186
      errors.add :base, I18n.t(:error_spent_on_closed_issue)
187
    end
185 188
  end
186 189

  
187 190
  def hours=(h)
app/views/issues/_action_menu.html.erb
3 3
            :onclick => 'showAndScrollTo("update", "issue_notes"); return false;',
4 4
            :class => 'icon icon-edit ', :accesskey => accesskey(:edit) if @issue.editable? %>
5 5
<%= link_to sprite_icon('time-add', l(:button_log_time)), new_issue_time_entry_path(@issue),
6
            :class => 'icon icon-time-add ' if User.current.allowed_to?(:log_time, @project) %>
6
            :class => 'icon icon-time-add ' if @issue.time_loggable? %>
7 7
<%= watcher_link(@issue, User.current) %>
8 8
<%= link_to sprite_icon('copy', l(:button_copy)), project_copy_issue_path(@project, @issue),
9 9
            :class => 'icon icon-copy ' if User.current.allowed_to?(:copy_issues, @project) && Issue.allowed_target_projects.any? %>
app/views/issues/_edit.html.erb
9 9
        </div>
10 10
        </fieldset>
11 11
    <% end %>
12
    <% if User.current.allowed_to?(:log_time, @issue.project) %>
12
    <% if @issue.time_loggable? %>
13 13
        <fieldset class="tabular" id="log_time"><legend><%= l(:button_log_time) %></legend>
14 14
        <%= labelled_fields_for :time_entry, @time_entry do |time_entry| %>
15 15
        <div class="splitcontent">
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_check_box :timelog_accept_closed_issues %></p>
12 14
</div>
13 15

  
14 16
<fieldset class="box">
config/locales/en.yml
235 235
  error_exceeds_maximum_hours_per_day: "Cannot log more than %{max_hours} hours on the same day (%{logged_hours} hours have already been logged)"
236 236
  error_can_not_delete_auth_source: "This authentication mode is in use and cannot be deleted."
237 237
  error_spent_on_future_date: "Cannot log time on a future date"
238
  error_spent_on_closed_issue: "Cannot log time on a closed issue"
238 239
  error_not_allowed_to_log_time_for_other_users: "You are not allowed to log time for other users"
239 240
  error_can_not_execute_macro_html: "Error executing the <strong>%{name}</strong> macro (%{error})"
240 241
  error_macro_does_not_accept_block: "This macro does not accept a block of text"
......
519 520
  setting_timelog_accept_0_hours: Accept time logs with 0 hours
520 521
  setting_timelog_max_hours_per_day: Maximum hours that can be logged per day and user
521 522
  setting_timelog_accept_future_dates: Accept time logs on future dates
523
  setting_timelog_accept_closed_issues: Accept time logs on closed issues
522 524
  setting_show_status_changes_in_mail_subject: Show status changes in issue mail notifications subject
523 525
  setting_project_list_defaults: Projects list defaults
524 526
  setting_twofa: Two-factor authentication
config/settings.yml
347 347
  default: 999
348 348
timelog_accept_future_dates:
349 349
  default: 1
350
timelog_accept_closed_issues:
351
  default: 1
350 352
show_status_changes_in_mail_subject:
351 353
  default: 1
352 354
wiki_tablesort_enabled:
test/functional/issues_controller_test.rb
5885 5885
    assert_select 'input[name=?]', 'time_entry[hours]', 0
5886 5886
  end
5887 5887

  
5888
  def test_get_edit_should_not_display_the_time_entry_form_on_closed_issue
5889
    with_settings :timelog_accept_closed_issues => '0' do
5890
      @request.session[:user_id] = 2
5891
      issue = Issue.find(1)
5892
      issue.update :status => IssueStatus.find(5)
5893
      get(:edit, :params => {:id => 1})
5894
      assert_select 'input[name=?]', 'time_entry[hours]', 0
5895
    end
5896
  end
5897

  
5888 5898
  def test_get_edit_with_params
5889 5899
    @request.session[:user_id] = 2
5890 5900
    get(
......
6341 6351
    assert mail.subject.include?("(#{IssueStatus.find(2).name})")
6342 6352
  end
6343 6353

  
6354
  def test_update_should_accept_time_entry_when_closing_issue
6355
    with_settings :timelog_accept_closed_issues => '0' do
6356
      issue = Issue.find(1)
6357
      assert_equal 1, issue.status_id
6358
      @request.session[:user_id] = 2
6359
      assert_difference('TimeEntry.count', 1) do
6360
        put(
6361
          :update,
6362
          :params => {
6363
            :id => 1,
6364
            :issue => {
6365
              :status_id => 5,
6366
            },
6367
            :time_entry => {
6368
              :hours => '2',
6369
              :comments => '',
6370
              :activity_id => TimeEntryActivity.first
6371
            }
6372
          }
6373
        )
6374
      end
6375
      assert_redirected_to :action => 'show', :id => '1'
6376
      issue.reload
6377
      assert issue.closed?
6378
    end
6379
  end
6380

  
6381
  def test_update_should_not_accept_time_entry_on_closed_issue
6382
    with_settings :timelog_accept_closed_issues => '0' do
6383
      issue = Issue.find(1)
6384
      issue.update :status => IssueStatus.find(5)
6385
      @request.session[:user_id] = 2
6386
      assert_no_difference('TimeEntry.count') do
6387
        put(
6388
          :update,
6389
          :params => {
6390
            :id => 1,
6391
            :issue => {
6392
            },
6393
            :time_entry => {
6394
              :hours => '2',
6395
              :comments => '',
6396
              :activity_id => TimeEntryActivity.first
6397
            }
6398
          }
6399
        )
6400
      end
6401
      assert_response :success
6402
    end
6403
  end
6404

  
6344 6405
  def test_put_update_with_note_only
6345 6406
    notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
6346 6407

  
test/unit/time_entry_test.rb
175 175
    end
176 176
  end
177 177

  
178
  def test_should_not_accept_closed_issue
179
    with_settings :timelog_accept_closed_issues => '0' do
180
      project = Project.find(1)
181
      entry = TimeEntry.generate project: project
182
      issue = project.issues.to_a.detect(&:closed?)
183
      entry.issue = issue
184
      assert !entry.save
185
      assert entry.errors[:base].present?
186
      assert_equal 'Cannot log time on a closed issue', entry.errors[:base].first
187
    end
188
  end
189

  
178 190
  def test_should_require_spent_on
179 191
    with_settings :timelog_accept_future_dates => '0' do
180 192
      entry = TimeEntry.find(1)
(2-2/2)