reports_kit 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.travis.yml +20 -0
  4. data/README.md +17 -19
  5. data/app/assets/javascripts/reports_kit/lib/_init.js +2 -1
  6. data/app/assets/javascripts/reports_kit/lib/chart.js +25 -16
  7. data/app/assets/javascripts/reports_kit/lib/report.js +42 -25
  8. data/app/assets/javascripts/reports_kit/lib/table.js +37 -2
  9. data/app/assets/stylesheets/reports_kit/reports.css.sass +3 -0
  10. data/docs/dimensions.md +26 -34
  11. data/docs/display_options.md +12 -15
  12. data/docs/filters.md +54 -63
  13. data/docs/measures.md +3 -4
  14. data/lib/reports_kit.rb +12 -10
  15. data/lib/reports_kit/base_controller.rb +1 -2
  16. data/lib/reports_kit/configuration.rb +19 -4
  17. data/lib/reports_kit/entity.rb +3 -0
  18. data/lib/reports_kit/helper.rb +17 -21
  19. data/lib/reports_kit/model_configuration.rb +1 -1
  20. data/lib/reports_kit/report_builder.rb +11 -11
  21. data/lib/reports_kit/reports/{abstract_measure.rb → abstract_series.rb} +1 -1
  22. data/lib/reports_kit/reports/{composite_measure.rb → composite_series.rb} +12 -8
  23. data/lib/reports_kit/reports/data/add_table_aggregations.rb +105 -0
  24. data/lib/reports_kit/reports/data/{composite_aggregation.rb → aggregate_composite.rb} +28 -27
  25. data/lib/reports_kit/reports/data/{one_dimension.rb → aggregate_one_dimension.rb} +9 -7
  26. data/lib/reports_kit/reports/data/{two_dimensions.rb → aggregate_two_dimensions.rb} +9 -8
  27. data/lib/reports_kit/reports/data/chart_options.rb +6 -11
  28. data/lib/reports_kit/reports/data/format_one_dimension.rb +56 -36
  29. data/lib/reports_kit/reports/data/format_table.rb +65 -0
  30. data/lib/reports_kit/reports/data/format_two_dimensions.rb +10 -8
  31. data/lib/reports_kit/reports/data/generate.rb +51 -28
  32. data/lib/reports_kit/reports/data/generate_for_properties.rb +52 -30
  33. data/lib/reports_kit/reports/data/populate_one_dimension.rb +30 -12
  34. data/lib/reports_kit/reports/data/populate_two_dimensions.rb +31 -31
  35. data/lib/reports_kit/reports/data/utils.rb +28 -24
  36. data/lib/reports_kit/reports/dimension.rb +4 -0
  37. data/lib/reports_kit/reports/{dimension_with_measure.rb → dimension_with_series.rb} +8 -9
  38. data/lib/reports_kit/reports/filter.rb +4 -0
  39. data/lib/reports_kit/reports/filter_types/base.rb +4 -3
  40. data/lib/reports_kit/reports/filter_types/boolean.rb +4 -4
  41. data/lib/reports_kit/reports/filter_types/datetime.rb +13 -3
  42. data/lib/reports_kit/reports/filter_types/number.rb +5 -5
  43. data/lib/reports_kit/reports/{filter_with_measure.rb → filter_with_series.rb} +7 -7
  44. data/lib/reports_kit/reports/generate_autocomplete_results.rb +2 -2
  45. data/lib/reports_kit/reports/inferrable_configuration.rb +6 -6
  46. data/lib/reports_kit/reports/{measure.rb → series.rb} +28 -15
  47. data/lib/reports_kit/reports_controller.rb +25 -5
  48. data/lib/reports_kit/value.rb +3 -0
  49. data/lib/reports_kit/version.rb +1 -1
  50. data/spec/fixtures/generate_inputs.yml +116 -63
  51. data/spec/fixtures/generate_outputs.yml +64 -0
  52. data/spec/reports_kit/report_builder_spec.rb +10 -12
  53. data/spec/reports_kit/reports/data/generate_spec.rb +559 -140
  54. data/spec/reports_kit/reports/{dimension_with_measure_spec.rb → dimension_with_series_spec.rb} +5 -7
  55. data/spec/reports_kit/reports/{filter_with_measure_spec.rb → filter_with_series_spec.rb} +3 -3
  56. data/spec/spec_helper.rb +5 -5
  57. data/spec/support/config.rb +31 -1
  58. data/spec/support/helpers.rb +6 -2
  59. metadata +17 -14
  60. data/lib/reports_kit/reports/data/entity.rb +0 -7
  61. data/lib/reports_kit/reports/data/value.rb +0 -7
