Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transaction stats in admin #8124

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions app/controllers/admin/statistics_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
##
# Controller to render admin stats
#
class Admin::StatisticsController < AdminController
def index
@public_body_count = PublicBody.count

@info_request_count = InfoRequest.count
@outgoing_message_count = OutgoingMessage.count
@incoming_message_count = IncomingMessage.count

@user_count = User.count
@track_thing_count = TrackThing.count

@comment_count = Comment.count
@request_by_state = InfoRequest.group('described_state').count
@tracks_by_type = TrackThing.group('track_type').count

@monthly_transactions = Statistics::MonthlyTransactions.new
end
end
135 changes: 135 additions & 0 deletions app/models/statistics/monthly_transactions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
class Statistics::MonthlyTransactions

Check warning on line 1 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Missing top-level documentation comment for `class Statistics::MonthlyTransactions`. Raw Output: app/models/statistics/monthly_transactions.rb:1:1: C: Style/Documentation: Missing top-level documentation comment for `class Statistics::MonthlyTransactions`.
include Enumerable

def initialize(start_year: nil, start_month: nil, end_year: nil, end_month: nil)

Check warning on line 4 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Line is too long. [82/80] (https://rubystyle.guide#max-line-length) Raw Output: app/models/statistics/monthly_transactions.rb:4:81: C: Layout/LineLength: Line is too long. [82/80] (https://rubystyle.guide#max-line-length)
@start_year = (start_year || InfoRequest.first.created_at.year).to_i
@start_month = (start_month || 1).to_i
@end_year = (end_year || Time.zone.now.year).to_i
@end_month = (end_month || Time.zone.now.month).to_i
end

def to_a
each_month.unshift(headers)
end

def each
yield(headers)

month_starts.each do |month_start|
yield(monthly_transactions(month_start))
end
end

def headers
['Period',
'Requests sent',
'Pro requests sent',
'Visible comments',
'Track this request email signups',
'Comments on own requests',
'Follow up messages sent',
'Confirmed users',
'Confirmed pro users',
'Request classifications',
'Public body change requests',
'Widget votes',
'Total tracks']
end

protected

attr_reader :start_year
attr_reader :start_month
attr_reader :end_year
attr_reader :end_month

private

def month_starts
(Date.new(start_year, start_month)..Date.new(end_year, end_month)).
select { |d| d.day == 1 }
end

def monthly_transactions(month_start)
month_end = month_start.end_of_month
period = "#{month_start}-#{month_end}"

date_conditions = ['created_at >= ?
AND created_at < ?',
month_start, month_end+1]

Check warning on line 59 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators) Raw Output: app/models/statistics/monthly_transactions.rb:59:46: C: Layout/SpaceAroundOperators: Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators)

request_count = InfoRequest.where(date_conditions).count
pro_request_count = InfoRequest.pro.where('info_requests.created_at >= ?
AND info_requests.created_at < ?',
month_start, month_end+1).count

Check warning on line 64 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators) Raw Output: app/models/statistics/monthly_transactions.rb:64:69: C: Layout/SpaceAroundOperators: Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators)
visible_comments_count = Comment.visible.where('comments.created_at >= ?
AND comments.created_at < ?',

Check warning on line 66 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Line is too long. [81/80] (https://rubystyle.guide#max-line-length) Raw Output: app/models/statistics/monthly_transactions.rb:66:81: C: Layout/LineLength: Line is too long. [81/80] (https://rubystyle.guide#max-line-length)
month_start, month_end+1).count

Check warning on line 67 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators) Raw Output: app/models/statistics/monthly_transactions.rb:67:75: C: Layout/SpaceAroundOperators: Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators)

Check warning on line 67 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Line is too long. [83/80] (https://rubystyle.guide#max-line-length) Raw Output: app/models/statistics/monthly_transactions.rb:67:81: C: Layout/LineLength: Line is too long. [83/80] (https://rubystyle.guide#max-line-length)

track_conditions = ['track_type = ?
AND track_medium = ?
AND created_at >= ?
AND created_at < ?',
'request_updates',
'email_daily',
month_start,
month_end + 1]
email_request_track_count = TrackThing.where(track_conditions).count

comment_on_own_request_conditions = ['comments.user_id = info_requests.user_id

Check warning on line 79 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Line is too long. [82/80] (https://rubystyle.guide#max-line-length) Raw Output: app/models/statistics/monthly_transactions.rb:79:81: C: Layout/LineLength: Line is too long. [82/80] (https://rubystyle.guide#max-line-length)
AND comments.created_at >= ?
AND comments.created_at < ?',
month_start, month_end+1]

Check warning on line 82 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators) Raw Output: app/models/statistics/monthly_transactions.rb:82:64: C: Layout/SpaceAroundOperators: Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators)

