Project

General

Profile

Feature #43948 ยป hours_filter_time_span_format.patch

Kenta Kumojima, 2026-04-10 16:28

View differences:

app/assets/javascripts/application-legacy.js
296 296
    break;
297 297
  case "integer":
298 298
  case "float":
299
  case "hour":
299 300
  case "tree":
300 301
    tr.find('.values').append(
301 302
      '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="14" class="value" /></span>' +
app/models/query.rb
343 343
    :search => [ "~", "*~", "!~" ],
344 344
    :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
345 345
    :float => [ "=", ">=", "<=", "><", "!*", "*" ],
346
    :hour => [ "=", ">=", "<=", "><", "!*", "*" ],
346 347
    :relation => ["=", "!", "=p", "=!p", "!p", "*o", "!o", "!*", "*"],
347 348
    :tree => ["=", "~", "!*", "*"]
348 349
  }
......
504 505
          if values_for(field).detect {|v| v.present? && !/\A[+-]?\d+(\.\d*)?\z/.match?(v)}
505 506
            add_filter_error(field, :invalid)
506 507
          end
508
        when :hour
509
          if values_for(field).detect {|v| v.present? && v.to_s.to_hours.nil? }
510
            add_filter_error(field, :invalid)
511
          end
507 512
        when :date, :date_past
508 513
          case operator_for(field)
509 514
          when "=", ">=", "<=", "><"
......
1254 1259
          else
1255 1260
            sql = "1=0"
1256 1261
          end
1257
        when :float
1262
        when :float, :hour
1258 1263
          if is_custom_filter
1259 1264
            sql =
1260 1265
              "(#{db_table}.#{db_field} <> '' AND " \
app/models/time_entry_query.rb
120 120
    ) if project.nil? || !project.leaf?
121 121

  
122 122
    add_available_filter "comments", :type => :text
123
    add_available_filter "hours", :type => :float
123
    add_available_filter "hours", :type => :hour
124 124

  
125 125
    add_custom_fields_filters(time_entry_custom_fields)
126 126
    add_associations_custom_fields_filters :project
......
253 253
    end
254 254
  end
255 255

  
256
  def sql_for_hours_field(field, operator, value)
257
    sql_for_field("hours", operator, value.map(&:to_hours), TimeEntry.table_name, "hours")
258
  end
259

  
256 260
  def sql_for_activity_id_field(field, operator, value)
257 261
    ids = value.map(&:to_i).join(',')
258 262
    table_name = Enumeration.table_name
test/unit/time_entry_query_test.rb
189 189
    assert_equal 7.0, query.results_scope.sum(:hours)
190 190
  end
191 191

  
192
  def test_hours_filter_with_float_string
193
    project = Project.find(1)
194

  
195
    TimeEntry.delete_all
196
    t1 = TimeEntry.generate!(:project => project, :hours => 0.25, :user_id => 2)
197
    t2 = TimeEntry.generate!(:project => project, :hours => 0.50, :user_id => 2)
198
    t3 = TimeEntry.generate!(:project => project, :hours => 0.75, :user_id => 2)
199
    t4 = TimeEntry.generate!(:project => project, :hours => 1.00, :user_id => 2)
200

  
201
    query = TimeEntryQuery.new(:project => project, :name => '_')
202
    query.add_filter('hours', '>=', ['0.75'])
203
    assert_equal [t3.id, t4.id].sort, query.results_scope.pluck(:id).sort
204
  end
205

  
206
  def test_hours_filter_with_hhmm_string
207
    project = Project.find(1)
208

  
209
    TimeEntry.delete_all
210
    t1 = TimeEntry.generate!(:project => project, :hours => 0.25, :user_id => 2)
211
    t2 = TimeEntry.generate!(:project => project, :hours => 0.50, :user_id => 2)
212
    t3 = TimeEntry.generate!(:project => project, :hours => 0.75, :user_id => 2)
213
    t4 = TimeEntry.generate!(:project => project, :hours => 1.00, :user_id => 2)
214

  
215
    query = TimeEntryQuery.new(:project => project, :name => '_')
216
    query.add_filter('hours', '>=', ['0:45'])
217
    assert_equal [t3.id, t4.id].sort, query.results_scope.pluck(:id).sort
218
  end
219

  
192 220
  def test_results_scope_should_be_in_the_same_order_when_paginating
193 221
    4.times {TimeEntry.generate!}
194 222
    q = TimeEntryQuery.new
    (1-1/1)