@@ -2,33 +2,51 @@ module ReportsKit
2
2
  module Reports
3
3
  module Data
4
4
  class PopulateOneDimension
5
- attr_accessor :sparse_measures_dimension_keys_values
5
+ attr_accessor :sparse_serieses_dimension_keys_values, :context_record, :properties
6
6
 
7
- def initialize(sparse_measures_dimension_keys_values)
8
- self.sparse_measures_dimension_keys_values = sparse_measures_dimension_keys_values
7
+ def initialize(sparse_serieses_dimension_keys_values, context_record: nil, properties: nil)
8
+ self.sparse_serieses_dimension_keys_values = sparse_serieses_dimension_keys_values
9
+ self.context_record = context_record
10
+ self.properties = properties
9
11
  end
10
12
 
11
13
  def perform
12
- return sparse_measures_dimension_keys_values if sparse_measures_dimension_keys_values.length == 1
13
- measures_dimension_keys_values
14
+ return sparse_serieses_dimension_keys_values if sparse_serieses_dimension_keys_values.length == 1
15
+ serieses_dimension_keys_values
14
16
  end
15
17
 
16
18
  private
17
19
 
18
- def measures_dimension_keys_values
19
- measures_dimension_keys_values = sparse_measures_dimension_keys_values.map do |measure, dimension_keys_values|
20
+ def serieses_dimension_keys_values
21
+ serieses_dimension_keys_values = sparse_serieses_dimension_keys_values.map do |series, dimension_keys_values|
20
22
  dimension_keys.each do |key|
21
23
  dimension_keys_values[key] ||= 0
22
24
  end
23
- [measure, dimension_keys_values]
25
+ [series, dimension_keys_values]
24
26
  end
25
- Hash[measures_dimension_keys_values]
27
+ Hash[serieses_dimension_keys_values]
26
28
  end
27
29
 
28
30
  def dimension_keys
29
- sparse_measures_dimension_keys_values.map do |measure, dimension_keys_values|
30
- dimension_keys_values.keys
31
- end.reduce(&:+).uniq
31
+ dimension_keys_from_edit_dimension_keys_method || dimension_keys_from_results
32
+ end
33
+
34
+ def dimension_keys_from_edit_dimension_keys_method
35
+ return unless edit_dimension_keys_method
36
+ edit_dimension_keys_method.call(dimension_keys: dimension_keys_from_results, properties: properties, context_record: context_record)
37
+ end
38
+
39
+ def dimension_keys_from_results
40
+ @dimension_keys_from_results ||= begin
41
+ sparse_serieses_dimension_keys_values.map do |series, dimension_keys_values|
42
+ dimension_keys_values.keys
43
+ end.reduce(&:+).uniq
44
+ end
45
+ end
46
+
47
+ def edit_dimension_keys_method
48
+ return unless properties
49
+ ReportsKit.configuration.custom_method(properties[:report_options].try(:[], :edit_dimension_keys_method))
32
50
  end
33
51
  end
34
52
  end
@@ -2,25 +2,25 @@ module ReportsKit
2
2
  module Reports
3
3
  module Data
4
4
  class PopulateTwoDimensions
5
- attr_accessor :measures, :dimension, :second_dimension, :sparse_measures_dimension_keys_values
5
+ attr_accessor :serieses, :dimension, :second_dimension, :sparse_serieses_dimension_keys_values
6
6
 
7
- def initialize(sparse_measures_dimension_keys_values)
8
- self.measures = sparse_measures_dimension_keys_values.keys
9
- self.dimension = measures.first.dimensions[0]
10
- self.second_dimension = measures.first.dimensions[1]
11
- self.sparse_measures_dimension_keys_values = sparse_measures_dimension_keys_values
7
+ def initialize(sparse_serieses_dimension_keys_values)
8
+ self.serieses = sparse_serieses_dimension_keys_values.keys
9
+ self.dimension = serieses.first.dimensions[0]
10
+ self.second_dimension = serieses.first.dimensions[1]
11
+ self.sparse_serieses_dimension_keys_values = sparse_serieses_dimension_keys_values
12
12
  end
13
13
 
14
14
  def perform
15
- measures_populated_dimension_keys_values
15
+ serieses_populated_dimension_keys_values
16
16
  end
17
17
 
