Merge branch '5482-issue-grouping'
This commit is contained in:
10
init.rb
10
init.rb
@@ -88,12 +88,16 @@ Dispatcher.to_prepare :redmine_contracts do
|
|||||||
Query.send(:include, RedmineContracts::Patches::QueryPatch)
|
Query.send(:include, RedmineContracts::Patches::QueryPatch)
|
||||||
end
|
end
|
||||||
|
|
||||||
unless Query.available_columns.collect(&:name).include?(:deliverable_title)
|
unless Query.available_columns.collect(&:name).include?(:deliverable)
|
||||||
Query.add_available_column(QueryColumn.new(:deliverable_title, :sortable => "#{Deliverable.table_name}.title"))
|
Query.add_available_column(QueryColumn.new(:deliverable, :sortable => "#{Deliverable.table_name}.title", :groupable => 'deliverable'))
|
||||||
end
|
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)
|
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 => 'contracts.name'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,11 @@ module RedmineContracts
|
|||||||
belongs_to :deliverable
|
belongs_to :deliverable
|
||||||
|
|
||||||
delegate :title, :to => :deliverable, :prefix => true, :allow_nil => true
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,36 @@ module RedmineContracts
|
|||||||
alias_method_chain :available_filters, :contract
|
alias_method_chain :available_filters, :contract
|
||||||
|
|
||||||
alias_method_chain :sql_for_field, :contract
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -83,6 +113,37 @@ module RedmineContracts
|
|||||||
end
|
end
|
||||||
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
|
||||||
|
|
||||||
|
# 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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
71
test/integration/issue_filtering_test.rb
Normal file
71
test/integration/issue_filtering_test.rb
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
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"
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
assert_select "tr.group" do
|
||||||
|
assert_select "td", :text => /None/ do
|
||||||
|
assert_select "span.count", "(1)"
|
||||||
|
end
|
||||||
|
assert_select "td", :text => Regexp.new(@deliverable.title) do
|
||||||
|
assert_select "span.count", "(1)"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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/ do
|
||||||
|
assert_select "span.count", "(1)"
|
||||||
|
end
|
||||||
|
assert_select "td", :text => Regexp.new(@contract.name) do
|
||||||
|
assert_select "span.count", "(1)"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user