best_boy 1.3.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/README.md +36 -3
  2. data/Rakefile +45 -7
  3. data/app/controllers/best_boy/best_boy_events_controller.rb +147 -98
  4. data/app/helpers/best_boy/best_boy_view_helper.rb +9 -0
  5. data/app/views/best_boy/best_boy_events/details.html.erb +33 -27
  6. data/app/views/best_boy/best_boy_events/monthly_details.html.erb +9 -9
  7. data/app/views/best_boy/best_boy_events/stats.html.erb +20 -19
  8. data/lib/best_boy/engine.rb +2 -0
  9. data/lib/best_boy/models/active_record/best_boy/eventable.rb +19 -0
  10. data/lib/best_boy/models/active_record/best_boy_day_report.rb +65 -0
  11. data/lib/best_boy/models/active_record/best_boy_event.rb +1 -11
  12. data/lib/best_boy/models/active_record/best_boy_month_report.rb +63 -0
  13. data/lib/best_boy/version.rb +1 -1
  14. data/lib/generators/active_record/best_boy_generator.rb +4 -1
  15. data/lib/generators/active_record/templates/create_best_boy_reports.rb +30 -0
  16. data/lib/tasks/recover_report_history.rake +146 -0
  17. data/spec/{best_boy → controllers}/best_boy_controller_spec.rb +6 -4
  18. data/spec/dummy/app/views/test_events/index.html.haml +9 -1
  19. data/spec/dummy/config/routes.rb +1 -0
  20. data/spec/dummy/db/migrate/20131108085915_create_best_boy_reports.rb +30 -0
  21. data/spec/dummy/db/schema.rb +27 -1
  22. data/spec/dummy/db/test.sqlite3 +0 -0
  23. data/spec/dummy/log/development.log +10092 -0
  24. data/spec/dummy/log/test.log +531 -0
  25. data/spec/dummy/tmp/cache/assets/development/sass/f99cb4f6f36f128b2d6950c813eec72c66616bfc/bootstrap.scssc +0 -0
  26. data/spec/dummy/tmp/cache/assets/development/sprockets/01af51e20498d87feb18694bed0d0731 +0 -0
  27. data/spec/dummy/tmp/cache/assets/development/sprockets/057daf732c672b9e0ec8bd233ec79077 +0 -0
  28. data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  29. data/spec/dummy/tmp/cache/assets/development/sprockets/1565c81151c1e0fe577f787a645bca3d +0 -0
  30. data/spec/dummy/tmp/cache/assets/development/sprockets/1c90620581903652712500bb92915909 +0 -0
  31. data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  32. data/spec/dummy/tmp/cache/assets/development/sprockets/3241270f308313221453f51980c07883 +0 -0
  33. data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  34. data/spec/dummy/tmp/cache/assets/development/sprockets/3a59d6acf2f4543a36d946d653b08dab +0 -0
  35. data/spec/dummy/tmp/cache/assets/development/sprockets/3a5f8aba9c98833836df55cdc5502ee8 +0 -0
  36. data/spec/dummy/tmp/cache/assets/development/sprockets/42804a4f90448633879c06a33e49f4e6 +0 -0
  37. data/spec/dummy/tmp/cache/assets/development/sprockets/48279ff6b6f65f85e766c3a7ae0c71f6 +0 -0
  38. data/spec/dummy/tmp/cache/assets/development/sprockets/642b8ba757f92502a3a3281a956eec2a +0 -0
  39. data/spec/dummy/tmp/cache/assets/development/sprockets/64fe0e7bbf53d3cf292e85e123137bcb +0 -0
  40. data/spec/dummy/tmp/cache/assets/development/sprockets/77e01a708457c1d4aac9446e173321a1 +0 -0
  41. data/spec/dummy/tmp/cache/assets/development/sprockets/8ac87e607a25fc208fc1da0c60b24b8b +0 -0
  42. data/spec/dummy/tmp/cache/assets/development/sprockets/8dab559778ce584628d484b9d919cfa8 +0 -0
  43. data/spec/dummy/tmp/cache/assets/development/sprockets/8fde9b9595ed926214e7858402849bb2 +0 -0
  44. data/spec/dummy/tmp/cache/assets/development/sprockets/c9e7400c0b4cf9165368acf909971237 +0 -0
  45. data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  46. data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  47. data/spec/dummy/tmp/cache/assets/development/sprockets/e58e48ebcd3216893f3b053ee6a3d7eb +0 -0
  48. data/spec/dummy/tmp/cache/assets/development/sprockets/e5cfb1a438298274f827c0cbea06e7dc +0 -0
  49. data/spec/dummy/tmp/cache/assets/development/sprockets/f14dc22e71f0438b9fc154ec08da7c10 +0 -0
  50. data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  51. data/spec/models/best_boy_event_spec.rb +20 -0
  52. data/spec/models/day_report_spec.rb +115 -0
  53. data/spec/models/eventable_spec.rb +51 -0
  54. data/spec/models/month_report_spec.rb +113 -0
  55. data/spec/spec_helper.rb +96 -40
  56. metadata +110 -123
  57. data/.gitignore +0 -10
  58. data/.rspec +0 -1
  59. data/.travis.yml +0 -3
  60. data/Gemfile +0 -3
  61. data/LICENSE.txt +0 -20
  62. data/best_boy.gemspec +0 -38
  63. data/db/bestboy.db +0 -0
  64. data/spec/best_boy/best_boy_event_spec.rb +0 -62
  65. data/spec/best_boy/eventable_spec.rb +0 -20
  66. data/spec/dummy/app/mailers/.gitkeep +0 -0
  67. data/spec/dummy/app/models/.gitkeep +0 -0
  68. data/spec/dummy/db/development.sqlite3 +0 -0
  69. data/spec/dummy/lib/assets/.gitkeep +0 -0