18
18
  private
19
19
 
20
- def measures_populated_dimension_keys_values
21
- measures_dimension_keys_values = {}
20
+ def serieses_populated_dimension_keys_values
21
+ serieses_dimension_keys_values = {}
22
22
  secondary_keys_sums = Hash.new(0)
23
- measures_populated_primary_keys_secondary_keys_values.each do |measure, primary_keys_secondary_keys_values|
23
+ serieses_populated_primary_keys_secondary_keys_values.each do |series, primary_keys_secondary_keys_values|
24
24
  primary_keys_secondary_keys_values.each do |primary_key, secondary_keys_values|
25
25
  secondary_keys_values.each do |secondary_key, value|
26
26
  secondary_keys_sums[secondary_key] += value
@@ -28,55 +28,55 @@ module ReportsKit
28
28
  end
29
29
  end
30
30
  sorted_secondary_keys = secondary_keys_sums.sort_by(&:last).reverse.map(&:first)
31
- measures_populated_primary_keys_secondary_keys_values.each do |measure, primary_key_secondary_keys_values|
32
- measures_dimension_keys_values[measure] = {}
31
+ serieses_populated_primary_keys_secondary_keys_values.each do |series, primary_key_secondary_keys_values|
32
+ serieses_dimension_keys_values[series] = {}
33
33
  primary_key_secondary_keys_values.each do |primary_key, secondary_keys_values|
34
34
  secondary_keys_values = secondary_keys_values.sort_by { |key, _| sorted_secondary_keys.index(key) }
35
35
  secondary_keys_values.each do |secondary_key, value|
36
36
  dimension_key = [primary_key, secondary_key]
37
- measures_dimension_keys_values[measure][dimension_key] = value
37
+ serieses_dimension_keys_values[series][dimension_key] = value
38
38
  secondary_keys_sums[secondary_key] += value
39
39
  end
40
40
  end
41
41
  end
42
- measures_dimension_keys_values
42
+ serieses_dimension_keys_values
43
43
  end
44
44
 
45
- def measures_populated_primary_keys_secondary_keys_values
45
+ def serieses_populated_primary_keys_secondary_keys_values
46
46
  @populated_dimension_keys_values ||= begin
47
- measures_populated_primary_keys_secondary_keys_values = {}
48
- measures.each do |measure|
49
- measures_populated_primary_keys_secondary_keys_values[measure] = {}
47
+ serieses_populated_primary_keys_secondary_keys_values = {}
48
+ serieses.each do |series|
49
+ serieses_populated_primary_keys_secondary_keys_values[series] = {}
50
50
  primary_keys.each do |primary_key|
51
- measures_populated_primary_keys_secondary_keys_values[measure][primary_key] = {}
51
+ serieses_populated_primary_keys_secondary_keys_values[series][primary_key] = {}
52
52
  secondary_keys.each do |secondary_key|
53
- value = measures_primary_keys_secondary_keys_values[measure][primary_key].try(:[], secondary_key) || 0
54
- measures_populated_primary_keys_secondary_keys_values[measure][primary_key][secondary_key] = value
53
+ value = serieses_primary_keys_secondary_keys_values[series][primary_key].try(:[], secondary_key) || 0
54
+ serieses_populated_primary_keys_secondary_keys_values[series][primary_key][secondary_key] = value
55
55
  end
56
56
  end
57
57
  end
58
- measures_populated_primary_keys_secondary_keys_values
58
+ serieses_populated_primary_keys_secondary_keys_values
59
59
  end
60
60
  end
61
61
 
62
- def measures_primary_keys_secondary_keys_values
63
- @measures_primary_keys_secondary_keys_values ||= begin
64
- measures_primary_keys_secondary_keys_values = {}
65
- sparse_measures_dimension_keys_values.each do |measure, dimension_keys_values|
66
- measures_primary_keys_secondary_keys_values[measure] = {}
62
+ def serieses_primary_keys_secondary_keys_values
63
+ @serieses_primary_keys_secondary_keys_values ||= begin
64
+ serieses_primary_keys_secondary_keys_values = {}
65
+ sparse_serieses_dimension_keys_values.each do |series, dimension_keys_values|
66
+ serieses_primary_keys_secondary_keys_values[series] = {}
67
67
  dimension_keys_values.each do |(primary_key, secondary_key), value|
68
68
  primary_key = primary_key.to_date if primary_key.is_a?(Time)
69
69
  secondary_key = secondary_key.to_date if secondary_key.is_a?(Time)
