Class: Ossert::QuartersStore

Inherits:
Object
  • Object
show all
Defined in:
lib/ossert/quarters_store.rb

Overview

Public: Class for data divided by quarters. Each quarter instantiates some statistics class. Contains methods for quarters calculations, such as grouping, preview and other.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data_klass_name) ⇒ QuartersStore

Public: Instantiate QuarterStore

data_klass - the Object for quarter data storage, to be compatable it

should implement:
  - class method #metrics returns Array of metric names;
  - instance method #metric_values returns values of metrics
    in same order.

Returns nothing.



17
18
19
20
21
22
# File 'lib/ossert/quarters_store.rb', line 17

def initialize(data_klass_name)
  @data_klass_name = data_klass_name
  @quarters = {}
  @start_date = Time.now
  @end_date = Time.now
end

Instance Attribute Details

#data_klassObject (readonly)

Returns the value of attribute data_klass.



6
7
8
# File 'lib/ossert/quarters_store.rb', line 6

def data_klass
  @data_klass
end

#end_dateObject (readonly)

Returns the value of attribute end_date.



6
7
8
# File 'lib/ossert/quarters_store.rb', line 6

def end_date
  @end_date
end

#quartersObject (readonly)

Returns the value of attribute quarters.



6
7
8
# File 'lib/ossert/quarters_store.rb', line 6

def quarters
  @quarters
end

#start_dateObject (readonly)

Returns the value of attribute start_date.



6
7
8
# File 'lib/ossert/quarters_store.rb', line 6

def start_date
  @start_date
end

Instance Method Details

#aggregated_quarter(offset = 1) ⇒ Object

Public: Generate aggregated quarter object for last year.

offset - the Numeric (default: 1) in quarters for offset of when “last year” should ends

Returns quarter Object with attributes aggregated for last year.



91
92
93
94
95
96
# File 'lib/ossert/quarters_store.rb', line 91

def aggregated_quarter(offset = 1)
  last_quarters = quarters.sort.last(4 + offset).take(4)
  last_quarters.inject(data_klass.new) do |acc, (_, quarter)|
    acc << quarter
  end
end

#date_to_start(date) ⇒ Object

Public: Find closest begining of quarter for given date.

date - the String, Numeric or DateTime to seek begining of quarter for.

Returns begining of quarter DateTime.



52
53
54
55
56
57
58
59
# File 'lib/ossert/quarters_store.rb', line 52

def date_to_start(date)
  if date.is_a? String
    # Alternative, but more expensive: DateTime.parse(value).beginning_of_quarter.to_i
    DateTime.new(*date.split('-').map(&:to_i)).beginning_of_quarter.to_i
  else
    Time.at(date).to_date.to_time(:utc).beginning_of_quarter.to_i
  end
end

#each_sortedObject

Public: Iterate (and yields) through quarters in ascending order

Yields the Numeric UNIX-timestamp beginning of quarter

the Object for quarter data

Returns Array of sorted pairs of time and quarter object.



140
141
142
# File 'lib/ossert/quarters_store.rb', line 140

def each_sorted
  quarters.sort.map { |time, quarter| yield(time, quarter) }
end

#fetch(date) ⇒ Object

Public: Strict fetch of quarter for given date

date - the String, Numeric or DateTime to seek begining of quarter for.

Returns quarter Object or KeyError will be raised.



33
34
35
# File 'lib/ossert/quarters_store.rb', line 33

def fetch(date)
  quarters.fetch date_to_start(date)
end

#find_or_create(date) ⇒ Object Also known as: []

Public: Find or create quarter for given date.

date - the String, Numeric or DateTime to seek begining of quarter for.

Returns quarter Object.



42
43
44
# File 'lib/ossert/quarters_store.rb', line 42

def find_or_create(date)
  quarters[date_to_start(date)] ||= data_klass.new
end

#fullfill!Object

Public: Fill quarter bounds and wholes in periods from first to last quarter. It will assign @start_date and @end_date of QuarterStore instance. Should be called after all data is gathered and we ready for data presentation.

Returns nothing.



103
104
105
106
107
108
109
110
111
112
# File 'lib/ossert/quarters_store.rb', line 103

def fullfill!
  return if quarters.empty?

  periods_range = with_quarters_dates do |period|
    find_or_create Time.at(period)
  end

  @start_date = Time.at(periods_range.first)
  @end_date = Time.at(periods_range.last)
end

#last_year_as_hash(offset = 1) ⇒ Object

Public: Get quarters metric values aggregated for last year.

offset - the Numeric (default: 1) in quarters for offset of when “last year” should ends

Returns Hash of quarter metrics and its values aggregated for last year.



82
83
84
# File 'lib/ossert/quarters_store.rb', line 82

def last_year_as_hash(offset = 1)
  data_klass.metrics.zip(aggregated_quarter(offset).metric_values).to_h
end

#last_year_data(offset = 1) ⇒ Object

Public: Get quarters metric values aggregated for last year.

offset - the Numeric (default: 1) in quarters for offset of when “last year” should ends

Returns Array of quarter metric values aggregated for last year.



73
74
75
# File 'lib/ossert/quarters_store.rb', line 73

def last_year_data(offset = 1)
  last_year_as_hash(offset).values
end

#previewObject

Public: Prepare quarters to preview.

Returns sorted Hash of quarter date and its data.



64
65
66
# File 'lib/ossert/quarters_store.rb', line 64

def preview
  quarters.sort.map { |unix_timestamp, quarter| [Time.at(unix_timestamp), quarter] }.to_h
end

#reverse_each_sortedObject

Public: Iterate (and yields) through quarters in descending order

Yields the Numeric UNIX-timestamp beginning of quarter

the Object for quarter data

Returns Array of sorted pairs of time and quarter object.



130
131
132
# File 'lib/ossert/quarters_store.rb', line 130

def reverse_each_sorted
  quarters.sort.reverse.map { |time, quarter| yield(time, quarter) }
end

#to_hashObject

Public: Generate Hash for current data structure.

Keys are UNIX-timestamps (beginning of each quarter),
values are quarter objects explicitly converted to Hash.

Returns Hash.



149
150
151
152
153
# File 'lib/ossert/quarters_store.rb', line 149

def to_hash
  quarters.each_with_object({}) do |(time, quarter), result|
    result[time] = quarter.to_hash
  end
end

#to_jsonObject

Public: Generate JSON for current data structure.

Keys are UNIX-timestamps (beginning of each quarter),
values are quarter objects explicitly converted to Hash.

Returns String contains valid JSON.



160
161
162
# File 'lib/ossert/quarters_store.rb', line 160

def to_json
  MultiJson.dump(self)
end

#with_quarters_datesObject

Public: Iterate (and yields) through quarter dates in ascending order

Yields the Numeric UNIX-timestamp inside of quarter

Returns Range of quarters dates



119
120
121
122
# File 'lib/ossert/quarters_store.rb', line 119

def with_quarters_dates
  sorted_quarters = quarters.keys.sort
  (sorted_quarters.first..sorted_quarters.last).step(93.days) { |period| yield(period) }
end