Skip to content

Commit a070fb7

Browse files
committedOct 21, 2019
Add monthly activity report.
1 parent 2c5a53c commit a070fb7

13 files changed

+163
-15
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Admin
2+
class MonthlyActivitiesController < BaseController
3+
def index
4+
@monthly_activities = MonthlyActivity.all
5+
end
6+
end
7+
end

‎app/models/monthly_activity.rb

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class MonthlyActivity < ApplicationRecord
2+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<h1>Activity</h1>
2+
3+
<table class="table monthly-adjustments">
4+
<thead>
5+
<tr>
6+
<th></th>
7+
<th class="left-lined" colspan="2">Activity</th>
8+
<th class="left-lined" colspan="3">Members</th>
9+
</tr>
10+
<tr>
11+
<th>Month</th>
12+
<th class="left-lined">Loans</th>
13+
<th>Members</th>
14+
<th class="left-lined">New</th>
15+
<th>Pending</th>
16+
</tr>
17+
</thead>
18+
<tbody>
19+
<% @monthly_activities.each do |ma| %>
20+
<tr>
21+
<td><%= Date::MONTHNAMES[ma.month] %> <%= ma.year %></td>
22+
<td class="left-lined"><%= ma.loans_count %></td>
23+
<td class="left-lined"><%= ma.active_members_count %></td>
24+
<td class="left-lined"><%= ma.new_members_count %></td>
25+
<td class="left-lined"><%= ma.pending_members_count %></td>
26+
</tr>
27+
<% end %>
28+
<tfoot>
29+
<tr>
30+
<td>Total</td>
31+
<td class="left-lined"><%= @monthly_activities.sum(&:loans_count) %></td>
32+
<td class="left-lined"><%= @monthly_activities.sum(&:active_members_count) %></td>
33+
<td class="left-lined"><%= @monthly_activities.sum(&:new_members_count) %></td>
34+
<td class="left-lined"><%= @monthly_activities.sum(&:pending_members_count) %></td>
35+
</tr>
36+
</tfoot>
37+
</table>

‎app/views/layouts/admin.html.erb

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
<li class="nav-item">
3535
<span class="nav-category">Reports</span>
3636
<ul class="nav">
37+
<li class="nav-item"><%= link_to "Activity", admin_monthly_activities_path %></li>
3738
<li class="nav-item"><%= link_to "Member Requests", admin_member_requests_path %></li>
3839
<li class="nav-item"><%= link_to "Money", admin_monthly_adjustments_path %></li>
3940
<li class="nav-item"><%= link_to "Volunteer Shifts", admin_shifts_path %></li>
@@ -76,6 +77,7 @@
7677
Reports <i class="icon icon-caret"></i>
7778
</a>
7879
<ul class="menu">
80+
<li class="menu-item"><%= link_to "Activity", admin_monthly_activities_path %></li>
7981
<li class="menu-item"><%= link_to "Member Requests", admin_member_requests_path %></li>
8082
<li class="menu-item"><%= link_to "Money", admin_monthly_adjustments_path %></li>
8183
<li class="menu-item"><%= link_to "Volunteer Shifts", admin_shifts_path %></li>

‎config/routes.rb

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
end
4949
resources :member_requests, only: :index
5050
resources :monthly_adjustments, only: :index
51+
resources :monthly_activities, only: :index
5152

5253
post "search", to: "searches#create"
5354
get "search", to: "searches#show"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class CreateMonthlyActivities < ActiveRecord::Migration[6.0]
2+
def change
3+
create_view :monthly_activities
4+
end
5+
end

‎db/schema.rb

+36-15
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema.define(version: 2019_09_25_030512) do
13+
ActiveRecord::Schema.define(version: 2019_10_21_005121) do
1414

1515
# These are extensions that must be enabled in order to support this database
1616
enable_extension "plpgsql"
@@ -237,20 +237,6 @@
237237
add_foreign_key "taggings", "items"
238238
add_foreign_key "taggings", "tags"
239239

