Project

General

Profile

« Previous | Next » 

Revision 2313

Adds ability to bulk copy issues (#1847).
This can be done by checking the 'Copy' checkbox on the 'Move' form.

View differences:

trunk/app/controllers/issues_controller.rb
283 283
      unsaved_issue_ids = []
284 284
      @issues.each do |issue|
285 285
        issue.init_journal(User.current)
286
        unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker)
286
        unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker, params[:copy_options])
287 287
      end
288 288
      if unsaved_issue_ids.empty?
289 289
        flash[:notice] = l(:notice_successful_update) unless @issues.empty?
trunk/app/models/issue.rb
71 71
    self
72 72
  end
73 73
  
74
  # Move an issue to a new project and tracker
75
  def move_to(new_project, new_tracker = nil)
74
  # Moves/copies an issue to a new project and tracker
75
  # Returns the moved/copied issue on success, false on failure
76
  def move_to(new_project, new_tracker = nil, options = {})
77
    options ||= {}
78
    issue = options[:copy] ? self.clone : self
76 79
    transaction do
77
      if new_project && project_id != new_project.id
80
      if new_project && issue.project_id != new_project.id
78 81
        # delete issue relations
79 82
        unless Setting.cross_project_issue_relations?
80
          self.relations_from.clear
81
          self.relations_to.clear
83
          issue.relations_from.clear
84
          issue.relations_to.clear
82 85
        end
83 86
        # issue is moved to another project
84 87
        # reassign to the category with same name if any
85
        new_category = category.nil? ? nil : new_project.issue_categories.find_by_name(category.name)
86
        self.category = new_category
87
        self.fixed_version = nil
88
        self.project = new_project
88
        new_category = issue.category.nil? ? nil : new_project.issue_categories.find_by_name(issue.category.name)
89
        issue.category = new_category
90
        issue.fixed_version = nil
91
        issue.project = new_project
89 92
      end
90 93
      if new_tracker
91
        self.tracker = new_tracker
94
        issue.tracker = new_tracker
92 95
      end
93
      if save
94
        # Manually update project_id on related time entries
95
        TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id})
96
      if options[:copy]
97
        issue.custom_field_values = self.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
98
        issue.status = self.status
99
      end
100
      if issue.save
101
        unless options[:copy]
102
          # Manually update project_id on related time entries
103
          TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id})
104
        end
96 105
      else
97
        rollback_db_transaction
106
        Issue.connection.rollback_db_transaction
98 107
        return false
99 108
      end
100 109
    end
101
    return true
110
    return issue
102 111
  end
103 112
  
104 113
  def priority_id=(pid)
trunk/app/views/issues/move.rhtml
16 16

  
17 17
<p><label for="new_tracker_id"><%=l(:field_tracker)%> :</label>
18 18
<%= select_tag "new_tracker_id", "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@trackers, "id", "name") %></p>
19

  
20
<p><label for="copy_options_copy"><%= l(:button_copy)%></label>
21
<%= check_box_tag "copy_options[copy]", "1" %></p>
19 22
</div>
20 23

  
21 24
<%= submit_tag l(:button_move) %>
trunk/test/functional/issues_controller_test.rb
672 672
    assert_equal 2, Issue.find(1).tracker_id
673 673
    assert_equal 2, Issue.find(2).tracker_id
674 674
  end
675

  
676
  def test_bulk_copy_to_another_project
677
    @request.session[:user_id] = 1
678
    assert_difference 'Issue.count', 2 do
679
      assert_no_difference 'Project.find(1).issues.count' do
680
        post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
681
      end
682
    end
683
    assert_redirected_to 'projects/ecookbook/issues'
684
  end
675 685
  
676 686
  def test_context_menu_one_issue
677 687
    @request.session[:user_id] = 2
trunk/test/unit/issue_test.rb
191 191
    assert_nil issue.category_id
192 192
  end
193 193
  
194
  def test_copy_to_the_same_project
195
    issue = Issue.find(1)
196
    copy = nil
197
    assert_difference 'Issue.count' do
198
      copy = issue.move_to(issue.project, nil, :copy => true)
199
    end
200
    assert_kind_of Issue, copy
201
    assert_equal issue.project, copy.project
202
    assert_equal "125", copy.custom_value_for(2).value
203
  end
204
  
205
  def test_copy_to_another_project_and_tracker
206
    issue = Issue.find(1)
207
    copy = nil
208
    assert_difference 'Issue.count' do
209
      copy = issue.move_to(Project.find(3), Tracker.find(2), :copy => true)
210
    end
211
    assert_kind_of Issue, copy
212
    assert_equal Project.find(3), copy.project
213
    assert_equal Tracker.find(2), copy.tracker
214
    # Custom field #2 is not associated with target tracker
215
    assert_nil copy.custom_value_for(2)
216
  end
217
  
194 218
  def test_issue_destroy
195 219
    Issue.find(1).destroy
196 220
    assert_nil Issue.find_by_id(1)

Also available in: Unified diff