@@ -18,30 +18,26 @@
18
18
  <th colspan="2">day</th>
19
19
  </tr>
20
20
  </thead>
21
- <tbody>
22
- <% @event_source_counts_per_group.each do |event_source_string, group_hash| %>
21
+ <% if available_event_sources.first.present? %>
22
+ <tbody>
23
+ <% @sourced_occurrences.keys.each do |source| %>
23
24
  <tr>
24
- <td><%= event_source_string %></td>
25
- <% group_hash.each do |group, counter| %>
26
- <td><%= counter %></td>
27
- <td><%= number_to_percentage(counter.to_f / detail_count * 100, :precision => 2) %></td>
25
+ <td><%= source %><dd/td>
26
+ <% @sourced_occurrences[source].keys.reverse.each do |time_period| %>
27
+ <td><%= @sourced_occurrences[source][time_period] %></td>
28
+ <td><%= relative_occurrences(@sourced_occurrences[source], time_period) %></td>
28
29
  <% end %>
29
30
  </tr>
30
- <% end %>
31
- </tbody>
31
+ <% end %>
32
+ </tbody>
33
+ <% end %>
32
34
  <tfoot>
33
35
  <tr>
34
- <th>Total</th>
35
- <th><%= result = @event_source_counts_per_group.values.inject(0){|sum, hash| sum += hash['overall'].to_i; sum} %></th>
36
- <th><%= number_to_percentage(result.to_f / detail_count * 100, :precision => 2) %></th>
37
- <th><%= result = @event_source_counts_per_group.values.inject(0){|sum, hash| sum += hash['year'].to_i; sum} %></th>
38
- <th><%= number_to_percentage(result.to_f / detail_count * 100, :precision => 2) %></th>
39
- <th><%= result = @event_source_counts_per_group.values.inject(0){|sum, hash| sum += hash['month'].to_i; sum} %></th>
40
- <th><%= number_to_percentage(result.to_f / detail_count * 100, :precision => 2) %></th>
41
- <th><%= result = @event_source_counts_per_group.values.inject(0){|sum, hash| sum += hash['week'].to_i; sum} %></th>
42
- <th><%= number_to_percentage(result.to_f / detail_count * 100, :precision => 2) %></th>
43
- <th><%= result = @event_source_counts_per_group.values.inject(0){|sum, hash| sum += hash['day'].to_i; sum} %></th>
44
- <th><%= number_to_percentage(result.to_f / detail_count * 100, :precision => 2) %></th>
36
+ <th>All</th>
37
+ <% @occurrences[params[:event]].keys.reverse.each do |time_period| %>
38
+ <th><%= @occurrences[params[:event]][time_period] %></th>
39
+ <th><%= relative_occurrences(@occurrences[params[:event]], time_period)%></th>
40
+ <% end %>
45
41
  </tr>
