diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 6bb2bc217..54da8047e 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -134,6 +134,11 @@ class IssueQuery < Query add_available_filter "start_date", :type => :date add_available_filter "due_date", :type => :date add_available_filter "estimated_hours", :type => :float + + if User.current.allowed_to?(:view_time_entries, project, :global => true) + add_available_filter "spent_time", :type => :float, :label => :label_spent_time + end + add_available_filter "done_ratio", :type => :integer if User.current.allowed_to?(:set_issues_private, nil, :global => true) || @@ -380,6 +385,24 @@ class IssueQuery < Query "#{neg} EXISTS (#{subquery})" end + def sql_for_spent_time_field(field, operator, value) + first, second = value.first.to_f, value.second.to_f + + sql_op = + case operator + when "=", ">=", "<=" ; "#{operator} #{first}" + when "><" ; "BETWEEN #{first} AND #{second}" + when "*" ; "> 0" + when "!*" ; "= 0" + else ; return nil + end + + "COALESCE((" + + "SELECT ROUND(CAST(SUM(hours) AS DECIMAL(30,3)), 2) " + + "FROM #{TimeEntry.table_name} " + + "WHERE issue_id = #{Issue.table_name}.id), 0) #{sql_op}" + end + def sql_for_watcher_id_field(field, operator, value) db_table = Watcher.table_name "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " + diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index 4dfc25712..00af4c511 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -2144,4 +2144,23 @@ class QueryTest < ActiveSupport::TestCase assert_equal ['1','2','3','4','5','6'], query.available_filters['status_id'][:values].map(&:second) end + + def test_issue_query_filter_by_spent_time + query = IssueQuery.new(:name => '_') + + query.filters = {'spent_time' => {:operator => '*', :values => ['']}} + assert_equal query.issues.pluck(:id), [3, 1] + + query.filters = {'spent_time' => {:operator => '!*', :values => ['']}} + assert_equal query.issues.pluck(:id), [13, 12, 11, 8, 7, 5, 2] + + query.filters = {'spent_time' => {:operator => '>=', :values => ['10']}} + assert_equal query.issues.pluck(:id), [1] + + query.filters = {'spent_time' => {:operator => '<=', :values => ['10']}} + assert_equal query.issues.pluck(:id), [13, 12, 11, 8, 7, 5, 3, 2] + + query.filters = {'spent_time' => {:operator => '><', :values => ['1', '2']}} + assert_equal query.issues.pluck(:id), [3] + end end