240-
create_view "monthly_adjustments", sql_definition: <<-SQL
241-
SELECT (date_part('year'::text, adjustments.created_at))::integer AS year,
242-
(date_part('month'::text, adjustments.created_at))::integer AS month,
243-
count(*) FILTER (WHERE (adjustments.kind = 'membership'::adjustment_kind)) AS membership_count,
244-
count(*) FILTER (WHERE (adjustments.kind = 'fine'::adjustment_kind)) AS fine_count,
245-
sum((- adjustments.amount_cents)) FILTER (WHERE (adjustments.kind = 'fine'::adjustment_kind)) AS fine_total_cents,
246-
sum((- adjustments.amount_cents)) FILTER (WHERE (adjustments.kind = 'membership'::adjustment_kind)) AS membership_total_cents,
247-
sum(adjustments.amount_cents) FILTER (WHERE (adjustments.kind = 'payment'::adjustment_kind)) AS payment_total_cents,
248-
sum(adjustments.amount_cents) FILTER (WHERE ((adjustments.kind = 'payment'::adjustment_kind) AND (adjustments.payment_source = 'square'::adjustment_source))) AS square_total_cents,
249-
sum(adjustments.amount_cents) FILTER (WHERE ((adjustments.kind = 'payment'::adjustment_kind) AND (adjustments.payment_source = 'cash'::adjustment_source))) AS cash_total_cents,
250-
sum(adjustments.amount_cents) FILTER (WHERE ((adjustments.kind = 'payment'::adjustment_kind) AND (adjustments.payment_source = 'forgiveness'::adjustment_source))) AS forgiveness_total_cents
251-
FROM adjustments
252-
GROUP BY ((date_part('year'::text, adjustments.created_at))::integer), ((date_part('month'::text, adjustments.created_at))::integer);
253-
SQL
254240
create_view "loan_summaries", sql_definition: <<-SQL
255241
SELECT loans.item_id,
256242
loans.member_id,
@@ -266,4 +252,39 @@
266252
FROM loans
267253
GROUP BY loans.item_id, loans.member_id, COALESCE(loans.initial_loan_id, loans.id);
268254
SQL
255+
create_view "monthly_adjustments", sql_definition: <<-SQL
256+
SELECT (date_part('year'::text, adjustments.created_at))::integer AS year,
257+
(date_part('month'::text, adjustments.created_at))::integer AS month,
258+
count(*) FILTER (WHERE (adjustments.kind = 'membership'::adjustment_kind)) AS membership_count,
259+
count(*) FILTER (WHERE (adjustments.kind = 'fine'::adjustment_kind)) AS fine_count,
260+
sum((- adjustments.amount_cents)) FILTER (WHERE (adjustments.kind = 'fine'::adjustment_kind)) AS fine_total_cents,
261+
sum((- adjustments.amount_cents)) FILTER (WHERE (adjustments.kind = 'membership'::adjustment_kind)) AS membership_total_cents,
262+
sum(adjustments.amount_cents) FILTER (WHERE (adjustments.kind = 'payment'::adjustment_kind)) AS payment_total_cents,
263+
sum(adjustments.amount_cents) FILTER (WHERE ((adjustments.kind = 'payment'::adjustment_kind) AND (adjustments.payment_source = 'square'::adjustment_source))) AS square_total_cents,
264+
sum(adjustments.amount_cents) FILTER (WHERE ((adjustments.kind = 'payment'::adjustment_kind) AND (adjustments.payment_source = 'cash'::adjustment_source))) AS cash_total_cents,
265+
sum(adjustments.amount_cents) FILTER (WHERE ((adjustments.kind = 'payment'::adjustment_kind) AND (adjustments.payment_source = 'forgiveness'::adjustment_source))) AS forgiveness_total_cents
266+
FROM adjustments
267+
GROUP BY ((date_part('year'::text, adjustments.created_at))::integer), ((date_part('month'::text, adjustments.created_at))::integer);
268+
SQL
269+
create_view "monthly_activities", sql_definition: <<-SQL
270+
WITH dates AS (
271+
SELECT min(date_trunc('month'::text, loans.created_at)) AS startm,
272+
max(date_trunc('month'::text, loans.created_at)) AS endm
273+
FROM loans
274+
), months AS (
275+
SELECT generate_series(dates.startm, dates.endm, '1 mon'::interval) AS month
276+
FROM dates
277+
)
278+
SELECT (date_part('year'::text, months.month))::integer AS year,
279+
(date_part('month'::text, months.month))::integer AS month,
280+
count(DISTINCT l.id) AS loans_count,
281+
count(DISTINCT l.member_id) AS active_members_count,
282+
count(DISTINCT m.id) FILTER (WHERE (m.status = 0)) AS pending_members_count,
283+
count(DISTINCT m.id) FILTER (WHERE (m.status = 1)) AS new_members_count
284+
FROM ((months
285+
LEFT JOIN loans l ON ((date_trunc('month'::text, l.created_at) = months.month)))
286+
LEFT JOIN members m ON ((date_trunc('month'::text, m.created_at) = months.month)))
287+
GROUP BY months.month
288+
ORDER BY months.month;
289+
SQL
269290
end