70
- measures_primary_keys_secondary_keys_values[measure][primary_key] ||= {}
71
- measures_primary_keys_secondary_keys_values[measure][primary_key][secondary_key] = value
70
+ serieses_primary_keys_secondary_keys_values[series][primary_key] ||= {}
71
+ serieses_primary_keys_secondary_keys_values[series][primary_key][secondary_key] = value
72
72
  end
73
73
  end
74
- measures_primary_keys_secondary_keys_values
74
+ serieses_primary_keys_secondary_keys_values
75
75
  end
76
76
  end
77
77
 
78
78
  def dimension_keys
79
- @dimension_keys ||= sparse_measures_dimension_keys_values.values.map(&:keys).reduce(&:+).uniq
79
+ @dimension_keys ||= sparse_serieses_dimension_keys_values.values.map(&:keys).reduce(&:+).uniq
80
80
  end
81
81
 
82
82
  def primary_keys
@@ -2,14 +2,18 @@ module ReportsKit
2
2
  module Reports
3
3
  module Data
4
4
  class Utils
5
- def self.format_display_time(time)
6
- time.strftime('%b %-d, \'%y')
7
- end
8
-
9
5
  def self.format_configuration_time(time)
10
6
  time.strftime('%b %-d, %Y')
11
7
  end
12
8
 
9
+ def self.format_csv_time(time)
10
+ time.strftime('%Y-%m-%d')
11
+ end
12
+
13
+ def self.format_display_time(time)
14
+ time.strftime('%b %-d, \'%y')
15
+ end
16
+
13
17
  def self.format_time_value(value)
14
18
  time = RelativeTime.parse(value, prevent_exceptions: true)
15
19
  return value unless time
@@ -22,17 +26,19 @@ module ReportsKit
22
26
  number.round(Generate::ROUND_PRECISION)
23
27
  end
24
28
 
29
+ def self.quote_column_name(string)
30
+ ActiveRecord::Base.connection.quote_column_name(string)
31
+ end
32
+
25
33
  def self.parse_date_string(string)
26
- begin
27
- Date.parse(string)
28
- rescue ArgumentError
29
- RelativeTime.parse(string)
30
- end
34
+ Date.parse(string)
35
+ rescue ArgumentError
36
+ RelativeTime.parse(string)
31
37
  end
32
38
 
33
39
  def self.populate_sparse_hash(hash, dimension:)
34
40
  keys = hash.keys
35
- is_nested = dimension.measure.has_two_dimensions?
41
+ is_nested = dimension.series.has_two_dimensions?
36
42
  if is_nested
37
43
  keys_values = arrays_values_to_nested_hash(hash)
38
44
  keys = keys_values.keys
@@ -67,11 +73,7 @@ module ReportsKit
67
73
  keys = keys.sort
68
74
  last_key = (dimension.last_key || keys.last).to_date
69
75
  last_key = last_key.beginning_of_week(ReportsKit.configuration.first_day_of_week) if granularity == 'week'
70
-
71
- if granularity == 'week'
72
- beginning_of_current_week = Date.today.beginning_of_week(ReportsKit.configuration.first_day_of_week)
73
- last_key = [beginning_of_current_week, last_key].compact.max
74
- end
76
+ last_key ||= Date.today.beginning_of_week(ReportsKit.configuration.first_day_of_week) if granularity == 'week'
75
77
 
76
78
  date = first_key
77
79
  populated_keys = []
@@ -145,8 +147,8 @@ module ReportsKit
145
147
  Value.new(raw_value, formatted_value)
146
148
  end
147
149
 
148
- def self.normalize_filters(measure_properties, ui_filters)
149
- measure_properties[:filters] = measure_properties[:filters].map do |filter_properties|
150
+ def self.normalize_filters(series_properties, ui_filters)
151
+ series_properties[:filters] = series_properties[:filters].map do |filter_properties|
150
152
  filter_properties = { key: filter_properties } if filter_properties.is_a?(String)
151
153
  key = filter_properties[:key]
152
154
  ui_key = filter_properties[:ui_key]
@@ -158,18 +160,20 @@ module ReportsKit
158
160
  end
159
161
  filter_properties
160
162
  end
161
- measure_properties
163
+ series_properties
162
164
  end
163
165
 
164
166
  def self.normalize_properties(properties, ui_filters: nil)
167
+ can_have_nesting = properties[:composite_operator].present? || properties[:series].is_a?(Array)
165
168
  ui_filters ||= properties[:ui_filters]
