From c4b1ab644ee60e18d0a62f3ab1ecb6aa57c1d731 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Wed, 4 Jan 2017 20:47:29 +0000 Subject: 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 --- app/controllers/issues_controller.rb | 17 ++++++++++++----- app/models/issue.rb | 9 +++++++++ app/views/issues/destroy.html.erb | 2 ++ 3 files changed, 23 insertions(+), 5 deletions(-) (limited to 'app') 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 @@



+<% if @project %> <%= text_field_tag 'reassign_to_id', params[:reassign_to_id], :size => 6, :onfocus => '$("#todo_reassign").attr("checked", true);' %> +<% end %>

<%= submit_tag l(:button_apply) %> -- cgit v1.2.3