diff --git a/app/assets/javascripts/application-legacy.js b/app/assets/javascripts/application-legacy.js index 66daa3767..211dd3e0a 100644 --- a/app/assets/javascripts/application-legacy.js +++ b/app/assets/javascripts/application-legacy.js @@ -296,6 +296,7 @@ function buildFilterRow(field, operator, values) { break; case "integer": case "float": + case "hour": case "tree": tr.find('.values').append( '' + diff --git a/app/models/query.rb b/app/models/query.rb index e95933b08..487d775a7 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -343,6 +343,7 @@ class Query < ApplicationRecord :search => [ "~", "*~", "!~" ], :integer => [ "=", ">=", "<=", "><", "!*", "*" ], :float => [ "=", ">=", "<=", "><", "!*", "*" ], + :hour => [ "=", ">=", "<=", "><", "!*", "*" ], :relation => ["=", "!", "=p", "=!p", "!p", "*o", "!o", "!*", "*"], :tree => ["=", "~", "!*", "*"] } @@ -504,6 +505,10 @@ class Query < ApplicationRecord if values_for(field).detect {|v| v.present? && !/\A[+-]?\d+(\.\d*)?\z/.match?(v)} add_filter_error(field, :invalid) end + when :hour + if values_for(field).detect {|v| v.present? && v.to_s.to_hours.nil? } + add_filter_error(field, :invalid) + end when :date, :date_past case operator_for(field) when "=", ">=", "<=", "><" @@ -1254,7 +1259,7 @@ class Query < ApplicationRecord else sql = "1=0" end - when :float + when :float, :hour if is_custom_filter sql = "(#{db_table}.#{db_field} <> '' AND " \ diff --git a/app/models/time_entry_query.rb b/app/models/time_entry_query.rb index 82b895671..e1fe8f03b 100644 --- a/app/models/time_entry_query.rb +++ b/app/models/time_entry_query.rb @@ -120,7 +120,7 @@ class TimeEntryQuery < Query ) if project.nil? || !project.leaf? add_available_filter "comments", :type => :text - add_available_filter "hours", :type => :float + add_available_filter "hours", :type => :hour add_custom_fields_filters(time_entry_custom_fields) add_associations_custom_fields_filters :project @@ -253,6 +253,10 @@ class TimeEntryQuery < Query end end + def sql_for_hours_field(field, operator, value) + sql_for_field("hours", operator, value.map(&:to_hours), TimeEntry.table_name, "hours") + end + def sql_for_activity_id_field(field, operator, value) ids = value.map(&:to_i).join(',') table_name = Enumeration.table_name diff --git a/test/unit/time_entry_query_test.rb b/test/unit/time_entry_query_test.rb index 16d4af075..c30613daa 100644 --- a/test/unit/time_entry_query_test.rb +++ b/test/unit/time_entry_query_test.rb @@ -189,6 +189,34 @@ class TimeEntryQueryTest < ActiveSupport::TestCase assert_equal 7.0, query.results_scope.sum(:hours) end + def test_hours_filter_with_float_string + project = Project.find(1) + + TimeEntry.delete_all + t1 = TimeEntry.generate!(:project => project, :hours => 0.25, :user_id => 2) + t2 = TimeEntry.generate!(:project => project, :hours => 0.50, :user_id => 2) + t3 = TimeEntry.generate!(:project => project, :hours => 0.75, :user_id => 2) + t4 = TimeEntry.generate!(:project => project, :hours => 1.00, :user_id => 2) + + query = TimeEntryQuery.new(:project => project, :name => '_') + query.add_filter('hours', '>=', ['0.75']) + assert_equal [t3.id, t4.id].sort, query.results_scope.pluck(:id).sort + end + + def test_hours_filter_with_hhmm_string + project = Project.find(1) + + TimeEntry.delete_all + t1 = TimeEntry.generate!(:project => project, :hours => 0.25, :user_id => 2) + t2 = TimeEntry.generate!(:project => project, :hours => 0.50, :user_id => 2) + t3 = TimeEntry.generate!(:project => project, :hours => 0.75, :user_id => 2) + t4 = TimeEntry.generate!(:project => project, :hours => 1.00, :user_id => 2) + + query = TimeEntryQuery.new(:project => project, :name => '_') + query.add_filter('hours', '>=', ['0:45']) + assert_equal [t3.id, t4.id].sort, query.results_scope.pluck(:id).sort + end + def test_results_scope_should_be_in_the_same_order_when_paginating 4.times {TimeEntry.generate!} q = TimeEntryQuery.new