summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2017-01-04 20:47:29 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2017-01-04 20:47:29 +0000
commitc4b1ab644ee60e18d0a62f3ab1ecb6aa57c1d731 (patch)
tree6ce9e42c502e0e76b39d2ff60b3a803a6655e47b /app
parent82a67f4ebe5ac133bede65b7366d5ea31b05f8dc (diff)
downloadredmine-c4b1ab644ee60e18d0a62f3ab1ecb6aa57c1d731.tar.gz
redmine-c4b1ab644ee60e18d0a62f3ab1ecb6aa57c1d731.zip
Merged r16118 to r16122 (#24693, #24718, #24722).
git-svn-id: http://svn.redmine.org/redmine/branches/3.3-stable@16132 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/controllers/issues_controller.rb17
-rw-r--r--app/models/issue.rb9
-rw-r--r--app/views/issues/destroy.html.erb2
3 files changed, 23 insertions, 5 deletions
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index c640aadbe..a3cd8fb9f 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -325,21 +325,28 @@ class IssuesController < ApplicationController
def destroy
raise Unauthorized unless @issues.all?(&:deletable?)
- @hours = TimeEntry.where(:issue_id => @issues.map(&:id)).sum(:hours).to_f
+
+ # all issues and their descendants are about to be deleted
+ issues_and_descendants_ids = Issue.self_and_descendants(@issues).pluck(:id)
+ time_entries = TimeEntry.where(:issue_id => issues_and_descendants_ids)
+ @hours = time_entries.sum(:hours).to_f
+
if @hours > 0
case params[:todo]
when 'destroy'
# nothing to do
when 'nullify'
- TimeEntry.where(['issue_id IN (?)', @issues]).update_all('issue_id = NULL')
+ time_entries.update_all(:issue_id => nil)
when 'reassign'
- reassign_to = @project.issues.find_by_id(params[:reassign_to_id])
+ reassign_to = @project && @project.issues.find_by_id(params[:reassign_to_id])
if reassign_to.nil?
flash.now[:error] = l(:error_issue_not_found_in_project)
return
+ elsif issues_and_descendants_ids.include?(reassign_to.id)
+ flash.now[:error] = l(:error_cannot_reassign_time_entries_to_an_issue_about_to_be_deleted)
+ return
else
- TimeEntry.where(['issue_id IN (?)', @issues]).
- update_all("issue_id = #{reassign_to.id}")
+ time_entries.update_all(:issue_id => reassign_to.id, :project_id => reassign_to.project_id)
end
else
# display the destroy form if it's a user request
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 58d51e139..f569ed0b2 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -1081,6 +1081,15 @@ class Issue < ActiveRecord::Base
end
end
+ # Returns a scope of the given issues and their descendants
+ def self.self_and_descendants(issues)
+ Issue.joins("JOIN #{Issue.table_name} ancestors" +
+ " ON ancestors.root_id = #{Issue.table_name}.root_id" +
+ " AND ancestors.lft <= #{Issue.table_name}.lft AND ancestors.rgt >= #{Issue.table_name}.rgt"
+ ).
+ where(:ancestors => {:id => issues.map(&:id)})
+ end
+
# Finds an issue relation given its id.
def find_relation(relation_id)
IssueRelation.where("issue_to_id = ? OR issue_from_id = ?", id, id).find(relation_id)
diff --git a/app/views/issues/destroy.html.erb b/app/views/issues/destroy.html.erb
index 4a0631e68..83da014cd 100644
--- a/app/views/issues/destroy.html.erb
+++ b/app/views/issues/destroy.html.erb
@@ -7,8 +7,10 @@
<p>
<label><%= radio_button_tag 'todo', 'destroy', true %> <%= l(:text_destroy_time_entries) %></label><br />
<label><%= radio_button_tag 'todo', 'nullify', false %> <%= l(:text_assign_time_entries_to_project) %></label><br />
+<% if @project %>
<label><%= radio_button_tag 'todo', 'reassign', false, :onchange => 'if (this.checked) { $("#reassign_to_id").focus(); }' %> <%= l(:text_reassign_time_entries) %></label>
<%= text_field_tag 'reassign_to_id', params[:reassign_to_id], :size => 6, :onfocus => '$("#todo_reassign").attr("checked", true);' %>
+<% end %>
</p>
</div>
<%= submit_tag l(:button_apply) %>