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.
- data/README.md +36 -3
- data/Rakefile +45 -7
- data/app/controllers/best_boy/best_boy_events_controller.rb +147 -98
- data/app/helpers/best_boy/best_boy_view_helper.rb +9 -0
- data/app/views/best_boy/best_boy_events/details.html.erb +33 -27
- data/app/views/best_boy/best_boy_events/monthly_details.html.erb +9 -9
- data/app/views/best_boy/best_boy_events/stats.html.erb +20 -19
- data/lib/best_boy/engine.rb +2 -0
- data/lib/best_boy/models/active_record/best_boy/eventable.rb +19 -0
- data/lib/best_boy/models/active_record/best_boy_day_report.rb +65 -0
- data/lib/best_boy/models/active_record/best_boy_event.rb +1 -11
- data/lib/best_boy/models/active_record/best_boy_month_report.rb +63 -0
- data/lib/best_boy/version.rb +1 -1
- data/lib/generators/active_record/best_boy_generator.rb +4 -1
- data/lib/generators/active_record/templates/create_best_boy_reports.rb +30 -0
- data/lib/tasks/recover_report_history.rake +146 -0
- data/spec/{best_boy → controllers}/best_boy_controller_spec.rb +6 -4
- data/spec/dummy/app/views/test_events/index.html.haml +9 -1
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/dummy/db/migrate/20131108085915_create_best_boy_reports.rb +30 -0
- data/spec/dummy/db/schema.rb +27 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +10092 -0
- data/spec/dummy/log/test.log +531 -0
- data/spec/dummy/tmp/cache/assets/development/sass/f99cb4f6f36f128b2d6950c813eec72c66616bfc/bootstrap.scssc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/01af51e20498d87feb18694bed0d0731 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/057daf732c672b9e0ec8bd233ec79077 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1565c81151c1e0fe577f787a645bca3d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1c90620581903652712500bb92915909 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3241270f308313221453f51980c07883 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3a59d6acf2f4543a36d946d653b08dab +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3a5f8aba9c98833836df55cdc5502ee8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/42804a4f90448633879c06a33e49f4e6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/48279ff6b6f65f85e766c3a7ae0c71f6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/642b8ba757f92502a3a3281a956eec2a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/64fe0e7bbf53d3cf292e85e123137bcb +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/77e01a708457c1d4aac9446e173321a1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8ac87e607a25fc208fc1da0c60b24b8b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8dab559778ce584628d484b9d919cfa8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8fde9b9595ed926214e7858402849bb2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c9e7400c0b4cf9165368acf909971237 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e58e48ebcd3216893f3b053ee6a3d7eb +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e5cfb1a438298274f827c0cbea06e7dc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f14dc22e71f0438b9fc154ec08da7c10 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/models/best_boy_event_spec.rb +20 -0
- data/spec/models/day_report_spec.rb +115 -0
- data/spec/models/eventable_spec.rb +51 -0
- data/spec/models/month_report_spec.rb +113 -0
- data/spec/spec_helper.rb +96 -40
- metadata +110 -123
- data/.gitignore +0 -10
- data/.rspec +0 -1
- data/.travis.yml +0 -3
- data/Gemfile +0 -3
- data/LICENSE.txt +0 -20
- data/best_boy.gemspec +0 -38
- data/db/bestboy.db +0 -0
- data/spec/best_boy/best_boy_event_spec.rb +0 -62
- data/spec/best_boy/eventable_spec.rb +0 -20
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- 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
|
-
|
22
|
-
|
21
|
+
<% if available_event_sources.first.present? %>
|
22
|
+
<tbody>
|
23
|
+
<% @sourced_occurrences.keys.each do |source| %>
|
23
24
|
<tr>
|
24
|
-
<td><%=
|
25
|
-
<%
|
26
|
-
<td><%=
|
27
|
-
<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
|
-
|
31
|
-
|
31
|
+
<% end %>
|
32
|
+
</tbody>
|
33
|
+
<% end %>
|
32
34
|
<tfoot>
|
33
35
|
<tr>
|
34
|
-
<th>
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
<%
|
72
|
-
|
73
|
-
<
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
<% (
|
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
|
-
<% @
|
33
|
+
<% @selected_month_occurrences.keys.each do |source| %>
|
34
34
|
<tr>
|
35
|
-
<td><%=
|
36
|
-
<%
|
37
|
-
<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
|
-
<% @
|
18
|
+
<% @occurrences.keys.each do |key| %>
|
19
19
|
<tr>
|
20
|
-
<td><%= link_to
|
21
|
-
|
22
|
-
|
23
|
-
|
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><%= @
|
31
|
-
<th><%= @
|
32
|
-
<th><%= @
|
33
|
-
<th><%= @
|
34
|
-
<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
|
-
<% @
|
61
|
+
<% @selected_year_occurrences.keys.each do |event| %>
|
61
62
|
<tr>
|
62
|
-
<td><%=
|
63
|
-
<%
|
64
|
-
<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
|
-
<%
|
73
|
-
<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>
|
data/lib/best_boy/engine.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/best_boy/version.rb
CHANGED
@@ -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
|
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
|