46
42
  </tfoot>
47
43
  </table>
@@ -68,15 +64,25 @@
68
64
  </tr>
69
65
  </thead>
70
66
  <tbody>
71
- <% @event_sources_counts_per_month.each do |event_source_string, month_hash| %>
72
- <tr>
73
- <td><%= event_source_string %></td>
74
- <% month_hash.each do |month, counter| %>
75
- <td><%= counter %></td>
76
- <% end %>
77
- </tr>
67
+ <% if available_event_sources? %>
68
+ <% @event_selected_year_occurrences.keys.reject { |k| k == "All" }.each do |source| %>
69
+ <tr>
70
+ <td><%= source %></td>
71
+ <% @event_selected_year_occurrences[source].keys.reject.each do |month| %>
72
+ <td><%= @event_selected_year_occurrences[source][month] %></td>
73
+ <% end %>
74
+ </tr>
75
+ <% end %>
78
76
  <% end %>
79
77
  </tbody>
78
+ <tfoot>
79
+ <tr>
80
+ <td><strong>All</strong></td>
81
+ <% @event_selected_year_occurrences["All"].keys.each do |month| %>
82
+ <td><%= @event_selected_year_occurrences["All"][month] %></td>
83
+ <% end %>
84
+ </tr>
85
+ </tfoot>
80
86
  </table>
81
87
  </div>
82
- </div>
88
+ </div>
@@ -24,20 +24,20 @@
24
24
  <thead>
25
25
  <tr>
26
26
  <th>Event Source</th>
27
- <% (1..(Time.days_in_month("1-#{current_month}-#{current_year}".to_time.month))).each do |day| %>
28
- <td><%= day %></td>
27
+ <% days_of(current_month).each do |day| %>
28
+ <td><%= day.strftime("%d") %></td>
29
29
  <% end %>
30
30
  </tr>
31
31
  </thead>
32
32
  <tbody>
33
- <% @event_sources_counts_per_day.each do |event_source_string, day_hash| %>
33
+ <% @selected_month_occurrences.keys.each do |source| %>
34
34
  <tr>
35
- <td><%= event_source_string %></td>
36
- <% day_hash.each do |day, counter| %>
37
- <td><%= counter %></td>
38
- <% end %>
35
+ <td><%= source %></td>
36
+ <% @selected_month_occurrences[source].keys.each do |day| %>
37
+ <td><%= @selected_month_occurrences[source][day] %></td>
38
+ <% end%>
39
39
  </tr>
40
- <% end %>
40
+ <% end%>
41
41
  </tbody>
42
42
  </table>
43
43
  </div>
@@ -48,4 +48,4 @@
48
48
  <div id='chart'></div>
49
49
  <%= render_chart(@chart, 'chart') %>
50
50
  </div>
51
- </div>
51
+ </div>
@@ -15,29 +15,30 @@
15
15
  </tr>
16
16
  </thead>
17
17
  <tbody>
18
- <% @event_counts_per_group.each do |event_string, group_hash| %>
18
+ <% @occurrences.keys.each do |key| %>
19
19
  <tr>
20
- <td><%= link_to event_string, best_boy_admin_details_path(:event => event_string, :owner_type => current_owner_type) %></td>
21
- <% group_hash.each do |group, counter| %>
22
- <td><%= counter %></td>
23
- <% end %>
20
+ <td><%= link_to key, best_boy_admin_details_path(:event => key, :owner_type => current_owner_type) %></td>
21
+ <td><%= @occurrences[key][:overall] %></td>
22
+ <td><%= @occurrences[key][:yearly] %></td>
23
+ <td><%= @occurrences[key][:monthly] %></td>
24
+ <td><%= @occurrences[key][:weekly] %> </td>
25
+ <td><%= @occurrences[key][:daily] %></td>
24
26
  </tr>
25
27
  <% end %>
26
28
  </tbody>
27
29
  <tfoot>
28
30
  <tr>
29
31
  <th>Total</th>
