best_boy 1.3.0 → 2.0.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 (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