Revision 2313
Added by Jean-Philippe Lang over 16 years ago
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
Adds ability to bulk copy issues (#1847).
This can be done by checking the 'Copy' checkbox on the 'Move' form.