30
- <th><%= @event_counts_per_group.values.inject(0){|sum, hash| sum += hash['overall'].to_i; sum} %></th>
31
- <th><%= @event_counts_per_group.values.inject(0){|sum, hash| sum += hash['year'].to_i; sum} %></th>
32
- <th><%= @event_counts_per_group.values.inject(0){|sum, hash| sum += hash['month'].to_i; sum} %></th>
33
- <th><%= @event_counts_per_group.values.inject(0){|sum, hash| sum += hash['week'].to_i; sum} %></th>
34
- <th><%= @event_counts_per_group.values.inject(0){|sum, hash| sum += hash['day'].to_i; sum} %></th>
32
+ <th><%= @this_year_totals[:overall] %></th>
33
+ <th><%= @this_year_totals[:yearly] %></th>
34
+ <th><%= @this_year_totals[:monthly] %></th>
35
+ <th><%= @this_year_totals[:weekly] %></th>
36
+ <th><%= @this_year_totals[:daily] %></th>
35
37
  </tr>
36
38
  </tfoot>
37
39
  </table>
38
40
  </div>
39
41
  </div>
40
-
41
42
  <div class="span12">
42
43
  <div class="well">
43
44
  <h3 class="pull-left">Statistics for <%= current_year %> per month</h3>
@@ -57,23 +58,23 @@
57
58
  </tr>
58
59
  </thead>
59
60
  <tbody>
60
- <% @event_counts_per_month.each do |event_string, month_hash| %>
61
+ <% @selected_year_occurrences.keys.each do |event| %>
61
62
  <tr>
62
- <td><%= event_string %></td>
63
- <% month_hash.each do |month, counter| %>
64
- <td><%= counter %></td>
63
+ <td><%= event %></td>
64
+ <% @selected_year_occurrences[event].keys.each do |month| %>
65
+ <td><%= @selected_year_occurrences[event][month] %></td>
65
66
  <% end %>
66
67
  </tr>
67
68
  <% end %>
68
69
  </tbody>
69
70
  <tfoot>
70
71
  <tr>
71
- <th>Total</th>
72
- <% (1..12).to_a.map(&:to_s).each do |month_no| %>
73
- <th><%= @event_counts_per_month.values.inject(0){|sum, hash| sum += hash[month_no].to_i; sum} %></th>
72
+ <th><strong>Total</strong></th>
73
+ <% @selected_year_totals.keys.each do |month| %>
74
+ <th><%= @selected_year_totals[month] %></th>
74
75
  <% end %>
75
76
  </tr>
76
77
  </tfoot>
77
78
  </table>
78
79
  </div>
79
- </div>
80
+ </div>
@@ -18,6 +18,8 @@ module BestBoy
18
18
  if BestBoy.orm == :active_record
19
19
  require "best_boy/models/active_record/best_boy_event.rb"
20
20
  require "best_boy/models/active_record/best_boy/eventable.rb"
21
+ require "best_boy/models/active_record/best_boy_day_report.rb"
22
+ require "best_boy/models/active_record/best_boy_month_report.rb"
21
23
  ActiveRecord::Base.send(:include, BestBoy::Eventable)
22
24
  else
23
25
  raise "Sorry, best_boy actually only supports ActiveRecord ORM."
@@ -52,6 +52,25 @@ module BestBoy
52
52
  best_boy_event = BestBoyEvent.new(:event => type, :event_source => source)
53
53
  best_boy_event.owner = self
54
54
  best_boy_event.save
55
+ report type, source
56
+ end
57
+
58
+ def report type, source = nil
59
+ month_report = BestBoy::MonthReport.current_or_create_for(self.class.to_s, type)
60
+ month_report_with_source = BestBoy::MonthReport.current_or_create_for(self.class.to_s, type, source) if source.present?
61
+
62
+ day_report = BestBoy::DayReport.current_or_create_for(self.class.to_s, type)
63
+ day_report_with_source = BestBoy::DayReport.current_or_create_for(self.class.to_s, type, source) if source.present?
64
+
65
+ increment_occurrences_in_reports month_report, month_report_with_source, day_report, day_report_with_source
66
+ end
67
+
68
+ def increment_occurrences_in_reports(month_report, month_report_with_source, day_report, day_report_with_source)
69
+ day_report_with_source.increment!(:occurrences) if day_report_with_source.present?
70
+ month_report_with_source.increment!(:occurrences) if month_report_with_source.present?
71
+
72
+ day_report.increment!(:occurrences)
73
+ month_report.increment!(:occurrences)
55
74
  end
56
75
  end
57
76
  end
