From 635ff493616bd211bd0000cc7d17e356e47abfcc Mon Sep 17 00:00:00 2001 From: kumojima Date: Fri, 17 Apr 2026 22:31:56 +0900 Subject: hours filter on issue_query --- app/models/issue_query.rb | 10 +++++++--- test/unit/query_test.rb | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index c59e8d35c..7ac5f4a22 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -225,10 +225,10 @@ class IssueQuery < Query add_available_filter "closed_on", :type => :date_past add_available_filter "start_date", :type => :date add_available_filter "due_date", :type => :date - add_available_filter "estimated_hours", :type => :float + add_available_filter "estimated_hours", :type => :hour if User.current.allowed_to?(:view_time_entries, project, :global => true) - add_available_filter "spent_time", :type => :float, :label => :label_spent_time + add_available_filter "spent_time", :type => :hour, :label => :label_spent_time end add_available_filter "done_ratio", :type => :integer @@ -531,8 +531,12 @@ class IssueQuery < Query "#{neg} EXISTS (#{subquery})" end + def sql_for_estimated_hours_field(field, operator, value) + sql_for_field("estimated_hours", operator, value.map(&:to_hours), Issue.table_name, "estimated_hours") + end + def sql_for_spent_time_field(field, operator, value) - first, second = value.first.to_f, value.second.to_f + first, second = value.first.to_s.to_hours, value.second.to_s.to_hours sql_op = case operator when "=", ">=", "<=" then "#{operator} #{first}" diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index 6318596f1..398341d7d 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -272,6 +272,15 @@ class QueryTest < ActiveSupport::TestCase assert_equal 2, issues.first.id end + def test_operator_is_on_hour + Issue.where(:id => 2).update_all("estimated_hours = 171.2") + query = IssueQuery.new(:name => '_') + query.add_filter('estimated_hours', '=', ['171:12']) + issues = find_issues_with_query(query) + assert_equal 1, issues.size + assert_equal 2, issues.first.id + end + def test_operator_is_on_issue_id_should_accept_comma_separated_values query = IssueQuery.new(:name => '_') query.add_filter("issue_id", '=', ['1,3']) @@ -450,6 +459,13 @@ class QueryTest < ActiveSupport::TestCase find_issues_with_query(query) end + def test_operator_greater_than_a_hour + query = IssueQuery.new(:project => Project.find(1), :name => '_') + query.add_filter('estimated_hours', '>=', ['40:30']) + assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5") + find_issues_with_query(query) + end + def test_operator_greater_than_on_int_custom_field f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true, :trackers => Tracker.all) CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7') @@ -3261,11 +3277,20 @@ class QueryTest < ActiveSupport::TestCase query.filters = {'spent_time' => {:operator => '>=', :values => ['10']}} assert_equal [1], query.issues.pluck(:id) + query.filters = {'spent_time' => {:operator => '>=', :values => ['10:00']}} + assert_equal [1], query.issues.pluck(:id) + query.filters = {'spent_time' => {:operator => '<=', :values => ['10']}} assert_equal [13, 12, 11, 8, 7, 5, 3, 2], query.issues.pluck(:id) + query.filters = {'spent_time' => {:operator => '<=', :values => ['10:00']}} + assert_equal [13, 12, 11, 8, 7, 5, 3, 2], query.issues.pluck(:id) + query.filters = {'spent_time' => {:operator => '><', :values => ['1', '2']}} assert_equal [3], query.issues.pluck(:id) + + query.filters = {'spent_time' => {:operator => '><', :values => ['1:00', '2:00']}} + assert_equal [3], query.issues.pluck(:id) end def test_issues_should_be_in_the_same_order_when_paginating -- 2.43.0