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
data/README.md
CHANGED
@@ -59,6 +59,12 @@ Run the migration
|
|
59
59
|
rake db:migrate
|
60
60
|
|
61
61
|
|
62
|
+
Update in Version 2
|
63
|
+
--------------------------------
|
64
|
+
|
65
|
+
From Version 2.x on BestBoy uses aggregated tables for the admin panel. See section "Some thoughts about Performance"
|
66
|
+
|
67
|
+
|
62
68
|
Update to fit the asset-pipeline
|
63
69
|
--------------------------------
|
64
70
|
|
@@ -120,6 +126,33 @@ After installation you can access it through:
|
|
120
126
|
|
121
127
|
<your application path>/best_boy_admin
|
122
128
|
|
129
|
+
Some thoughts about Performance
|
130
|
+
-------------------------------
|
131
|
+
|
132
|
+
When you're running BestBoy for a long time, accessing and processing data in
|
133
|
+
the backend can take awfully long.
|
134
|
+
|
135
|
+
By changing to version 1.4.0, we modified BestBoy's data storage organization to
|
136
|
+
reduce database queries. This leads to far more acceptable loading times. To do
|
137
|
+
so, BestBoy creates daily and monthly reports, which are aggregations
|
138
|
+
of the persisted events. When computing statistical data, BestBoy
|
139
|
+
then uses the aggregated tables.
|
140
|
+
|
141
|
+
If you're upgrading BestBoy from an older version, there
|
142
|
+
is a rake task for 'recovering' these report structure for
|
143
|
+
an existing set of events. Simply run
|
144
|
+
|
145
|
+
bundle exec rake best_boy:recover_report_history
|
146
|
+
|
147
|
+
If you want to recover this report structure not for the whole lifetime,
|
148
|
+
you can pass a date as argument to the rake task call:
|
149
|
+
|
150
|
+
bundle exec rake best_boy:recover_report_history['2010-02-01']
|
151
|
+
|
152
|
+
The latter would destroy and recover the all reports created after
|
153
|
+
beginning of Feb 1st, 2010 up to now.
|
154
|
+
|
155
|
+
Budget some time for this task, since it can take long if your BestBoyEvent table has grown very big.
|
123
156
|
|
124
157
|
Used gems and resource
|
125
158
|
----------------------
|
@@ -127,14 +160,14 @@ Used gems and resource
|
|
127
160
|
|
128
161
|
[Stefan Petre](http://www.eyecon.ro/bootstrap-datepicker) for Datepicker in Twitter Bootstrap style
|
129
162
|
|
130
|
-
[Winston Teo Yong Wei](https://github.com/winston/google_visualr)
|
163
|
+
[Winston Teo Yong Wei](https://github.com/winston/google_visualr) Google_Visualr in its version 2.1.2
|
131
164
|
|
132
165
|
|
133
166
|
Contributors in alphabetic order
|
134
167
|
--------------------------------
|
135
168
|
@cseydel
|
136
169
|
@danscho
|
137
|
-
|
170
|
+
@rneumann
|
138
171
|
|
139
172
|
Thanks
|
140
173
|
------
|
@@ -142,4 +175,4 @@ We are extremely grateful to everyone contributing to this project.
|
|
142
175
|
Big thanks to each contributor on Impressionist. This gem helped me a long way to get here in modelling and creating a gem.
|
143
176
|
|
144
177
|
|
145
|
-
See LICENSE.txt for details on licenses.
|
178
|
+
See LICENSE.txt for details on licenses.
|
data/Rakefile
CHANGED
@@ -1,11 +1,49 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler/setup'
|
3
|
-
require 'rake'
|
4
|
-
require 'rspec/core'
|
5
|
-
require 'rspec/core/rake_task'
|
1
|
+
# require 'rubygems'
|
2
|
+
# require 'bundler/setup'
|
3
|
+
# require 'rake'
|
4
|
+
# require 'rspec/core'
|
5
|
+
# require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
# Bundler::GemHelper.install_tasks
|
8
|
+
# RSpec::Core::RakeTask.new(:spec)
|
9
|
+
# task :default => :spec
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
#!/usr/bin/env rake
|
14
|
+
begin
|
15
|
+
require 'bundler/setup'
|
16
|
+
rescue LoadError
|
17
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
18
|
+
end
|
19
|
+
begin
|
20
|
+
require 'rdoc/task'
|
21
|
+
rescue LoadError
|
22
|
+
require 'rdoc/rdoc'
|
23
|
+
require 'rake/rdoctask'
|
24
|
+
RDoc::Task = Rake::RDocTask
|
25
|
+
end
|
26
|
+
|
27
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
28
|
+
rdoc.rdoc_dir = 'rdoc'
|
29
|
+
rdoc.title = 'BestBoy'
|
30
|
+
rdoc.options << '--line-numbers'
|
31
|
+
rdoc.rdoc_files.include('README.rdoc')
|
32
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
33
|
+
end
|
34
|
+
|
35
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
36
|
+
load 'rails/tasks/engine.rake'
|
37
|
+
|
38
|
+
|
6
39
|
|
7
40
|
Bundler::GemHelper.install_tasks
|
8
41
|
|
9
|
-
|
42
|
+
# We use rspec
|
43
|
+
require 'rspec/core'
|
44
|
+
require 'rspec/core/rake_task'
|
45
|
+
|
46
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
47
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
10
48
|
|
11
|
-
task :default => :spec
|
49
|
+
task :default => :spec
|
@@ -1,136 +1,180 @@
|
|
1
1
|
module BestBoy
|
2
2
|
class BestBoyEventsController < BestBoy.base_controller.constantize
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
before_action BestBoy.before_filter if BestBoy.before_filter.present?
|
5
|
+
|
6
6
|
skip_before_filter BestBoy.skip_before_filter if BestBoy.skip_before_filter.present?
|
7
7
|
skip_after_filter BestBoy.skip_after_filter if BestBoy.skip_after_filter.present?
|
8
8
|
|
9
9
|
layout 'best_boy_backend'
|
10
10
|
|
11
|
-
helper_method :available_owner_types, :available_events, :available_event_sources, :available_years,
|
12
|
-
:current_owner_type, :current_event, :current_event_source, :current_month, :current_year, :collection,
|
13
|
-
:render_chart, :month_name_array, :detail_count
|
14
11
|
|
12
|
+
helper BestBoy::BestBoyViewHelper
|
13
|
+
helper_method :available_owner_types, :available_events, :available_event_sources, :available_event_sources?, :available_years,
|
14
|
+
:current_owner_type, :current_event, :current_event_source, :current_month, :current_year, :collection,
|
15
|
+
:days_of, :render_chart, :month_name_array, :detail_count
|
15
16
|
|
16
17
|
def stats
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@event_counts_per_group = {}
|
23
|
-
overall_hash = counter_scope.inject({}){ |hash, element| hash[element.event] = element.counter; hash}
|
24
|
-
current_year_hash = counter_scope.per_year(Time.zone.now).inject({}){ |hash, element| hash[element.event] = element.counter; hash }
|
25
|
-
current_month_hash = counter_scope.per_month(Time.zone.now).inject({}){ |hash, element| hash[element.event] = element.counter; hash }
|
26
|
-
current_week_hash = counter_scope.per_week(Time.zone.now).inject({}){ |hash, element| hash[element.event] = element.counter; hash }
|
27
|
-
current_day_hash = counter_scope.per_day(Time.zone.now).inject({}){ |hash, element| hash[element.event] = element.counter; hash }
|
18
|
+
collect_occurrences
|
19
|
+
collect_occurrences_for_selected_year
|
20
|
+
available_events_totals
|
21
|
+
selected_year_totals
|
22
|
+
end
|
28
23
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@event_counts_per_group[event]['day'] = current_day_hash[event] || 0
|
36
|
-
end
|
24
|
+
def details
|
25
|
+
collect_occurrences
|
26
|
+
collect_occurrences_grouped_by_sources
|
27
|
+
collect_occurrences_for_selected_year_of current_event
|
28
|
+
selected_year_totals
|
29
|
+
end
|
37
30
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
%w(1 2 3 4 5 6 7 8 9 10 11 12).each do |month|
|
43
|
-
month_hash = counter_scope.per_month("1-#{month}-#{current_year}".to_time).inject({}){ |hash, element| hash[element.event] = element.counter; hash}
|
31
|
+
def monthly_details
|
32
|
+
collect_occurrences_for_month current_month
|
33
|
+
monthly_details_chart
|
34
|
+
end
|
44
35
|
|
45
|
-
|
46
|
-
|
47
|
-
@event_counts_per_month[event][month] = month_hash[event] || 0
|
48
|
-
end
|
49
|
-
end
|
36
|
+
def charts
|
37
|
+
build_chart
|
50
38
|
end
|
51
39
|
|
40
|
+
private
|
52
41
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
42
|
+
def collect_event_occurrences(event)
|
43
|
+
{
|
44
|
+
event => {
|
45
|
+
:daily => BestBoy::DayReport.daily_occurrences_for(current_owner_type, event, nil, Time.zone.now),
|
46
|
+
:weekly => BestBoy::DayReport.weekly_occurrences_for(current_owner_type, event),
|
47
|
+
:monthly => BestBoy::MonthReport.monthly_occurrences_for(current_owner_type, event, nil, Time.zone.now),
|
48
|
+
:yearly => BestBoy::MonthReport.yearly_occurrences_for(current_owner_type, event, nil, Time.zone.now),
|
49
|
+
:overall => BestBoy::MonthReport.overall_occurrences_for(current_owner_type, event)
|
50
|
+
}
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def collect_occurrences
|
55
|
+
@occurrences = {}
|
56
|
+
available_events.each { |event| @occurrences.merge! collect_event_occurrences(event) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def collect_source_occurrences(source)
|
60
|
+
{
|
61
|
+
source => {
|
62
|
+
:daily => BestBoy::DayReport.daily_occurrences_for(current_owner_type, current_event, source, Time.zone.now),
|
63
|
+
:weekly => BestBoy::DayReport.weekly_occurrences_for(current_owner_type, current_event, source),
|
64
|
+
:monthly => BestBoy::MonthReport.monthly_occurrences_for(current_owner_type, current_event, source, Time.zone.now),
|
65
|
+
:yearly => BestBoy::MonthReport.yearly_occurrences_for(current_owner_type, current_event, source, Time.zone.now),
|
66
|
+
:overall => BestBoy::MonthReport.overall_occurrences_for(current_owner_type, current_event, source)
|
67
|
+
}
|
68
|
+
}
|
69
|
+
end
|
74
70
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
%w(1 2 3 4 5 6 7 8 9 10 11 12).each do |month|
|
80
|
-
month_hash = counter_scope.per_month("1-#{month}-#{current_year}".to_time).inject({}){ |hash, element| hash[element.event_source] = element.counter; hash}
|
71
|
+
def collect_occurrences_grouped_by_sources
|
72
|
+
@sourced_occurrences = {}
|
73
|
+
available_event_sources.each { |source| @sourced_occurrences.merge! collect_source_occurrences(source) }
|
74
|
+
end
|
81
75
|
|
82
|
-
|
83
|
-
|
84
|
-
|
76
|
+
def collect_occurrences_for_month(month)
|
77
|
+
@selected_month_occurrences = {}
|
78
|
+
if available_event_sources?
|
79
|
+
available_event_sources.each do |source|
|
80
|
+
days_of(month).each do |day|
|
81
|
+
@selected_month_occurrences.merge!({source => {day => BestBoy::DayReport.daily_occurrences_for(current_owner_type, current_event, source, day)}}) { |k, v1, v2| v1.merge!(v2) }
|
82
|
+
end
|
85
83
|
end
|
86
84
|
end
|
85
|
+
days_of(month).each do |day|
|
86
|
+
@selected_month_occurrences.merge!({"All" => {day => BestBoy::DayReport.daily_occurrences_for(current_owner_type, current_event, nil, day)}}) { |k, v1, v2| v1.merge!(v2) }
|
87
|
+
end
|
87
88
|
end
|
88
89
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
@event_sources_counts_per_day = {}
|
97
|
-
days.each do |day|
|
98
|
-
day_hash = counter_scope.per_day("#{day}-#{current_month}-#{current_year}".to_time).inject({}){ |hash, element| hash[element.event_source] = element.counter; hash}
|
99
|
-
|
100
|
-
available_event_sources.each do |event_source|
|
101
|
-
@event_sources_counts_per_day[event_source] ||= {}
|
102
|
-
@event_sources_counts_per_day[event_source][day] = day_hash[event_source] || 0
|
90
|
+
def collect_occurrences_for_selected_year
|
91
|
+
@selected_year_occurrences = {}
|
92
|
+
available_events.each do |event|
|
93
|
+
@selected_year_occurrences.merge!({event => {}})
|
94
|
+
(1..12).each do |month|
|
95
|
+
date = Date.parse("#{current_year}-#{month}-1")
|
96
|
+
@selected_year_occurrences[event].merge!({month.to_s => BestBoy::MonthReport.monthly_occurrences_for(current_owner_type, event, nil, date)})
|
103
97
|
end
|
104
98
|
end
|
99
|
+
end
|
105
100
|
|
106
|
-
|
107
|
-
|
108
|
-
available_event_sources.
|
109
|
-
|
101
|
+
def collect_occurrences_for_selected_year_of(event)
|
102
|
+
@event_selected_year_occurrences = {}
|
103
|
+
sources = available_event_sources.to_a + ["All"]
|
104
|
+
|
105
|
+
sources.each do |source|
|
106
|
+
@event_selected_year_occurrences.merge!({source => {}})
|
107
|
+
(1..12).each do |month|
|
108
|
+
date = Date.parse("#{current_year}-#{month}-1")
|
109
|
+
query_source = source == "All" ? nil : source
|
110
|
+
branch = {month.to_s => BestBoy::MonthReport.monthly_occurrences_for(current_owner_type, event, query_source, date)}
|
111
|
+
@event_selected_year_occurrences[source].merge!(branch)
|
112
|
+
end
|
110
113
|
end
|
114
|
+
end
|
111
115
|
|
112
|
-
|
113
|
-
|
114
|
-
|
116
|
+
def available_events_totals
|
117
|
+
@this_year_totals = { :daily => 0, :weekly => 0, :monthly => 0, :yearly => 0, :overall => 0 }
|
118
|
+
available_events.each do |event|
|
119
|
+
@this_year_totals.keys.each do |time_period|
|
120
|
+
@this_year_totals[time_period] += @occurrences[event][time_period]
|
121
|
+
end
|
115
122
|
end
|
116
|
-
@chart = GoogleVisualr::Interactive::AreaChart.new(data_table, { width: 900, height: 240, title: "" })
|
117
123
|
end
|
118
124
|
|
125
|
+
def selected_year_totals
|
126
|
+
@selected_year_totals = {}
|
127
|
+
# OPTIMIZE ME:
|
128
|
+
# Query below could be replaced with a GROUP_BY or similar
|
129
|
+
# SQL-statement for performance boost, i.e. similar to
|
130
|
+
# BestBoy::MonthReport.select("SUM(occurances) AS counter, DATE_PART('month', created_at) as month").where(:owner_type => current_owner_type, created_at: current_year.beginning_of_year..current_year.end_of_year).group("DATE_PART('month', created_at)")
|
131
|
+
(1..12).each do |month|
|
132
|
+
date = Date.parse("#{current_year}-#{month}-1")
|
133
|
+
@selected_year_totals.merge!({
|
134
|
+
month => BestBoy::MonthReport
|
135
|
+
.where(owner_type: current_owner_type, event_source: nil)
|
136
|
+
.between(date.beginning_of_month, date.end_of_month).sum(:occurrences)
|
137
|
+
})
|
138
|
+
end
|
139
|
+
end
|
119
140
|
|
120
|
-
|
141
|
+
def days_of(month)
|
142
|
+
reference = Date.parse("#{current_year}#{month}-1")
|
143
|
+
(reference.beginning_of_month..reference.end_of_month)
|
144
|
+
end
|
121
145
|
|
122
146
|
def render_chart(chart, dom)
|
123
147
|
chart.to_js(dom).html_safe
|
124
148
|
end
|
125
149
|
|
126
|
-
def
|
150
|
+
def chart_for(data)
|
151
|
+
@chart = GoogleVisualr::Interactive::AreaChart.new(data, { width: 900, height: 240, title: "" })
|
152
|
+
end
|
153
|
+
|
154
|
+
def row_values_for(day)
|
155
|
+
available_event_sources.collect{ |event_source| @selected_month_occurrences[event_source][day] } + [@selected_month_occurrences["All"][day]]
|
156
|
+
end
|
157
|
+
|
158
|
+
def monthly_details_chart
|
159
|
+
data_table = GoogleVisualr::DataTable.new
|
160
|
+
data_table.new_column('string', 'time')
|
161
|
+
|
162
|
+
labels = available_event_sources.to_a + ["All"]
|
163
|
+
labels.each { |label| data_table.new_column('number', label.to_s) }
|
164
|
+
|
165
|
+
days_of(params[:month]).each { |day| data_table.add_row( [day.strftime("%d")] + row_values_for(day) ) }
|
166
|
+
chart_for data_table
|
167
|
+
end
|
168
|
+
|
169
|
+
def build_chart
|
127
170
|
data_table = GoogleVisualr::DataTable.new
|
128
171
|
data_table.new_column('string', 'time')
|
129
172
|
data_table.new_column('number', current_owner_type.to_s)
|
173
|
+
|
130
174
|
time_periode_range.each do |periode|
|
131
175
|
data_table.add_row([chart_legend_time_name(periode), custom_data_count(current_event_source, calculated_point_in_time(periode))])
|
132
176
|
end
|
133
|
-
|
177
|
+
chart_for data_table
|
134
178
|
end
|
135
179
|
|
136
180
|
def week_name_array
|
@@ -142,11 +186,12 @@ module BestBoy
|
|
142
186
|
end
|
143
187
|
|
144
188
|
def custom_data_count(source, time)
|
145
|
-
scope =
|
189
|
+
scope = %("week", "month").include?(current_time_interval) ? BestBoy::DayReport.created_on(time) : BestBoy::MonthReport.between(time.beginning_of_month, time.end_of_month)
|
190
|
+
scope = scope.where(owner_type: current_owner_type)
|
146
191
|
scope = scope.where(event: current_event) if current_event.present?
|
147
192
|
scope = scope.where(event_source: source) if source.present?
|
148
|
-
scope = scope.
|
149
|
-
scope.
|
193
|
+
scope = scope.where(event_source: nil) if source.nil?
|
194
|
+
scope.sum(:occurrences)
|
150
195
|
end
|
151
196
|
|
152
197
|
def time_periode_range
|
@@ -211,21 +256,25 @@ module BestBoy
|
|
211
256
|
end
|
212
257
|
|
213
258
|
def available_events
|
214
|
-
@available_events ||=
|
259
|
+
@available_events ||= BestBoy::MonthReport.where(owner_type: current_owner_type).order(:event).uniq.pluck(:event)
|
215
260
|
end
|
216
261
|
|
217
262
|
def available_event_sources
|
218
263
|
@available_event_sources ||= (
|
219
|
-
|
264
|
+
BestBoy::MonthReport.where(owner_type: current_owner_type).where('event_source IS NOT NULL').order(:event_source).uniq.pluck(:event_source)
|
220
265
|
)
|
221
266
|
end
|
222
267
|
|
268
|
+
def available_event_sources?
|
269
|
+
available_event_sources.first.present?
|
270
|
+
end
|
271
|
+
|
223
272
|
def available_years
|
224
|
-
@available_years = (
|
273
|
+
@available_years = (BestBoy::MonthReport.where(owner_type: current_owner_type, event_source: nil).order(:created_at).first.created_at.to_date.year..Time.zone.now.year).map{ |year| year.to_s } rescue [Time.zone.now.year]
|
225
274
|
end
|
226
275
|
|
227
276
|
def available_owner_types
|
228
|
-
@available_owner_types ||=
|
277
|
+
@available_owner_types ||= BestBoy::MonthReport.where(event_source: nil).order(:owner_type).uniq.pluck(:owner_type)
|
229
278
|
end
|
230
279
|
|
231
280
|
def detail_count
|
@@ -254,4 +303,4 @@ module BestBoy
|
|
254
303
|
end
|
255
304
|
|
256
305
|
end
|
257
|
-
end
|
306
|
+
end
|