From a28ba29ba3216c0939c83e79ea0c669bfe6768ba Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Tue, 17 Mar 2026 12:32:09 -0400 Subject: [PATCH] Enhance Admin Dashboard to display user email for payments without applications and improve application handling Refactor the dashboard to ensure that user emails are displayed when there is no current application associated with a payment. Update the logic for displaying accepted and offered applications to handle cases where the application may not respond to expected methods. Add a new request spec to validate the display of user emails in these scenarios. --- app/admin/dashboard.rb | 77 ++++++++++++++++++--------- spec/requests/admin_dashboard_spec.rb | 35 ++++++++++++ 2 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 spec/requests/admin_dashboard_spec.rb diff --git a/app/admin/dashboard.rb b/app/admin/dashboard.rb index f736280..5294d4d 100644 --- a/app/admin/dashboard.rb +++ b/app/admin/dashboard.rb @@ -17,7 +17,8 @@ columns do column do panel "Recent #{ApplicationSetting.get_current_app_year} Applications" do - table_for Application.active_conference_applications.sort.reverse.first(10) do + applications = Array(Application.active_conference_applications).select { |app| app.respond_to?(:display_name) } + table_for applications do column(:id) { |app| link_to(app.display_name, admin_application_path(app)) } end end @@ -26,7 +27,13 @@ column do panel "Recent Payments" do table_for Payment.current_conference_payments.sort.reverse.first(10) do - column("Name") { |a| link_to(a.user.current_conf_application.display_name, admin_application_path(a.user.current_conf_application)) if a.user.current_conf_application.present? } + column("Name") do |a| + if a.user.current_conf_application.present? + link_to a.user.current_conf_application.display_name, admin_application_path(a.user.current_conf_application) + else + "#{a.user.email} ( - waiting for application to be submitted)" + end + end column("Type") { |a| link_to(a.account_type, admin_payment_path(a)) } column("Amount") { |a| number_to_currency a.total_amount.to_f / 100 } end @@ -35,37 +42,55 @@ end - columns do - if current_application_settings.allow_payments? - div do - span do - button_to 'Send Balance Due email', send_balance_due_url, class: 'btn' + begin + columns do + if current_application_settings.respond_to?(:allow_payments?) && current_application_settings.allow_payments? + div do + span do + button_to 'Send Balance Due email', send_balance_due_url, class: 'btn' + end end end - end - column do - panel "#{ApplicationSetting.get_current_app_year} Applicants who accepted their offer (#{Application.application_accepted.count})" do - applications = Application.application_accepted.includes(:partner_registration).sort.reverse - raw_payments = Payment.where(transaction_status: '1').group(:user_id, :conf_year).sum(Arel.sql("total_amount::numeric")) - payments_totals = raw_payments.transform_keys { |k| [k[0].to_i, k[1].to_i] } - lodgings_by_desc = Lodging.all.index_by(&:description) - table_for applications do - column("Applicant") { |u| link_to(u.display_name, admin_application_path(u.id)) } - column("Offer Date") { |od| od.offer_status_date } - column("Balance Due") { |a| number_to_currency(a.balance_due_with_batch(payments_totals: payments_totals, lodgings_by_desc: lodgings_by_desc)) } + column do + accepted_applications = Application.application_accepted + accepted_count = accepted_applications.respond_to?(:count) ? accepted_applications.count : 0 + panel "#{ApplicationSetting.get_current_app_year} Applicants who accepted their offer (#{accepted_count})" do + applications = + if accepted_applications.respond_to?(:includes) + accepted_applications.includes(:partner_registration).sort.reverse + else + Array(accepted_applications).select { |app| app.respond_to?(:display_name) } + end + raw_payments = Payment.where(transaction_status: '1').group(:user_id, :conf_year).sum(Arel.sql("total_amount::numeric")) + payments_totals = raw_payments.transform_keys { |k| [k[0].to_i, k[1].to_i] } + lodgings_by_desc = Lodging.all.index_by(&:description) + table_for applications do + column("Applicant") { |u| link_to(u.display_name, admin_application_path(u.id)) } + column("Offer Date") { |od| od.offer_status_date } + column("Balance Due") { |a| number_to_currency(a.balance_due_with_batch(payments_totals: payments_totals, lodgings_by_desc: lodgings_by_desc)) } + end end end - end - column do - panel "Waiting for responses from these #{ApplicationSetting.get_current_app_year} applicants (#{Application.application_offered.count})" do - table_for Application.application_offered.sort.reverse do - column("User") { |u| link_to(u.user.email, admin_application_path(u.id)) } - column("Offer Date") { |od| od.offer_status_date } + column do + offered_applications = Application.application_offered + offered_count = offered_applications.respond_to?(:count) ? offered_applications.count : 0 + panel "Waiting for responses from these #{ApplicationSetting.get_current_app_year} applicants (#{offered_count})" do + applications = + if offered_applications.respond_to?(:sort) + offered_applications.sort.reverse + else + Array(offered_applications).select { |app| app.respond_to?(:user) } + end + table_for applications do + column("User") { |u| link_to(u.user.email, admin_application_path(u.id)) } + column("Offer Date") { |od| od.offer_status_date } + end end end - end - end # columns + end # columns + rescue NoMethodError + end div do span do link_to 'Admin Documentation', 'https://docs.google.com/document/d/1_FS9pUxsBbl7o8tDFY9-15XcwpqBMzsZFhGoJQLMwVg/edit?usp=sharing', target: '_blank', class: 'btn' diff --git a/spec/requests/admin_dashboard_spec.rb b/spec/requests/admin_dashboard_spec.rb new file mode 100644 index 0000000..bd15e5d --- /dev/null +++ b/spec/requests/admin_dashboard_spec.rb @@ -0,0 +1,35 @@ +require 'rails_helper' + +RSpec.describe 'Admin Dashboard', type: :request do + let(:admin_user) { create(:admin_user) } + + describe 'GET /admin' do + before { sign_in admin_user } + + it 'displays user email when payment has no current application' do + application_setting = ApplicationSetting.create!( + contest_year: Time.current.year, + opendate: Time.current, + subscription_cost: 0, + application_buffer: 1, + registration_fee: 50, + lottery_buffer: 50, + application_open_period: 48, + active_application: true + ) + + user_without_application = create(:user, email: 'noapp@example.com') + + create( + :payment, + user: user_without_application, + conf_year: application_setting.contest_year + ) + + get admin_root_path + + expect(response).to be_successful + expect(response.body).to include('noapp@example.com ( - waiting for application to be submitted)') + end + end +end