@@ -0,0 +1,65 @@
1
+ module BestBoy
2
+ class DayReport < ActiveRecord::Base
3
+
4
+ # db configuration
5
+ #
6
+ #
7
+
8
+ self.table_name = "best_boy_day_reports"
9
+
10
+ # associations
11
+ #
12
+ #
13
+
14
+ belongs_to :owner, polymorphic: true
15
+ belongs_to :month_report
16
+
17
+ # validations
18
+ #
19
+ #
20
+
21
+ validates :month_report_id, :owner_type, :event, presence: true
22
+
23
+ # scopes
24
+ #
25
+ #
26
+
27
+ scope :created_on, ->(date) { where(created_at: date.beginning_of_day..date.end_of_day) }
28
+ scope :week, -> { where(created_at: Time.zone.now.beginning_of_week..Time.zone.now) }
29
+
30
+ # class methods
31
+ #
32
+ #
33
+
34
+ def self.current_for(date, owner, type, source = nil)
35
+ self.for(owner, type, source).created_on(date)
36
+ end
37
+
38
+ def self.current_or_create_for(owner, type, source = nil)
39
+ day_report = self.current_for(Time.zone.now, owner, type, source).last
40
+ day_report.present? ? day_report : self.create_for(owner, type, source)
41
+ end
42
+
43
+ def self.create_for(owner, type, source = nil)
44
+ month_report = BestBoy::MonthReport.current_or_create_for(owner, type, source)
45
+ BestBoy::DayReport.create(
46
+ owner_type: owner,
47
+ event: type,
48
+ month_report_id: month_report.to_param,
49
+ event_source: source
50
+ )
51
+ end
52
+
53
+ def self.for(owner, type, source = nil)
54
+ self.where(owner_type: owner, event: type, event_source: source)
55
+ end
56
+
57
+ def self.daily_occurrences_for(owner, type, source = nil, date)
58
+ self.created_on(date).for(owner, type, source).sum(:occurrences)
59
+ end
60
+
61
+ def self.weekly_occurrences_for(owner, type, source = nil)
62
+ self.week.for(owner, type, source).sum(:occurrences)
63
+ end
64
+ end
65
+ end
@@ -10,14 +10,4 @@ class BestBoyEvent < ActiveRecord::Base
10
10
  #
11
11
  validates :event, :presence => true
12
12
 
13
- # scopes
14
- #
15
- #
16
-
17
- scope :per_day, lambda { |date| where("best_boy_events.created_at BETWEEN ? AND ?", date.beginning_of_day, date.end_of_day) }
18
- scope :per_week, lambda { |date| where("best_boy_events.created_at BETWEEN ? AND ?", date.beginning_of_week, date.end_of_week) }
19
- scope :per_month, lambda { |date| where("best_boy_events.created_at BETWEEN ? AND ?", date.beginning_of_month, date.end_of_month) }
20
- scope :per_year, lambda { |date| where("best_boy_events.created_at BETWEEN ? AND ?", date.beginning_of_year, date.end_of_year) }
21
-
22
-
23
- end
13
+ end
@@ -0,0 +1,63 @@
1
+ module BestBoy
2
+ class MonthReport < ActiveRecord::Base
3
+
4
+ # db configuration
5
+ #
6
+ #
7
+
8
+ self.table_name = "best_boy_month_reports"
9
+
10
+ # associations
11
+ #
12
+ #
13
+
14
+ belongs_to :owner, polymorphic: true
15
+ has_many :day_reports
16
+
17
+ # validations
18
+ #
19
+ #
20
+
21
+ validates :owner_type, :event, presence: true
22
+
23
+ # scopes
24
+ #
25
+ #
26
+
27
+ scope :created_on, ->(date) { where(created_at: date.beginning_of_day..date.end_of_day) }
28
+ scope :between, ->(start_date, end_date) { where(created_at: start_date.beginning_of_day..end_date.end_of_day) }
29
+
30
+ # class methods
31
+ #
32
+ #
33
+
34
+ def self.current_for(date, owner, type, source = nil)
35
+ self.for(owner, type, source).between(date.beginning_of_month, date)
36
+ end
37
+
38
+ def self.current_or_create_for(owner, type, source = nil)
39
+ month_report = self.current_for(Time.zone.now, owner, type, source).last
40
+ month_report.present? ? month_report : self.create_for(owner, type, source)
41
+ end
42
+
43
+ def self.create_for(owner, type, source = nil)
44
+ BestBoy::MonthReport.create(owner_type: owner.to_s, event: type, event_source: source)
45
+ end
46
+
47
+ def self.for(owner, type, source = nil)
48
+ self.where(owner_type: owner, event: type, event_source: source)
49
+ end
50
+
51
+ def self.monthly_occurrences_for(owner, type, source = nil, date)
52
+ self.for(owner, type, source).between(date.beginning_of_month, date.end_of_month).sum(:occurrences)
53
+ end
54
+
55
+ def self.yearly_occurrences_for(owner, type, source = nil, date)
56
+ self.for(owner, type, source).between(date.beginning_of_year, date).sum(:occurrences)
57
+ end
58
+
59
+ def self.overall_occurrences_for(owner, type, source = nil)
60
+ self.for(owner, type, source).sum(:occurrences)
61
+ end
62
+ end
63
+ end
@@ -1,3 +1,3 @@
1
1
  module BestBoy
