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.
- 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
|