diff --git a/app/controllers/admin/reports/monthly_activities_controller.rb b/app/controllers/admin/reports/monthly_activities_controller.rb
index 9fb4ea37a..cc593cd60 100644
--- a/app/controllers/admin/reports/monthly_activities_controller.rb
+++ b/app/controllers/admin/reports/monthly_activities_controller.rb
@@ -2,32 +2,43 @@ module Admin
module Reports
class MonthlyActivitiesController < BaseController
def index
- fetch_monthly_activities
+ @monthly_activities = fetch_activities
end
- def fetch_monthly_activities
- @monthly_activities = {}
+ private
- # TODO: load_async in Rails 7
- appointments = MonthlyAppointment.all
- loans = MonthlyLoan.all
- members = MonthlyMember.all
- renewals = MonthlyRenewal.all
+ def fetch_activities
+ records = [*MonthlyAppointment.all, *MonthlyLoan.all, *MonthlyMember.all, *MonthlyRenewal.all]
- assign_monthlies(appointments, %i[appointments_count completed_appointments_count])
- assign_monthlies(loans, %i[loans_count active_members_count])
- assign_monthlies(members, %i[new_members_count pending_members_count])
- assign_monthlies(renewals, %i[renewals_count])
+ records.group_by(&:year).each_with_object([]) do |(year, records_for_year), grouped_year|
+ monthly_values = records_for_year.group_by(&:month).each_with_object([]) do |(month, records_for_month), grouped_month|
+ grouped_month << [month, records_to_amount_hash(records_for_month)]
+ end
- @monthly_activities = @monthly_activities.sort.to_h
+ grouped_year << [year, monthly_values.sort_by(&:first)]
+ end.sort_by(&:first)
end
- def assign_monthlies(records, columns)
- records.each do |record|
- key = "#{record.year}-#{record.month.to_s.rjust(2, "0")}"
- monthly = @monthly_activities[key] ||= Hash.new(0)
+ def columns_for_record(record)
+ case record
+ when MonthlyAppointment
+ %i[appointments_count completed_appointments_count]
+ when MonthlyLoan
+ %i[loans_count active_members_count]
+ when MonthlyMember
+ %i[new_members_count pending_members_count]
+ when MonthlyRenewal
+ %i[renewals_count]
+ else
+ raise "Unknow record type: #{record}"
+ end
+ end
- columns.each { |column| monthly[column] = record[column] }
+ def records_to_amount_hash(records)
+ records.each_with_object(Hash.new(0)) do |record, hash|
+ columns_for_record(record).each do |column|
+ hash[column] = record[column]
+ end
end
end
end
diff --git a/app/views/admin/reports/monthly_activities/index.html.erb b/app/views/admin/reports/monthly_activities/index.html.erb
index 83b81e43e..c26e56b7e 100644
--- a/app/views/admin/reports/monthly_activities/index.html.erb
+++ b/app/views/admin/reports/monthly_activities/index.html.erb
@@ -2,49 +2,83 @@
<%= index_header "Activity" %>
<% end %>
-
-
-
- |
- Activity |
- Members |
- Appointments |
-
-
- Month |
- Loans |
- Renewals |
- Members |
- New |
- Pending |
- Scheduled |
- Completed |
-
-
-
- <% @monthly_activities.each do |date, activities| %>
-
- <% year, month = date.split("-") %>
- <%= Date::MONTHNAMES[month.to_i] %> <%= year %> |
- <%= activities[:loans_count] %> |
- <%= activities[:renewals_count] %> |
- <%= activities[:active_members_count] %> |
- <%= activities[:new_members_count] %> |
- <%= activities[:pending_members_count] %> |
- <%= activities[:appointments_count] %> |
- <%= activities[:completed_appointments_count] %> |
-
- <% end %>
-
-
- Total |
- <%= @monthly_activities.values.sum { |a| a[:loans_count] } %> |
- <%= @monthly_activities.values.sum { |a| a[:renewals_count] } %> |
- <%= @monthly_activities.values.sum { |a| a[:active_members_count] } %> |
- <%= @monthly_activities.values.sum { |a| a[:new_members_count] } %> |
- <%= @monthly_activities.values.sum { |a| a[:pending_members_count] } %> |
- <%= @monthly_activities.values.sum { |a| a[:appointments_count] } %> |
- <%= @monthly_activities.values.sum { |a| a[:completed_appointments_count] } %> |
-
-
-
+<% @monthly_activities.each do |(year, activities_by_month)| %>
+
+
<%= year -%>
+
+
+
+ |
+ Activity |
+ Members |
+ Appointments |
+
+
+ Month |
+ Loans |
+ Renewals |
+ Members |
+ New |
+ Pending |
+ Scheduled |
+ Completed |
+
+
+
+ <% activities_by_month.each do |month, activities| %>
+
+ <%= Date::MONTHNAMES[month.to_i] %> |
+ ">
+ <%= activities[:loans_count] %>
+ |
+ ">
+ <%= activities[:renewals_count] %>
+ |
+ ">
+ <%= activities[:active_members_count] %>
+ |
+ ">
+ <%= activities[:new_members_count] %>
+ |
+ ">
+ <%= activities[:pending_members_count] %>
+ |
+ ">
+ <%= activities[:appointments_count] %>
+ |
+ ">
+ <%= activities[:completed_appointments_count] %>
+ |
+
+ <% end %>
+
+
+ Total |
+ ">
+ <%= activities_by_month.map(&:second).sum { |a| a[:loans_count] } %>
+ |
+ ">
+ <%= activities_by_month.map(&:second).sum { |a| a[:renewals_count] } %>
+ |
+ ">
+ <%= activities_by_month.map(&:second).sum { |a| a[:active_members_count] } %>
+ |
+ ">
+ <%= activities_by_month.map(&:second).sum { |a| a[:new_members_count] } %>
+ |
+ ">
+ <%= activities_by_month.map(&:second).sum { |a| a[:pending_members_count] } %>
+ |
+ ">
+ <%= activities_by_month.map(&:second).sum { |a| a[:appointments_count] } %>
+ |
+ ">
+ <%= activities_by_month.map(&:second).sum { |a| a[:completed_appointments_count] } %>
+ |
+
+
+
+
+
+
+<% end %>
diff --git a/test/system/admin/reports/monthly_activities_test.rb b/test/system/admin/reports/monthly_activities_test.rb
index 2837977c5..159a93020 100644
--- a/test/system/admin/reports/monthly_activities_test.rb
+++ b/test/system/admin/reports/monthly_activities_test.rb
@@ -38,100 +38,119 @@ class MonthlyActivitiesTest < ApplicationSystemTestCase
sign_in_as_admin
end
+ # Table for 2021
# ╔═══════════════╦══════════════════════════════════╦═════════════════════╦════════════════════════════╗
# ║ ║ Activity ║ Members ║ Appointments ║
# ├───────────────┼──────────────────────────────────┼─────────────────────┼────────────────────────────┤
# ║ Month ║ Loans ║ Renewals ║ Members ║ New ║ Pending ║ Scheduled ║ Completed ║
# ╠═══════════════╬═══════════╬═══════════╬══════════╬══════════╬══════════╬═══════════════╬════════════╣
- # ║ November 2021 ║ 0 ║ 0 ║ 0 ║ 1 ║ 0 ║ 0 ║ 0 ║
- # ║ December 2021 ║ 1 ║ 0 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║
- # ║ January 2022 ║ 3 ║ 1 ║ 1 ║ 2 ║ 1 ║ 2 ║ 1 ║
+ # ║ November ║ 0 ║ 0 ║ 0 ║ 1 ║ 0 ║ 0 ║ 0 ║
+ # ║ December ║ 1 ║ 0 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║
# ╠═══════════════╬═══════════╬═══════════╬══════════╬══════════╬══════════╬═══════════════╬════════════╣
- # ║ Total ║ 4 ║ 1 ║ 2 ║ 3 ║ 1 ║ 3 ║ 2 ║
+ # ║ Total ║ 1 ║ 0 ║ 1 ║ 1 ║ 0 ║ 1 ║ 1 ║
+ # ╚═══════════════╩═══════════╩═══════════╩══════════╩══════════╩══════════╩═══════════════╩════════════╝
+ # Table for 2022
+ # ╔═══════════════╦══════════════════════════════════╦═════════════════════╦════════════════════════════╗
+ # ║ ║ Activity ║ Members ║ Appointments ║
+ # ├───────────────┼──────────────────────────────────┼─────────────────────┼────────────────────────────┤
+ # ║ Month ║ Loans ║ Renewals ║ Members ║ New ║ Pending ║ Scheduled ║ Completed ║
+ # ╠═══════════════╬═══════════╬═══════════╬══════════╬══════════╬══════════╬═══════════════╬════════════╣
+ # ║ January ║ 3 ║ 1 ║ 1 ║ 2 ║ 1 ║ 2 ║ 1 ║
+ # ╠═══════════════╬═══════════╬═══════════╬══════════╬══════════╬══════════╬═══════════════╬════════════╣
+ # ║ Total ║ 3 ║ 1 ║ 1 ║ 2 ║ 1 ║ 2 ║ 1 ║
# ╚═══════════════╩═══════════╩═══════════╩══════════╩══════════╩══════════╩═══════════════╩════════════╝
test "table is populated accordingly" do
visit admin_reports_monthly_activities_url
- assert_selector ".monthly-adjustments"
- within(".monthly-adjustments") do
- # ║ ║ Activity ║ Members ║ Appointments ║
- within("thead > tr:nth-child(1)") do
- within("th:nth-child(2)") { assert_text("Activity") }
- within("th:nth-child(3)") { assert_text("Members") }
- within("th:nth-child(4)") { assert_text("Appointments") }
- end
+ assert_selector "#year-2021"
+ assert_selector "#year-2022"
+
+ # table headings
+ ["#year-2021", "#year-2022"].each do |selector|
+ within("#year-2021") do
+ within("thead > tr:nth-child(1)") do
+ within("th:nth-child(2)") { assert_text("Activity") }
+ within("th:nth-child(3)") { assert_text("Members") }
+ within("th:nth-child(4)") { assert_text("Appointments") }
+ end
- # ║ Month ║ Loans ║ Renewals ║ Members ║ New ║ Pending ║ Scheduled ║ Completed ║
- within("thead > tr:nth-child(2)") do
- within("th:nth-child(1)") { assert_text("Month") }
+ within("thead > tr:nth-child(2)") do
+ within("th:nth-child(1)") { assert_text("Month") }
- within("th:nth-child(2)") { assert_text("Loans") }
- within("th:nth-child(3)") { assert_text("Renewals") }
- within("th:nth-child(4)") { assert_text("Members") }
+ within("th:nth-child(2)") { assert_text("Loans") }
+ within("th:nth-child(3)") { assert_text("Renewals") }
+ within("th:nth-child(4)") { assert_text("Members") }
- within("th:nth-child(5)") { assert_text("New") }
- within("th:nth-child(6)") { assert_text("Pending") }
+ within("th:nth-child(5)") { assert_text("New") }
+ within("th:nth-child(6)") { assert_text("Pending") }
- within("th:nth-child(7)") { assert_text("Scheduled") }
- within("th:nth-child(8)") { assert_text("Completed") }
+ within("th:nth-child(7)") { assert_text("Scheduled") }
+ within("th:nth-child(8)") { assert_text("Completed") }
+ end
end
+ end
- # ║ November 2021 ║ 0 ║ 0 ║ 0 ║ 1 ║ 0 ║ 0 ║ 0 ║
+ within("#year-2021") do
within("tbody > tr:nth-child(1)") do
- within("td:nth-child(1)") { assert_text("November 2021") }
-
- within("td:nth-child(2)") { assert_text("0") }
- within("td:nth-child(3)") { assert_text("0") }
- within("td:nth-child(4)") { assert_text("0") }
-
- within("td:nth-child(5)") { assert_text("1") }
- within("td:nth-child(6)") { assert_text("0") }
-
- within("td:nth-child(7)") { assert_text("0") }
- within("td:nth-child(8)") { assert_text("0") }
+ within("td.month") { assert_text("November") }
+
+ within("td.loans_count-2021-11") { assert_text("0") }
+ within("td.renewals_count-2021-11") { assert_text("0") }
+ within("td.active_members_count-2021-11") { assert_text("0") }
+ within("td.new_members_count-2021-11") { assert_text("1") }
+ within("td.pending_members_count-2021-11") { assert_text("0") }
+ within("td.appointments_count-2021-11") { assert_text("0") }
+ within("td.completed_appointments_count-2021-11") { assert_text("0") }
end
- # ║ December 2021 ║ 1 ║ 0 ║ 1 ║ 0 ║ 0 ║ 1 ║ 1 ║
within("tbody > tr:nth-child(2)") do
- within("td:nth-child(1)") { assert_text("December 2021") }
-
- within("td:nth-child(2)") { assert_text("1") }
- within("td:nth-child(3)") { assert_text("0") }
- within("td:nth-child(4)") { assert_text("1") }
-
- within("td:nth-child(5)") { assert_text("0") }
- within("td:nth-child(6)") { assert_text("0") }
+ within("td.month") { assert_text("December") }
+
+ within("td.loans_count-2021-12") { assert_text("1") }
+ within("td.renewals_count-2021-12") { assert_text("0") }
+ within("td.active_members_count-2021-12") { assert_text("1") }
+ within("td.new_members_count-2021-12") { assert_text("0") }
+ within("td.pending_members_count-2021-12") { assert_text("0") }
+ within("td.appointments_count-2021-12") { assert_text("1") }
+ within("td.completed_appointments_count-2021-12") { assert_text("1") }
+ end
- within("td:nth-child(7)") { assert_text("1") }
- within("td:nth-child(8)") { assert_text("1") }
+ within("tfoot > tr") do
+ within("td.total") { assert_text("Total") }
+
+ within("td.loans_count-2021") { assert_text("1") }
+ within("td.renewals_count-2021") { assert_text("0") }
+ within("td.active_members_count-2021") { assert_text("1") }
+ within("td.new_members_count-2021") { assert_text("1") }
+ within("td.pending_members_count-2021") { assert_text("0") }
+ within("td.appointments_count-2021") { assert_text("1") }
+ within("td.completed_appointments_count-2021") { assert_text("1") }
end
+ end
- # ║ January 2022 ║ 3 ║ 1 ║ 1 ║ 2 ║ 1 ║ 2 ║ 1 ║
- within("tbody > tr:nth-child(3)") do
- within("td:nth-child(1)") { assert_text("January 2022") }
-
- within("td:nth-child(2)") { assert_text("3") }
- within("td:nth-child(3)") { assert_text("1") }
- within("td:nth-child(4)") { assert_text("1") }
- within("td:nth-child(5)") { assert_text("2") }
- within("td:nth-child(6)") { assert_text("1") }
- within("td:nth-child(7)") { assert_text("2") }
- within("td:nth-child(8)") { assert_text("1") }
+ within("#year-2022") do
+ within("tbody > tr:nth-child(1)") do
+ within("td.month") { assert_text("January") }
+
+ within("td.loans_count-2022-1") { assert_text("3") }
+ within("td.renewals_count-2022-1") { assert_text("1") }
+ within("td.active_members_count-2022-1") { assert_text("1") }
+ within("td.new_members_count-2022-1") { assert_text("2") }
+ within("td.pending_members_count-2022-1") { assert_text("1") }
+ within("td.appointments_count-2022-1") { assert_text("2") }
+ within("td.completed_appointments_count-2022-1") { assert_text("1") }
end
- # ║ Total ║ 4 ║ 1 ║ 2 ║ 3 ║ 1 ║ 3 ║ 2 ║
within("tfoot > tr") do
- within("td:nth-child(1)") { assert_text("Total") }
-
- within("td:nth-child(2)") { assert_text("4") }
- within("td:nth-child(3)") { assert_text("1") }
- within("td:nth-child(4)") { assert_text("2") }
-
- within("td:nth-child(5)") { assert_text("3") }
- within("td:nth-child(6)") { assert_text("1") }
-
- within("td:nth-child(7)") { assert_text("3") }
- within("td:nth-child(8)") { assert_text("2") }
+ within("td.total") { assert_text("Total") }
+
+ within("td.loans_count-2022") { assert_text("3") }
+ within("td.renewals_count-2022") { assert_text("1") }
+ within("td.active_members_count-2022") { assert_text("1") }
+ within("td.new_members_count-2022") { assert_text("2") }
+ within("td.pending_members_count-2022") { assert_text("1") }
+ within("td.appointments_count-2022") { assert_text("2") }
+ within("td.completed_appointments_count-2022") { assert_text("1") }
end
end
end