2
- VERSION = "1.3.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -14,7 +14,10 @@ module ActiveRecord
14
14
  end
15
15
 
16
16
  def create_migration_file
17
- %w(create_best_boy_events_table.rb add_event_source_to_best_boy_events_table.rb).each do |migration_file|
17
+ %w( create_best_boy_events_table.rb
18
+ add_event_source_to_best_boy_events_table.rb
19
+ create_best_boy_reports.rb
20
+ ).each do |migration_file|
18
21
  destination = "db/migrate/#{migration_file.sub(%r\.rb$\, '')}"
19
22
  if not self.class.migration_exists?(File.dirname(destination), File.basename(destination))
20
23
  migration_template migration_file, destination
@@ -0,0 +1,30 @@
1
+ class CreateBestBoyReports < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :best_boy_day_reports, :force => true do |t|
4
+ t.string :owner_type
5
+ t.string :event
6
+ t.string :event_source
7
+ t.integer :month_report_id
8
+ t.integer :occurrences, default: 0
9
+ t.timestamps
10
+ end
11
+ add_index :best_boy_day_reports, [:owner_type, :event, :event_source], :name => :index_best_boy_day_reports_aggregated_columns
12
+ add_index :best_boy_day_reports, :created_at
13
+ add_index :best_boy_day_reports, :month_report_id
14
+
15
+ create_table :best_boy_month_reports, :force => true do |t|
16
+ t.string :owner_type
17
+ t.string :event
18
+ t.string :event_source
19
+ t.integer :occurrences, default: 0
20
+ t.timestamps
21
+ end
22
+ add_index :best_boy_month_reports, [:owner_type, :event, :event_source], :name => :index_best_boy_month_reports_aggregated_columns
23
+ add_index :best_boy_month_reports, :created_at
24
+ end
25
+
26
+ def self.down
27
+ drop_table :best_boy_month_reports
28
+ drop_table :best_boy_day_reports
29
+ end
30
+ end
@@ -0,0 +1,146 @@
1
+ namespace :best_boy do
2
+ desc "Creates consistent structure of DayReports and MonthReports for a given set of events"
3
+ task :recover_report_history, [:date] => :environment do |t, args|
4
+
5
+ # helper methods
6
+ #
7
+ #
8
+
9
+ def month_report_id_for(year, owner_type, source, event)
10
+ date = Date.parse("#{year}-01-01")
11
+ BestBoy::MonthReport.where(created_at: date.beginning_of_day..date.end_of_year.end_of_day,
12
+ owner_type: owner_type,
13
+ event_source: source,
14
+ event: event).first.id
15
+ end
16
+
17
+ def flush
18
+ print "."
19
+ STDOUT.flush
20
+ end
21
+
22
+ # Read optional date
23
+ #
24
+ #
25
+
26
+ start = args.date.present? ? Date.parse(args.date) : nil
27
+
28
+ puts ""
29
+ puts "> Destroying all reports ..."
30
+ puts ">... that where created after beginning of day #{start}" if start.present?
31
+ puts ""
32
+
33
+ # Destroy all existing reports
34
+ #
35
+ #
36
+
37
+ if start.present?
38
+ BestBoy::MonthReport.between(start, Date.today).destroy_all
39
+ BestBoy::DayReport.where(created_at: start.beginning_of_day..Date.today.end_of_day).destroy_all
40
+ else
41
+ BestBoy::MonthReport.destroy_all
42
+ BestBoy::DayReport.destroy_all
43
+ end
44
+
45
+ puts ""
46
+ puts "> Selected report data has been destroyed."
47
+ puts ""
48
+
49
+ owner_types = BestBoyEvent.order(:owner_type).uniq.pluck(:owner_type)
50
+ available_events = {}
51
+ available_event_sources = {}
52
+
53
+ owner_types.each do |owner_type|
54
+ available_events.merge!( { owner_type => BestBoyEvent.where(owner_type: owner_type).order(:event).uniq.pluck(:event) } )
55
+ available_event_sources.merge!( { owner_type => BestBoyEvent.where(owner_type: owner_type).order(:event_source).uniq.pluck(:event_source) } ) # explicitly including nil
56
+ end
57
+
58
+ start = BestBoyEvent.order('created_at ASC').first.created_at.to_date unless start.present?
59
+ days = (start..BestBoyEvent.order('created_at ASC').last.created_at.to_date)
60
+
61
+ puts ""
62
+ puts "> Start creating new reports for #{days.count} days ..."
63
+ puts ""
64
+
65
+ days.each do |day|
66
+ owner_types.each do |owner_type|
67
+ available_events[owner_type].each do |event|
68
+ available_event_sources[owner_type].each do |source|
69
+
70
+ base_scope = BestBoyEvent.where(owner_type: owner_type, event: event, event_source: source).order('created_at DESC')
71
+
72
+ # Create MonthReports when...
73
+ # - diving into loop initially or
74
+ # - a new month starts
75
+
76
+ if day.day == 1 || days.first == day
77
+
78
+ # Check if Events occured during the whole month.
79
+ # If any, create MonthReports.
80
+
81
+ month_scope = base_scope.where(created_at: day.beginning_of_month.beginning_of_day..day.end_of_month.end_of_day)
82
+ monthly_occurrences = month_scope.count
83
+
84
+ if monthly_occurrences > 0
85
+ artifical_created_at = month_scope.first.created_at
86
+ if source.present?
87
+ month_report_with_source = BestBoy::MonthReport.new
88
+ month_report_with_source.owner_type = owner_type
89
+ month_report_with_source.event = event
90
+ month_report_with_source.event_source = source
91
+ month_report_with_source.occurrences = monthly_occurrences
92
+ month_report_with_source.created_at = artifical_created_at
93
+ month_report_with_source.save!
94
+ end
95
+
96
+ month_report_without_source = BestBoy::MonthReport.new
97
+ month_report_without_source.owner_type = owner_type
98
+ month_report_without_source.event = event
99
+ month_report_without_source.event_source = nil
100
+ month_report_without_source.occurrences = monthly_occurrences
101
+ month_report_without_source.created_at = artifical_created_at
102
+ month_report_without_source.save!
103
+ end
104
+ end
105
+
106
+ # Create DayReports if Events occured that specific day
107
+ #
108
+ #
109
+
110
+ day_scope = base_scope.where(created_at: day.beginning_of_day..day.end_of_day)
111
+ daily_occurrences = day_scope.count
112
+
113
+ if daily_occurrences > 0
114
+ if source.present?
115
+ day_report_with_source = BestBoy::DayReport.new
116
+ day_report_with_source.owner_type = owner_type
117
+ day_report_with_source.event = event
118
+ day_report_with_source.event_source = source
119
+ day_report_with_source.occurrences = daily_occurrences
120
+ day_report_with_source.created_at = day_scope.first.created_at
121
+ day_report_with_source.month_report_id = month_report_id_for(day.year, owner_type, source, event)
122
+ day_report_with_source.save!
123
+ end
124
+
125
+ day_report_without_source = BestBoy::DayReport.new
126
+ day_report_without_source.owner_type = owner_type
127
+ day_report_without_source.event = event
128
+ day_report_without_source.event_source = nil
129
+ day_report_without_source.occurrences = daily_occurrences
130
+ day_report_without_source.created_at = day_scope.first.created_at
131
+ day_report_without_source.month_report_id = month_report_id_for(day.year, owner_type, nil, event)
132
+ day_report_without_source.save!
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ flush
139
+ end
140
+
141
+ puts ""
142
+ puts ""
143
+ puts "> Reports recovered. Done!"
144
+ puts ""
145
+ end
146
+ end