Show warning and the reason when the issue cannot be closed or reopen because of open subtask(s), blocking issue(s) or closed parent issue (#31589).

Patch by Marius BALTEANU.


git-svn-id: http://svn.redmine.org/redmine/trunk@19570 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Go MAEDA
2020-03-10 03:50:47 +00:00
parent 463e8163fc
commit 5917137d12
5 changed files with 77 additions and 4 deletions

View File

@@ -56,6 +56,7 @@ class Issue < ActiveRecord::Base
DONE_RATIO_OPTIONS = %w(issue_field issue_status)
attr_reader :transition_warning
attr_writer :deleted_attachment_ids
delegate :notes, :notes=, :private_notes, :private_notes=, :to => :current_journal, :allow_nil => true
@@ -969,6 +970,28 @@ class Issue < ActiveRecord::Base
!relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil?
end
# Returns true if this issue can be closed and if not, returns false and populates the reason
def closable?
if descendants.open.any?
@transition_warning = l(:notice_issue_not_closable_by_open_tasks)
return false
end
if blocked?
@transition_warning = l(:notice_issue_not_closable_by_blocking_issue)
return false
end
return true
end
# Returns true if this issue can be reopen and if not, returns false and populates the reason
def reopenable?
if ancestors.open(false).any?
@transition_warning = l(:notice_issue_not_reopenable_by_closed_parent_issue)
return false
end
return true
end
# Returns the default status of the issue based on its tracker
# Returns nil if tracker is nil
def default_status
@@ -1008,11 +1031,11 @@ class Issue < ActiveRecord::Base
statuses << default_status if include_default || (new_record? && statuses.empty?)
statuses = statuses.compact.uniq.sort
if blocked? || descendants.open.any?
unless closable?
# cannot close a blocked issue or a parent with open subtasks
statuses.reject!(&:is_closed?)
end
if ancestors.open(false).any?
unless reopenable?
# cannot reopen a subtask of a closed parent
statuses.select!(&:is_closed?)
end

View File

@@ -3,8 +3,13 @@
<div class="splitcontent">
<div class="splitcontentleft">
<% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %>
<p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" %></p>
<p>
<%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" %>
<% if @issue.transition_warning %>
<span class="icon-only icon-warning" title="<%= @issue.transition_warning %>"><%= @issue.transition_warning %></span>
<% end %>
</p>
<%= hidden_field_tag 'was_default_status', @issue.status_id, :id => nil if @issue.status == @issue.default_status %>
<% else %>
<p><label><%= l(:field_status) %></label> <%= @issue.status %></p>