From d2aa87fdd2c342d4c944456817d209a78b5457c8 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Tue, 22 Feb 2011 09:10:15 -0800 Subject: [PATCH 1/6] [#5482] Add issue grouping by deliverable --- init.rb | 2 +- lib/redmine_contracts/patches/query_patch.rb | 15 +++++++ test/integration/issue_filtering_test.rb | 45 ++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 test/integration/issue_filtering_test.rb diff --git a/init.rb b/init.rb index 6dd2fac..d9edd6b 100644 --- a/init.rb +++ b/init.rb @@ -89,7 +89,7 @@ Dispatcher.to_prepare :redmine_contracts do end unless Query.available_columns.collect(&:name).include?(:deliverable_title) - Query.add_available_column(QueryColumn.new(:deliverable_title, :sortable => "#{Deliverable.table_name}.title")) + Query.add_available_column(QueryColumn.new(:deliverable_title, :sortable => "#{Deliverable.table_name}.title", :groupable => 'deliverable')) end unless Query.available_columns.collect(&:name).include?(:contract_name) diff --git a/lib/redmine_contracts/patches/query_patch.rb b/lib/redmine_contracts/patches/query_patch.rb index d5f4a91..fa8819a 100644 --- a/lib/redmine_contracts/patches/query_patch.rb +++ b/lib/redmine_contracts/patches/query_patch.rb @@ -12,6 +12,8 @@ module RedmineContracts alias_method_chain :available_filters, :contract alias_method_chain :sql_for_field, :contract + + alias_method_chain :issues, :deliverable end end @@ -83,6 +85,19 @@ module RedmineContracts end end + # Add the deliverables into the includes + # + # Used with grouping + def issues_with_deliverable(options={}) + options[:include] ||= [] + options[:include] << :deliverable + + issues_without_deliverable(options) + end + + # TODO: core bug: Query#issue_count_by_group doesn't allow setting + # options like Query#issue does. + end end end diff --git a/test/integration/issue_filtering_test.rb b/test/integration/issue_filtering_test.rb new file mode 100644 index 0000000..b831092 --- /dev/null +++ b/test/integration/issue_filtering_test.rb @@ -0,0 +1,45 @@ +require 'test_helper' + +class IssueFilteringTest < ActionController::IntegrationTest + include Redmine::I18n + + def setup + @project = Project.generate!(:identifier => 'main') + @contract = Contract.generate!(:project => @project) + @manager = User.generate! + @deliverable = FixedDeliverable.generate!(:contract => @contract, :manager => @manager) + @user = User.generate_user_with_permission_to_manage_budget(:project => @project).reload + @user.admin = true # Getting odd permissions issues + @user.save + @issue1 = Issue.generate_for_project!(@project) + @issue2 = Issue.generate_for_project!(@project, :deliverable => @deliverable) + assert_equal @deliverable, @issue2.deliverable + + login_as(@user.login, 'contracts') + end + + should "allow grouping issues by deliverable" do + visit_project(@project) + click_link "Issues" + + assert_select '#group_by' do + assert_select 'option', "Deliverable" + end + + select "Deliverable", :from => 'group_by' + + # Apply link is behind a JavaScript form + visit "/projects/#{@project.identifier}/issues/?set_filter&group_by=deliverable_title" + assert_response :success + + assert_select "tr.group" do + assert_select "td", :text => /None/ + end + + assert_select "tr.group" do + assert_select "td", :text => Regexp.new(@deliverable.title) + end + + end + +end From a0b92851a729f2a346497aae64bd7310e441ee42 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Tue, 22 Feb 2011 09:41:15 -0800 Subject: [PATCH 2/6] [#5482] Add issue grouping by contract --- init.rb | 2 +- lib/redmine_contracts/patches/query_patch.rb | 50 +++++++++++++++++++- test/integration/issue_filtering_test.rb | 24 ++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/init.rb b/init.rb index d9edd6b..594f0ee 100644 --- a/init.rb +++ b/init.rb @@ -93,7 +93,7 @@ Dispatcher.to_prepare :redmine_contracts do end unless Query.available_columns.collect(&:name).include?(:contract_name) - Query.add_available_column(QueryColumn.new(:contract_name, :sortable => "#{Contract.table_name}.name")) + Query.add_available_column(QueryColumn.new(:contract_name, :sortable => "#{Contract.table_name}.name", :groupable => 'contract_id')) end end diff --git a/lib/redmine_contracts/patches/query_patch.rb b/lib/redmine_contracts/patches/query_patch.rb index fa8819a..35779fe 100644 --- a/lib/redmine_contracts/patches/query_patch.rb +++ b/lib/redmine_contracts/patches/query_patch.rb @@ -14,6 +14,34 @@ module RedmineContracts alias_method_chain :sql_for_field, :contract alias_method_chain :issues, :deliverable + alias_method_chain :issues, :contract + + # Override Query#count_by_group to allow adding include options like + # Query#issues + # TODO: core bug: Query#issue_count_by_group doesn't allow setting + # options like Query#issue does. + def issue_count_by_group(options={}) + includes = ([:status, :project] + (options[:include] || [])).uniq + + r = nil + if grouped? + begin + # Rails will raise an (unexpected) RecordNotFound if there's only a nil group value + r = Issue.count(:group => group_by_statement, :include => includes, :conditions => statement) + rescue ActiveRecord::RecordNotFound + r = {nil => issue_count} + end + c = group_by_column + if c.is_a?(QueryCustomFieldColumn) + r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h} + end + end + r + rescue ::ActiveRecord::StatementInvalid => e + raise ::Query::StatementInvalid.new(e.message) + end + + alias_method_chain :issue_count_by_group, :contract end end @@ -95,8 +123,26 @@ module RedmineContracts issues_without_deliverable(options) end - # TODO: core bug: Query#issue_count_by_group doesn't allow setting - # options like Query#issue does. + # Add the contracts into the includes + # + # Used with grouping + def issues_with_contract(options={}) + options[:include] ||= [] + options[:include] << {:deliverable => :contract} + + issues_without_contract(options) + end + + # Add the contracts into the includes + # + # Used with grouping + def issue_count_by_group_with_contract(options={}) + options[:include] ||= [] + options[:include] << {:deliverable => :contract} + + issue_count_by_group_without_contract(options) + end + end end diff --git a/test/integration/issue_filtering_test.rb b/test/integration/issue_filtering_test.rb index b831092..60d73fe 100644 --- a/test/integration/issue_filtering_test.rb +++ b/test/integration/issue_filtering_test.rb @@ -42,4 +42,28 @@ class IssueFilteringTest < ActionController::IntegrationTest end + should "allow grouping issues by contract" do + visit_project(@project) + click_link "Issues" + + assert_select '#group_by' do + assert_select 'option', "Contract" + end + + select "Contract", :from => 'group_by' + + # Apply link is behind a JavaScript form + visit "/projects/#{@project.identifier}/issues/?set_filter&group_by=contract_name" + assert_response :success + + assert_select "tr.group" do + assert_select "td", :text => /None/ + end + + assert_select "tr.group" do + assert_select "td", :text => Regexp.new(@contract.name) + end + + end + end From 96fa509a1e93256492aef497c4b3f80ad7f5ed7f Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Tue, 22 Feb 2011 10:11:04 -0800 Subject: [PATCH 3/6] [#5482] Change deliverable QueryColumn so the grouped counts are shown --- init.rb | 4 ++-- test/integration/issue_filtering_test.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/init.rb b/init.rb index 594f0ee..0530c55 100644 --- a/init.rb +++ b/init.rb @@ -88,8 +88,8 @@ Dispatcher.to_prepare :redmine_contracts do Query.send(:include, RedmineContracts::Patches::QueryPatch) end - unless Query.available_columns.collect(&:name).include?(:deliverable_title) - Query.add_available_column(QueryColumn.new(:deliverable_title, :sortable => "#{Deliverable.table_name}.title", :groupable => 'deliverable')) + unless Query.available_columns.collect(&:name).include?(:deliverable) + Query.add_available_column(QueryColumn.new(:deliverable, :sortable => "#{Deliverable.table_name}.title", :groupable => 'deliverable')) end unless Query.available_columns.collect(&:name).include?(:contract_name) diff --git a/test/integration/issue_filtering_test.rb b/test/integration/issue_filtering_test.rb index 60d73fe..85015ad 100644 --- a/test/integration/issue_filtering_test.rb +++ b/test/integration/issue_filtering_test.rb @@ -29,7 +29,7 @@ class IssueFilteringTest < ActionController::IntegrationTest select "Deliverable", :from => 'group_by' # Apply link is behind a JavaScript form - visit "/projects/#{@project.identifier}/issues/?set_filter&group_by=deliverable_title" + visit "/projects/#{@project.identifier}/issues/?set_filter&group_by=deliverable" assert_response :success assert_select "tr.group" do From 7d7d6da8b56295ece9ddabff29ce319f5c75c33b Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Tue, 22 Feb 2011 10:34:42 -0800 Subject: [PATCH 4/6] [#5482] Add tests for the grouping counts --- test/integration/issue_filtering_test.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/integration/issue_filtering_test.rb b/test/integration/issue_filtering_test.rb index 85015ad..71a0544 100644 --- a/test/integration/issue_filtering_test.rb +++ b/test/integration/issue_filtering_test.rb @@ -33,11 +33,15 @@ class IssueFilteringTest < ActionController::IntegrationTest assert_response :success assert_select "tr.group" do - assert_select "td", :text => /None/ + assert_select "td", :text => /None/ do + assert_select "span.count", "(1)" + end end assert_select "tr.group" do - assert_select "td", :text => Regexp.new(@deliverable.title) + assert_select "td", :text => Regexp.new(@deliverable.title) do + assert_select "span.count", "(1)" + end end end @@ -57,11 +61,15 @@ class IssueFilteringTest < ActionController::IntegrationTest assert_response :success assert_select "tr.group" do - assert_select "td", :text => /None/ + assert_select "td", :text => /None/ do + assert_select "span.count", "(1)" + end end assert_select "tr.group" do - assert_select "td", :text => Regexp.new(@contract.name) + assert_select "td", :text => Regexp.new(@contract.name) do + assert_select "span.count", "()" + end end end From 3384dd3dbdd320a7e3ac917f9a92fac37b7f2664 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Tue, 22 Feb 2011 10:35:32 -0800 Subject: [PATCH 5/6] Refactor: merge assertions in tests --- test/integration/issue_filtering_test.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/integration/issue_filtering_test.rb b/test/integration/issue_filtering_test.rb index 71a0544..395b8c3 100644 --- a/test/integration/issue_filtering_test.rb +++ b/test/integration/issue_filtering_test.rb @@ -36,9 +36,6 @@ class IssueFilteringTest < ActionController::IntegrationTest assert_select "td", :text => /None/ do assert_select "span.count", "(1)" end - end - - assert_select "tr.group" do assert_select "td", :text => Regexp.new(@deliverable.title) do assert_select "span.count", "(1)" end @@ -64,9 +61,6 @@ class IssueFilteringTest < ActionController::IntegrationTest assert_select "td", :text => /None/ do assert_select "span.count", "(1)" end - end - - assert_select "tr.group" do assert_select "td", :text => Regexp.new(@contract.name) do assert_select "span.count", "()" end From 496c6bada7455507b48126c1de0d88dccb8c7bc9 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Tue, 22 Feb 2011 10:58:19 -0800 Subject: [PATCH 6/6] [#5482] Fix counts when grouping by contracts in the issues list --- init.rb | 6 +++++- lib/redmine_contracts/patches/issue_patch.rb | 6 +++++- test/integration/issue_filtering_test.rb | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/init.rb b/init.rb index 0530c55..19e673c 100644 --- a/init.rb +++ b/init.rb @@ -92,8 +92,12 @@ Dispatcher.to_prepare :redmine_contracts do Query.add_available_column(QueryColumn.new(:deliverable, :sortable => "#{Deliverable.table_name}.title", :groupable => 'deliverable')) end + # Hack in order to get the associated contract to be grouped by name + # * Proxy method Issue#contract_name + # * Naming Query column contract_name + # * Grouping by 'contracts.name' unless Query.available_columns.collect(&:name).include?(:contract_name) - Query.add_available_column(QueryColumn.new(:contract_name, :sortable => "#{Contract.table_name}.name", :groupable => 'contract_id')) + Query.add_available_column(QueryColumn.new(:contract_name, :sortable => "#{Contract.table_name}.name", :groupable => 'contracts.name')) end end diff --git a/lib/redmine_contracts/patches/issue_patch.rb b/lib/redmine_contracts/patches/issue_patch.rb index c2d0597..4df6003 100644 --- a/lib/redmine_contracts/patches/issue_patch.rb +++ b/lib/redmine_contracts/patches/issue_patch.rb @@ -10,7 +10,11 @@ module RedmineContracts belongs_to :deliverable delegate :title, :to => :deliverable, :prefix => true, :allow_nil => true - delegate :contract_name, :to => :deliverable, :allow_nil => true + delegate :contract, :to => :deliverable, :allow_nil => true + + def contract_name + contract.try(:name) + end end end diff --git a/test/integration/issue_filtering_test.rb b/test/integration/issue_filtering_test.rb index 395b8c3..7ec6513 100644 --- a/test/integration/issue_filtering_test.rb +++ b/test/integration/issue_filtering_test.rb @@ -62,7 +62,7 @@ class IssueFilteringTest < ActionController::IntegrationTest assert_select "span.count", "(1)" end assert_select "td", :text => Regexp.new(@contract.name) do - assert_select "span.count", "()" + assert_select "span.count", "(1)" end end