166
169
  properties = properties.dup
167
- properties[:measures] = [properties.delete(:measure)] if properties[:measure]
168
- return properties if ui_filters.blank? || properties[:measures].blank?
169
- properties[:measures] = properties[:measures].map do |measure_properties|
170
- measure_properties = normalize_properties(measure_properties, ui_filters: ui_filters)
171
- next(measure_properties) if measure_properties[:filters].blank?
172
- normalize_filters(measure_properties, ui_filters)
170
+ properties[:series] ||= properties.slice(*Series::VALID_KEYS).presence
171
+ properties[:series] = [properties[:series]] if properties[:series].is_a?(Hash) && properties[:series].present?
172
+ return properties if ui_filters.blank? || properties[:series].blank?
173
+ properties[:series] = properties[:series].map do |series_properties|
174
+ series_properties = normalize_properties(series_properties, ui_filters: ui_filters) if can_have_nesting
175
+ next(series_properties) if series_properties[:filters].blank?
176
+ normalize_filters(series_properties, ui_filters)
173
177
  end
174
178
  properties
175
179
  end
@@ -15,6 +15,10 @@ module ReportsKit
15
15
  properties[:key]
16
16
  end
17
17
 
18
+ def expression
19
+ properties[:expression] || key
20
+ end
21
+
18
22
  def label
19
23
  properties.key?(:label) ? properties[:label] : key.titleize
20
24
  end
@@ -1,7 +1,6 @@
1
1
  module ReportsKit
2
2
  module Reports
3
- class DimensionWithMeasure
4
- DEFAULT_DIMENSION_INSTANCES_LIMIT = 30
3
+ class DimensionWithSeries
5
4
  DEFAULT_GRANULARITY = 'week'
6
5
  VALID_GRANULARITIES = %w(day week).freeze
7
6
  ADAPTER_NAMES_CLASSES = {
@@ -9,16 +8,16 @@ module ReportsKit
9
8
  'postgresql' => Adapters::Postgresql
10
9
  }.freeze
11
10
 
12
- attr_accessor :dimension, :measure, :configuration
11
+ attr_accessor :dimension, :series, :configuration
13
12
 
14
- delegate :key, :properties, :label, to: :dimension
13
+ delegate :key, :expression, :properties, :label, to: :dimension
15
14
  delegate :configured_by_association?, :configured_by_column?, :configured_by_model?, :configured_by_time?,
16
15
  :settings_from_model, :reflection, :instance_class, :model_class, :column_type,
17
16
  to: :configuration
18
17
 
19
- def initialize(dimension:, measure:)
18
+ def initialize(dimension:, series:)
20
19
  self.dimension = dimension
21
- self.measure = measure
20
+ self.series = series
22
21
  self.configuration = InferrableConfiguration.new(self, :dimensions)
23
22
  missing_group_setting = settings && !settings.key?(:group)
24
23
  raise ArgumentError.new("Dimension settings for dimension '#{key}' of #{model_class} must include :group") if missing_group_setting
@@ -84,7 +83,7 @@ module ReportsKit
84
83
  if configured_by_time?
85
84
  properties[:limit]
86
85
  else
87
- properties[:limit] || DEFAULT_DIMENSION_INSTANCES_LIMIT
86
+ properties[:limit] || ReportsKit.configuration.default_dimension_limit
88
87
  end
89
88
  end
90
89
 
@@ -104,8 +103,8 @@ module ReportsKit
104
103
  end
105
104
 
106
105
  def datetime_filters
107
- return [] unless measure.filters.present?
108
- measure.filters.map(&:filter_type).select { |filter_type| filter_type.is_a?(FilterTypes::Datetime) }
106
+ return [] unless series.filters.present?
107
+ series.filters.map(&:filter_type).select { |filter_type| filter_type.is_a?(FilterTypes::Datetime) }
109
108
  end
110
109
 
111
110
  def should_be_sorted_by_count?
@@ -13,6 +13,10 @@ module ReportsKit
13
13
  properties[:key]
14
14
  end
15
15
 
16
+ def expression
17
+ properties[:expression] || key
18
+ end
19
+
16
20
  def label
17
21
  key.titleize
18
22
  end
@@ -2,11 +2,12 @@ module ReportsKit
2
2
  module Reports
3
3
  module FilterTypes
4
4
  class Base
5
- attr_accessor :settings, :properties
5
+ attr_accessor :settings, :properties, :primary_dimension
6
6
 