‎db/views/monthly_activities_v01.sql

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
WITH dates AS
2+
(SELECT min(date_trunc('month', created_at)) AS startm,
3+
max(date_trunc('month', created_at)) AS endm FROM loans),
4+
months AS
5+
(SELECT generate_series(startm, endm, '1 month') AS month FROM dates)
6+
SELECT extract(YEAR FROM months.month)::integer AS year,
7+
extract(MONTH FROM months.month)::integer AS month,
8+
count(DISTINCT l.id) AS loans_count,
9+
count(DISTINCT l.member_id) AS active_members_count,
10+
count(DISTINCT m.id) filter (WHERE m.status = 0) AS pending_members_count,
11+
count(DISTINCT m.id) filter (WHERE m.status = 1) AS new_members_count
12+
FROM months
13+
LEFT OUTER JOIN loans l ON date_trunc('month', l.created_at) = months.month
14+
LEFT JOIN members m ON date_trunc('month', m.created_at) = months.month
15+
GROUP BY months.month
16+
ORDER BY months.month ASC;

‎script/install-hooks

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
3+
ln -s script/pre-commit .git/hooks/pre-commit

‎script/pre-commit

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
3+
script/pre-commit-format-javascript
4+
script/pre-commit-format-ruby

‎script/pre-commit-format-javascript

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/sh
2+
# ./.git/hooks/pre-commit-format-javascript
3+
# Assumption: npm/yarn has installed the prettier package
4+
# Based on the bash script prescribed at https://prettier.io/docs/en/precommit.html#option-5-bash-script
5+
6+
jsfiles=$(git diff --cached --name-only --diff-filter=ACM "*.js" "*.jsx" | tr '\n' ' ')
7+
[ -z "$jsfiles" ] && exit 0
8+
9+
# Prettify all staged .js files
10+
echo "💅 Automatically formatting staged Javascript files using prettier ($(echo $jsfiles | wc -w | awk '{print $1}') total)"
11+
echo "$jsfiles" | xargs ./node_modules/.bin/prettier --write --loglevel=error
12+
13+
# Add back the modified/prettified files to staging
14+
echo "$jsfiles" | xargs git add
15+
16+
exit 0

‎script/pre-commit-format-ruby

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/sh
2+
# ./.git/hooks/pre-commit-format-ruby
3+
# Assumption: bundler has installed the standard gem
4+
# Based on the bash script prescribed at https://prettier.io/docs/en/precommit.html#option-5-bash-script
5+
6+
rubyfiles=$(git diff --cached --name-only --diff-filter=ACM "*.rb" "*.rake" "Gemfile" "Rakefile" | tr '\n' ' ')
7+
[ -z "$rubyfiles" ] && exit 0
8+
9+
# Standardize all ruby files
10+
echo "💅 Automatically formatting staged Ruby files using standardrb ($(echo $rubyfiles | wc -w | awk '{print $1}') total)"
11+
echo "$rubyfiles" | xargs bundle exec standardrb --fix
12+
13+
# Add back the modified/prettified files to staging
14+
echo "$rubyfiles" | xargs git add
15+
16+
exit 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require "test_helper"
2+
3+
class MonthlyActivitiesControllerTest < ActionDispatch::IntegrationTest
4+
include Devise::Test::IntegrationHelpers
5+
6+
setup do
7+
@user = users(:admin)
8+
sign_in @user
9+
end
10+
11+
test "should get index" do
12+
create(:member, created_at: 2.months.ago)
13+
create(:loan, created_at: 1.months.ago)
14+
15+
get admin_monthly_activities_url
16+
assert_response :success
17+
end
18+
end

0 commit comments

Comments
 (0)
Please sign in to comment.