comment_on_own_request_count =
Comment.
includes(:info_request).
references(:info_request).
where(comment_on_own_request_conditions).
count

followup_date_range =
['created_at >= ? AND created_at < ?', month_start, month_end + 1]

follow_up_count =
OutgoingMessage.followup.is_searchable.where(followup_date_range).count

confirmed_users_count =
User.active.
where(email_confirmed: true).
where(date_conditions).
count

pro_confirmed_users_count =
User.pro.active.
where(email_confirmed: true).
where('users.created_at >= ?
AND users.created_at < ?',
month_start, month_end+1).

Check warning on line 108 in app/models/statistics/monthly_transactions.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators) Raw Output: app/models/statistics/monthly_transactions.rb:108:40: C: Layout/SpaceAroundOperators: Surrounding space missing for operator `+`. (https://rubystyle.guide#spaces-operators)
count

request_classifications_count =
RequestClassification.where(date_conditions).count

public_body_change_requests_count =
PublicBodyChangeRequest.where(date_conditions).count

widget_votes_count = WidgetVote.where(date_conditions).count

total_tracks_count = TrackThing.where(date_conditions).count

[period,
request_count,
pro_request_count,
visible_comments_count,
email_request_track_count,
comment_on_own_request_count,
follow_up_count,
confirmed_users_count,
pro_confirmed_users_count,
request_classifications_count,
public_body_change_requests_count,
widget_votes_count,
total_tracks_count]
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,27 @@
</div>
</div>
</div>

<div class="row">
<div class="span12">
<h2>Transactions</h2>

<table class="table table-condensed table-hover">
<% @monthly_transactions.each_with_index do |row, index| %>
<tr>
<% if index.zero? %>
<% row.each do |cell| %>
<th style="text-orientation: sideways; writing-mode: vertical-lr;">
<%= cell %>
</th>
<% end %>
<% else %>
<% row.each do |cell| %>
<%= tag.td cell, class: { muted: cell.to_i.zero? } %>
<% end %>
<% end %>
</tr>
<% end %>
</table>
</div>
</div>
2 changes: 1 addition & 1 deletion app/views/admin_general/_admin_navbar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<ul class="dropdown-menu" role="menu">
<li><%= link_to 'Summary', admin_general_index_path %></li>
<li><%= link_to 'Timeline', admin_timeline_path %></li>
<li><%= link_to 'Stats', admin_stats_path %></li>
<li><%= link_to 'Stats', admin_statistics_path %></li>
<li><%= link_to 'Debug', admin_debug_path %></li>
</ul>
</li>
Expand Down
9 changes: 6 additions & 3 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -626,9 +626,12 @@ def matches?(request)
match '/admin/debug' => 'admin_general#debug',
:as => :admin_debug,
:via => :get
match '/admin/stats' => 'admin_general#stats',
:as => :admin_stats,
:via => :get
####

#### Admin::Statistics controller
namespace :admin do
resources :statistics, only: [:index]
end
####

#### AdminRequest controller
Expand Down
110 changes: 8 additions & 102 deletions lib/tasks/stats.rake
Original file line number Diff line number Diff line change
Expand Up @@ -4,110 +4,16 @@ namespace :stats do
task show: :environment do
example = 'rake stats:show START_YEAR=2009 [START_MONTH=3 END_YEAR=2012 END_MONTH=10]'
check_for_env_vars(['START_YEAR'], example)
start_year = (ENV['START_YEAR']).to_i
start_month = (ENV['START_MONTH'] || 1).to_i
end_year = (ENV['END_YEAR'] || Time.zone.now.year).to_i
end_month = (ENV['END_MONTH'] || Time.zone.now.month).to_i

month_starts = (Date.new(start_year, start_month)..Date.new(end_year, end_month)).select { |d| d.day == 1 }

headers = ['Period',
'Requests sent',
'Pro requests sent',
'Visible comments',
'Track this request email signups',
'Comments on own requests',
'Follow up messages sent',
'Confirmed users',
'Confirmed pro users',
'Request classifications',
'Public body change requests',
'Widget votes',
'Total tracks']
puts headers.join("\t")

month_starts.each do |month_start|
month_end = month_start.end_of_month
period = "#{month_start}-#{month_end}"

date_conditions = ['created_at >= ?
AND created_at < ?',
month_start, month_end+1]

request_count = InfoRequest.where(date_conditions).count
pro_request_count = InfoRequest.pro.where('info_requests.created_at >= ?
AND info_requests.created_at < ?',
month_start, month_end+1).count
visible_comments_count = Comment.visible.where('comments.created_at >= ?
AND comments.created_at < ?',
month_start, month_end+1).count

track_conditions = ['track_type = ?
AND track_medium = ?
AND created_at >= ?
AND created_at < ?',
'request_updates',
'email_daily',
month_start,
month_end + 1]
email_request_track_count = TrackThing.where(track_conditions).count

comment_on_own_request_conditions = ['comments.user_id = info_requests.user_id
AND comments.created_at >= ?
AND comments.created_at < ?',
month_start, month_end+1]

comment_on_own_request_count =
Comment.
includes(:info_request).
references(:info_request).
where(comment_on_own_request_conditions).
count

followup_date_range =
['created_at >= ? AND created_at < ?', month_start, month_end + 1]

follow_up_count =
OutgoingMessage.followup.is_searchable.where(followup_date_range).count

confirmed_users_count =
User.active.
where(email_confirmed: true).
where(date_conditions).
count

pro_confirmed_users_count =
User.pro.active.
where(email_confirmed: true).
where('users.created_at >= ?
AND users.created_at < ?',
month_start, month_end+1).
count

request_classifications_count =
RequestClassification.where(date_conditions).count

public_body_change_requests_count =
PublicBodyChangeRequest.where(date_conditions).count

widget_votes_count = WidgetVote.where(date_conditions).count

total_tracks_count = TrackThing.where(date_conditions).count

stats = Statistics::MonthlyTransactions.new(
start_year: (ENV['START_YEAR']).to_i,
start_month: (ENV['START_MONTH'] || 1).to_i,
end_year: (ENV['END_YEAR'] || Time.zone.now.year).to_i,
end_month: (ENV['END_MONTH'] || Time.zone.now.month).to_i
)

puts [period,
request_count,
pro_request_count,
visible_comments_count,
email_request_track_count,
comment_on_own_request_count,
follow_up_count,
confirmed_users_count,
pro_confirmed_users_count,
request_classifications_count,
public_body_change_requests_count,
widget_votes_count,
total_tracks_count].join("\t")
stats.each do |row|
puts row.join("\t")
end
end

Expand Down
69 changes: 69 additions & 0 deletions spec/controllers/admin/statistics_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require 'spec_helper'

RSpec.describe Admin::StatisticsController do
describe 'GET #stats' do
it 'assigns the number of public bodies to the view' do
get :index
expect(assigns[:public_body_count]).to eq PublicBody.count
end

it 'assigns the number of requests to the view' do
get :index
expect(assigns[:info_request_count]).to eq InfoRequest.count
end

it 'assigns the number of users to the view' do
get :index
expect(assigns[:user_count]).to eq User.count
end

it 'assigns the number of tracks to the view' do
get :index
expect(assigns[:track_thing_count]).to eq TrackThing.count
end

it 'assigns the number of comments to the view' do
get :index
expect(assigns[:comment_count]).to eq Comment.count
end

it 'assigns a Hash with grouped counts of requests by state to the view' do
InfoRequest.destroy_all

8.times { FactoryBot.create(:successful_request) }
2.times { FactoryBot.create(:info_request) }
FactoryBot.create(:attention_requested_request)

get :index
expect(assigns[:request_by_state]).
to eq({ 'successful' => 8,
'waiting_response' => 2,
'attention_requested' => 1 })
end

it 'assigns a Hash with grouped counts of tracks by type to the view' do
TrackThing.destroy_all

FactoryBot.create(:search_track)
2.times { FactoryBot.create(:public_body_track) }
4.times { FactoryBot.create(:request_update_track) }
6.times { FactoryBot.create(:successful_request_track) }
7.times { FactoryBot.create(:new_request_track) }

get :index
expect(assigns[:tracks_by_type]).
to eq({
"search_query" => 1,
"public_body_updates" => 2,
"request_updates" => 4,
"all_successful_requests" => 6,
"all_new_requests" => 7 })
end

it 'assigns the monthly transactions' do
get :index
expect(assigns[:monthly_transactions]).
to be_a(Statistics::MonthlyTransactions)
end
end
end
Loading
Loading