7
- def initialize(settings, properties)
7
+ def initialize(settings, properties, primary_dimension:)
8
8
  self.settings = settings || {}
9
9
  self.properties = properties
10
+ self.primary_dimension = primary_dimension
10
11
  end
11
12
 
12
13
  def apply_filter(records)
@@ -39,7 +40,7 @@ module ReportsKit
39
40
  end
40
41
 
41
42
  def column
42
- settings[:column] || properties[:key]
43
+ settings[:column] || Data::Utils.quote_column_name(properties[:key])
43
44
  end
44
45
  end
45
46
  end
@@ -20,13 +20,13 @@ module ReportsKit
20
20
  end
21
21
 
22
22
  def boolean_value
23
- case criteria[:value]
23
+ case value
24
24
  when true, 'true'
25
25
  true
26
26
  when false, 'false'
27
27
  false
28
28
  else
29
- raise ArgumentError.new("Unsupported value: '#{criteria[:value]}'")
29
+ raise ArgumentError.new("Unsupported value: '#{value}'")
30
30
  end
31
31
  end
32
32
 
@@ -35,11 +35,11 @@ module ReportsKit
35
35
  end
36
36
 
37
37
  def valid?
38
- criteria[:value].present?
38
+ value.present?
39
39
  end
40
40
 
41
41
  def conditions
42
- settings[:conditions] || properties[:key]
42
+ settings[:conditions] || Data::Utils.quote_column_name(properties[:key])
43
43
  end
44
44
  end
45
45
  end
@@ -10,7 +10,7 @@ module ReportsKit
10
10
  def apply_conditions(records)
11
11
  case criteria[:operator]
12
12
  when 'between'
13
- records.where("#{column} IS NOT NULL").where("#{column} BETWEEN ? AND ?", start_at, end_at)
13
+ records.where.not(column => nil).where(column => start_at..end_at)
14
14
  else
15
15
  raise ArgumentError.new("Unsupported operator: '#{criteria[:operator]}'")
16
16
  end
@@ -21,8 +21,8 @@ module ReportsKit
21
21
  return unless valid?
22
22
  start_string, end_string = value.split(SEPARATOR)
23
23
  start_at = ReportsKit::Reports::Data::Utils.parse_date_string(start_string)
24
- end_at = ReportsKit::Reports::Data::Utils.parse_date_string(end_string).end_of_day
25
- [start_at, end_at]
24
+ end_at = ReportsKit::Reports::Data::Utils.parse_date_string(end_string)
25
+ adjust_range_to_dimension(start_at, end_at)
26
26
  end
27
27
  end
28
28
 
@@ -34,6 +34,16 @@ module ReportsKit
34
34
  start_at_end_at.try(:[], 1)
35
35
  end
36
36
 
37
+ def adjust_range_to_dimension(start_at, end_at)
38
+ return [start_at.beginning_of_day, end_at.end_of_day] unless primary_dimension.configured_by_time?
39
+ return [start_at.beginning_of_day, end_at.end_of_day] if primary_dimension.granularity == 'day'
40
+ return [
41
+ start_at.beginning_of_week(ReportsKit.configuration.first_day_of_week),
42
+ end_at.end_of_week(ReportsKit.configuration.first_day_of_week)
43
+ ] if primary_dimension.granularity == 'week'
44
+ [start_at, end_at]
45
+ end
46
+
37
47
  def valid?
38
48
  value.present?
39
49
  end
@@ -7,15 +7,15 @@ module ReportsKit
7
7
  def apply_conditions(records)
8
8
  case criteria[:operator]
9
9
  when '>'
10
- records.where("#{column} > #{value.to_i}")
10
+ records.where(column => (value.to_i...Float::INFINITY))
11
11
  when '>='
12
- records.where("#{column} >= #{value.to_i}")
12
+ records.where(column => (value.to_i..Float::INFINITY))
13
13
  when '<'
14
- records.where("#{column} < #{value.to_i}")
14
+ records.where(column => (-Float::INFINITY...value.to_i))
15
15
  when '<='
16
- records.where("#{column} <= #{value.to_i}")
16
+ records.where(column => (-Float::INFINITY..value.to_i))
17
17
  when '='
18
- records.where("#{column} = #{value.to_i}")
18
+ records.where(column => value.to_i)
19
19
  else
20
20
  raise ArgumentError.new("Unsupported operator: '#{criteria[:operator]}'")
21
21
  end