mirror of
https://github.com/redmine/redmine.git
synced 2025-11-08 06:15:59 +01:00
Extend Issue Summary to include subprojects (#2529).
Patch by Mizuki ISHIKAWA. git-svn-id: http://svn.redmine.org/redmine/trunk@17563 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -27,49 +27,50 @@ class ReportsController < ApplicationController
|
|||||||
@assignees = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
|
@assignees = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
|
||||||
@authors = @project.users.sort
|
@authors = @project.users.sort
|
||||||
@subprojects = @project.descendants.visible
|
@subprojects = @project.descendants.visible
|
||||||
|
with_subprojects = Setting.display_subprojects_issues?
|
||||||
@issues_by_tracker = Issue.by_tracker(@project)
|
@issues_by_tracker = Issue.by_tracker(@project, with_subprojects)
|
||||||
@issues_by_version = Issue.by_version(@project)
|
@issues_by_version = Issue.by_version(@project, with_subprojects)
|
||||||
@issues_by_priority = Issue.by_priority(@project)
|
@issues_by_priority = Issue.by_priority(@project, with_subprojects)
|
||||||
@issues_by_category = Issue.by_category(@project)
|
@issues_by_category = Issue.by_category(@project, with_subprojects)
|
||||||
@issues_by_assigned_to = Issue.by_assigned_to(@project)
|
@issues_by_assigned_to = Issue.by_assigned_to(@project, with_subprojects)
|
||||||
@issues_by_author = Issue.by_author(@project)
|
@issues_by_author = Issue.by_author(@project, with_subprojects)
|
||||||
@issues_by_subproject = Issue.by_subproject(@project) || []
|
@issues_by_subproject = Issue.by_subproject(@project) || []
|
||||||
|
|
||||||
render :template => "reports/issue_report"
|
render :template => "reports/issue_report"
|
||||||
end
|
end
|
||||||
|
|
||||||
def issue_report_details
|
def issue_report_details
|
||||||
|
with_subprojects = Setting.display_subprojects_issues?
|
||||||
case params[:detail]
|
case params[:detail]
|
||||||
when "tracker"
|
when "tracker"
|
||||||
@field = "tracker_id"
|
@field = "tracker_id"
|
||||||
@rows = @project.rolled_up_trackers(false).visible
|
@rows = @project.rolled_up_trackers(false).visible
|
||||||
@data = Issue.by_tracker(@project)
|
@data = Issue.by_tracker(@project, with_subprojects)
|
||||||
@report_title = l(:field_tracker)
|
@report_title = l(:field_tracker)
|
||||||
when "version"
|
when "version"
|
||||||
@field = "fixed_version_id"
|
@field = "fixed_version_id"
|
||||||
@rows = @project.shared_versions.sort
|
@rows = @project.shared_versions.sort
|
||||||
@data = Issue.by_version(@project)
|
@data = Issue.by_version(@project, with_subprojects)
|
||||||
@report_title = l(:field_version)
|
@report_title = l(:field_version)
|
||||||
when "priority"
|
when "priority"
|
||||||
@field = "priority_id"
|
@field = "priority_id"
|
||||||
@rows = IssuePriority.all.reverse
|
@rows = IssuePriority.all.reverse
|
||||||
@data = Issue.by_priority(@project)
|
@data = Issue.by_priority(@project, with_subprojects)
|
||||||
@report_title = l(:field_priority)
|
@report_title = l(:field_priority)
|
||||||
when "category"
|
when "category"
|
||||||
@field = "category_id"
|
@field = "category_id"
|
||||||
@rows = @project.issue_categories
|
@rows = @project.issue_categories
|
||||||
@data = Issue.by_category(@project)
|
@data = Issue.by_category(@project, with_subprojects)
|
||||||
@report_title = l(:field_category)
|
@report_title = l(:field_category)
|
||||||
when "assigned_to"
|
when "assigned_to"
|
||||||
@field = "assigned_to_id"
|
@field = "assigned_to_id"
|
||||||
@rows = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
|
@rows = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
|
||||||
@data = Issue.by_assigned_to(@project)
|
@data = Issue.by_assigned_to(@project, with_subprojects)
|
||||||
@report_title = l(:field_assigned_to)
|
@report_title = l(:field_assigned_to)
|
||||||
when "author"
|
when "author"
|
||||||
@field = "author_id"
|
@field = "author_id"
|
||||||
@rows = @project.users.sort
|
@rows = @project.users.sort
|
||||||
@data = Issue.by_author(@project)
|
@data = Issue.by_author(@project, with_subprojects)
|
||||||
@report_title = l(:field_author)
|
@report_title = l(:field_author)
|
||||||
when "subproject"
|
when "subproject"
|
||||||
@field = "project_id"
|
@field = "project_id"
|
||||||
|
|||||||
@@ -1464,28 +1464,28 @@ class Issue < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.by_tracker(project)
|
def self.by_tracker(project, with_subprojects=false)
|
||||||
count_and_group_by(:project => project, :association => :tracker)
|
count_and_group_by(:project => project, :association => :tracker, :with_subprojects => with_subprojects)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.by_version(project)
|
def self.by_version(project, with_subprojects=false)
|
||||||
count_and_group_by(:project => project, :association => :fixed_version)
|
count_and_group_by(:project => project, :association => :fixed_version, :with_subprojects => with_subprojects)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.by_priority(project)
|
def self.by_priority(project, with_subprojects=false)
|
||||||
count_and_group_by(:project => project, :association => :priority)
|
count_and_group_by(:project => project, :association => :priority, :with_subprojects => with_subprojects)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.by_category(project)
|
def self.by_category(project, with_subprojects=false)
|
||||||
count_and_group_by(:project => project, :association => :category)
|
count_and_group_by(:project => project, :association => :category, :with_subprojects => with_subprojects)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.by_assigned_to(project)
|
def self.by_assigned_to(project, with_subprojects=false)
|
||||||
count_and_group_by(:project => project, :association => :assigned_to)
|
count_and_group_by(:project => project, :association => :assigned_to, :with_subprojects => with_subprojects)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.by_author(project)
|
def self.by_author(project, with_subprojects=false)
|
||||||
count_and_group_by(:project => project, :association => :author)
|
count_and_group_by(:project => project, :association => :author, :with_subprojects => with_subprojects)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.by_subproject(project)
|
def self.by_subproject(project)
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<% for row in rows %>
|
<% for row in rows %>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="name"><%= link_to row.name, aggregate_path(@project, field_name, row) %></td>
|
<td class="name"><%= link_to row.name, aggregate_path(@project, field_name, row, :subproject_id => nil) %></td>
|
||||||
<% for status in @statuses %>
|
<% for status in @statuses %>
|
||||||
<td><%= aggregate_link data, { field_name => row.id, "status_id" => status.id }, aggregate_path(@project, field_name, row, :status_id => status.id) %></td>
|
<td><%= aggregate_link data, { field_name => row.id, "status_id" => status.id }, aggregate_path(@project, field_name, row, :status_id => status.id, :subproject_id => nil) %></td>
|
||||||
<% end %>
|
<% end %>
|
||||||
<td><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o") %></td>
|
<td><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o", :subproject_id => nil) %></td>
|
||||||
<td><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c") %></td>
|
<td><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c", :subproject_id => nil) %></td>
|
||||||
<td><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*") %></td>
|
<td><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*", :subproject_id => nil) %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<% for row in rows %>
|
<% for row in rows %>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="name"><%= link_to row.name, aggregate_path(@project, field_name, row) %></td>
|
<td class="name"><%= link_to row.name, aggregate_path(@project, field_name, row, :subproject_id => nil) %></td>
|
||||||
<td><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o") %></td>
|
<td><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o", :subproject_id => nil) %></td>
|
||||||
<td><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c") %></td>
|
<td><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c", :subproject_id => nil) %></td>
|
||||||
<td><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*") %></td>
|
<td><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*", :subproject_id => nil) %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -34,6 +34,38 @@ class ReportsControllerTest < Redmine::ControllerTest
|
|||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_issue_report_with_subprojects_issues
|
||||||
|
Setting.stubs(:display_subprojects_issues?).returns(true)
|
||||||
|
get :issue_report, :params => {
|
||||||
|
:id => 1
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_response :success
|
||||||
|
# Count subprojects issues
|
||||||
|
assert_select 'table.list tbody :nth-child(1):first' do
|
||||||
|
assert_select 'td', :text => 'Bug'
|
||||||
|
assert_select ':nth-child(2)', :text => '5' # open
|
||||||
|
assert_select ':nth-child(3)', :text => '3' # closed
|
||||||
|
assert_select ':nth-child(4)', :text => '8' # total
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_issue_report_without_subprojects_issues
|
||||||
|
Setting.stubs(:display_subprojects_issues?).returns(false)
|
||||||
|
get :issue_report, :params => {
|
||||||
|
:id => 1
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_response :success
|
||||||
|
# Do not count subprojects issues
|
||||||
|
assert_select 'table.list tbody :nth-child(1):first' do
|
||||||
|
assert_select 'td', :text => 'Bug'
|
||||||
|
assert_select ':nth-child(2)', :text => '3' # open
|
||||||
|
assert_select ':nth-child(3)', :text => '3' # closed
|
||||||
|
assert_select ':nth-child(4)', :text => '6' # total
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_get_issue_report_details
|
def test_get_issue_report_details
|
||||||
%w(tracker version priority category assigned_to author subproject).each do |detail|
|
%w(tracker version priority category assigned_to author subproject).each do |detail|
|
||||||
get :issue_report_details, :params => {
|
get :issue_report_details, :params => {
|
||||||
@@ -45,6 +77,7 @@ class ReportsControllerTest < Redmine::ControllerTest
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_get_issue_report_details_by_tracker_should_show_only_statuses_used_by_the_project
|
def test_get_issue_report_details_by_tracker_should_show_only_statuses_used_by_the_project
|
||||||
|
Setting.stubs(:display_subprojects_issues?).returns(false)
|
||||||
WorkflowTransition.delete_all
|
WorkflowTransition.delete_all
|
||||||
WorkflowTransition.create(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
|
WorkflowTransition.create(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
|
||||||
WorkflowTransition.create(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
|
WorkflowTransition.create(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
|
||||||
@@ -70,6 +103,52 @@ class ReportsControllerTest < Redmine::ControllerTest
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_get_issue_report_details_by_tracker_with_subprojects_issues
|
||||||
|
Setting.stubs(:display_subprojects_issues?).returns(true)
|
||||||
|
get :issue_report_details, :params => {
|
||||||
|
:id => 1,
|
||||||
|
:detail => 'tracker'
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_response :success
|
||||||
|
# Count subprojects issues
|
||||||
|
assert_select 'table.list tbody :nth-child(1)' do
|
||||||
|
assert_select 'td', :text => 'Bug'
|
||||||
|
assert_select ':nth-child(2)', :text => '5' # status:1
|
||||||
|
assert_select ':nth-child(3)', :text => '-' # status:2
|
||||||
|
assert_select ':nth-child(4)', :text => '-' # status:3
|
||||||
|
assert_select ':nth-child(5)', :text => '-' # status:4
|
||||||
|
assert_select ':nth-child(6)', :text => '3' # status:5
|
||||||
|
assert_select ':nth-child(7)', :text => '-' # status:6
|
||||||
|
assert_select ':nth-child(8)', :text => '5' # open
|
||||||
|
assert_select ':nth-child(9)', :text => '3' # closed
|
||||||
|
assert_select ':nth-child(10)', :text => '8' # total
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_get_issue_report_details_by_tracker_without_subprojects_issues
|
||||||
|
Setting.stubs(:display_subprojects_issues?).returns(false)
|
||||||
|
get :issue_report_details, :params => {
|
||||||
|
:id => 1,
|
||||||
|
:detail => 'tracker'
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_response :success
|
||||||
|
# Do not count subprojects issues
|
||||||
|
assert_select 'table.list tbody :nth-child(1)' do
|
||||||
|
assert_select 'td', :text => 'Bug'
|
||||||
|
assert_select ':nth-child(2)', :text => '3' # status:1
|
||||||
|
assert_select ':nth-child(3)', :text => '-' # status:2
|
||||||
|
assert_select ':nth-child(4)', :text => '-' # status:3
|
||||||
|
assert_select ':nth-child(5)', :text => '-' # status:4
|
||||||
|
assert_select ':nth-child(6)', :text => '3' # status:5
|
||||||
|
assert_select ':nth-child(7)', :text => '-' # status:6
|
||||||
|
assert_select ':nth-child(8)', :text => '3' # open
|
||||||
|
assert_select ':nth-child(9)', :text => '3' # closed
|
||||||
|
assert_select ':nth-child(10)', :text => '6' # total
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_get_issue_report_details_by_tracker_should_show_issue_count
|
def test_get_issue_report_details_by_tracker_should_show_issue_count
|
||||||
Issue.delete_all
|
Issue.delete_all
|
||||||
Issue.generate!(:tracker_id => 1)
|
Issue.generate!(:tracker_id => 1)
|
||||||
|
|||||||
@@ -2756,45 +2756,63 @@ class IssueTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "#by_tracker" do
|
test "#by_tracker" do
|
||||||
User.current = User.anonymous
|
User.current = User.find(2)
|
||||||
groups = Issue.by_tracker(Project.find(1))
|
groups = Issue.by_tracker(Project.find(1))
|
||||||
assert_equal 3, groups.count
|
groups_containing_subprojects = Issue.by_tracker(Project.find(1), true)
|
||||||
assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
|
assert_equal 13, groups_containing_subprojects.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "#by_version" do
|
test "#by_version" do
|
||||||
User.current = User.anonymous
|
User.current = User.find(2)
|
||||||
groups = Issue.by_version(Project.find(1))
|
project = Project.find(1)
|
||||||
assert_equal 3, groups.count
|
Issue.generate!(:project_id => project.descendants.visible.first, :fixed_version_id => project.shared_versions.find_by(:sharing => 'tree').id)
|
||||||
|
|
||||||
|
groups = Issue.by_version(project)
|
||||||
|
groups_containing_subprojects = Issue.by_version(project, true)
|
||||||
assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
|
assert_equal 4, groups_containing_subprojects.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "#by_priority" do
|
test "#by_priority" do
|
||||||
User.current = User.anonymous
|
User.current = User.find(2)
|
||||||
groups = Issue.by_priority(Project.find(1))
|
project = Project.find(1)
|
||||||
assert_equal 4, groups.count
|
groups = Issue.by_priority(project)
|
||||||
|
groups_containing_subprojects = Issue.by_priority(project, true)
|
||||||
assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
|
assert_equal 13, groups_containing_subprojects.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "#by_category" do
|
test "#by_category" do
|
||||||
User.current = User.anonymous
|
User.current = User.find(2)
|
||||||
groups = Issue.by_category(Project.find(1))
|
project = Project.find(1)
|
||||||
assert_equal 2, groups.count
|
issue_category = IssueCategory.create(:project => project.descendants.visible.first, :name => 'test category')
|
||||||
|
Issue.generate!(:project_id => project.descendants.visible.first, :category_id => issue_category.id)
|
||||||
|
|
||||||
|
groups = Issue.by_category(project)
|
||||||
|
groups_containing_subprojects = Issue.by_category(project, true)
|
||||||
assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
|
assert_equal 4, groups_containing_subprojects.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "#by_assigned_to" do
|
test "#by_assigned_to" do
|
||||||
User.current = User.anonymous
|
User.current = User.find(2)
|
||||||
groups = Issue.by_assigned_to(Project.find(1))
|
project = Project.find(1)
|
||||||
assert_equal 2, groups.count
|
Issue.generate!(:project_id => project.descendants.visible.first, :assigned_to => User.current)
|
||||||
|
|
||||||
|
groups = Issue.by_assigned_to(project)
|
||||||
|
groups_containing_subprojects = Issue.by_assigned_to(project, true)
|
||||||
assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
|
assert_equal 3, groups_containing_subprojects.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "#by_author" do
|
test "#by_author" do
|
||||||
User.current = User.anonymous
|
User.current = User.find(2)
|
||||||
groups = Issue.by_author(Project.find(1))
|
project = Project.find(1)
|
||||||
assert_equal 4, groups.count
|
groups = Issue.by_author(project)
|
||||||
|
groups_containing_subprojects = Issue.by_author(project, true)
|
||||||
assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
|
assert_equal 13, groups_containing_subprojects.inject(0) {|sum, group| sum + group['total'].to_i}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "#by_subproject" do
|
test "#by_subproject" do
|
||||||
|
|||||||
Reference in New Issue
Block a user