This can be done by checking the 'Copy' checkbox on the 'Move' form. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2313 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/0.9.0
@@ -283,7 +283,7 @@ class IssuesController < ApplicationController | |||
unsaved_issue_ids = [] | |||
@issues.each do |issue| | |||
issue.init_journal(User.current) | |||
unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker) | |||
unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker, params[:copy_options]) | |||
end | |||
if unsaved_issue_ids.empty? | |||
flash[:notice] = l(:notice_successful_update) unless @issues.empty? |
@@ -71,34 +71,43 @@ class Issue < ActiveRecord::Base | |||
self | |||
end | |||
# Move an issue to a new project and tracker | |||
def move_to(new_project, new_tracker = nil) | |||
# Moves/copies an issue to a new project and tracker | |||
# Returns the moved/copied issue on success, false on failure | |||
def move_to(new_project, new_tracker = nil, options = {}) | |||
options ||= {} | |||
issue = options[:copy] ? self.clone : self | |||
transaction do | |||
if new_project && project_id != new_project.id | |||
if new_project && issue.project_id != new_project.id | |||
# delete issue relations | |||
unless Setting.cross_project_issue_relations? | |||
self.relations_from.clear | |||
self.relations_to.clear | |||
issue.relations_from.clear | |||
issue.relations_to.clear | |||
end | |||
# issue is moved to another project | |||
# reassign to the category with same name if any | |||
new_category = category.nil? ? nil : new_project.issue_categories.find_by_name(category.name) | |||
self.category = new_category | |||
self.fixed_version = nil | |||
self.project = new_project | |||
new_category = issue.category.nil? ? nil : new_project.issue_categories.find_by_name(issue.category.name) | |||
issue.category = new_category | |||
issue.fixed_version = nil | |||
issue.project = new_project | |||
end | |||
if new_tracker | |||
self.tracker = new_tracker | |||
issue.tracker = new_tracker | |||
end | |||
if save | |||
# Manually update project_id on related time entries | |||
TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id}) | |||
if options[:copy] | |||
issue.custom_field_values = self.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h} | |||
issue.status = self.status | |||
end | |||
if issue.save | |||
unless options[:copy] | |||
# Manually update project_id on related time entries | |||
TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id}) | |||
end | |||
else | |||
rollback_db_transaction | |||
Issue.connection.rollback_db_transaction | |||
return false | |||
end | |||
end | |||
return true | |||
return issue | |||
end | |||
def priority_id=(pid) |
@@ -16,6 +16,9 @@ | |||
<p><label for="new_tracker_id"><%=l(:field_tracker)%> :</label> | |||
<%= select_tag "new_tracker_id", "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@trackers, "id", "name") %></p> | |||
<p><label for="copy_options_copy"><%= l(:button_copy)%></label> | |||
<%= check_box_tag "copy_options[copy]", "1" %></p> | |||
</div> | |||
<%= submit_tag l(:button_move) %> |
@@ -672,6 +672,16 @@ class IssuesControllerTest < Test::Unit::TestCase | |||
assert_equal 2, Issue.find(1).tracker_id | |||
assert_equal 2, Issue.find(2).tracker_id | |||
end | |||
def test_bulk_copy_to_another_project | |||
@request.session[:user_id] = 1 | |||
assert_difference 'Issue.count', 2 do | |||
assert_no_difference 'Project.find(1).issues.count' do | |||
post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'} | |||
end | |||
end | |||
assert_redirected_to 'projects/ecookbook/issues' | |||
end | |||
def test_context_menu_one_issue | |||
@request.session[:user_id] = 2 |
@@ -191,6 +191,30 @@ class IssueTest < Test::Unit::TestCase | |||
assert_nil issue.category_id | |||
end | |||
def test_copy_to_the_same_project | |||
issue = Issue.find(1) | |||
copy = nil | |||
assert_difference 'Issue.count' do | |||
copy = issue.move_to(issue.project, nil, :copy => true) | |||
end | |||
assert_kind_of Issue, copy | |||
assert_equal issue.project, copy.project | |||
assert_equal "125", copy.custom_value_for(2).value | |||
end | |||
def test_copy_to_another_project_and_tracker | |||
issue = Issue.find(1) | |||
copy = nil | |||
assert_difference 'Issue.count' do | |||
copy = issue.move_to(Project.find(3), Tracker.find(2), :copy => true) | |||
end | |||
assert_kind_of Issue, copy | |||
assert_equal Project.find(3), copy.project | |||
assert_equal Tracker.find(2), copy.tracker | |||
# Custom field #2 is not associated with target tracker | |||
assert_nil copy.custom_value_for(2) | |||
end | |||
def test_issue_destroy | |||
Issue.find(1).destroy | |||
assert_nil Issue.find_by_id(1) |