reports_kit 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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