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

Scholarship related #737

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
22 changes: 21 additions & 1 deletion app/controllers/admin/memberships_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,29 @@ def unmake_admin
redirect_to admin_memberships_path
end

# updating scholarship status
#if requested --> approve (approve=true), revoke (approve=false)
#if approved --> revoke (approve=true), continue (approve=true)
#if not-requested --> approve
def approve_or_continue_scholarship
user = User.find(params[:id])
if user.scholarship_since?
user.scholarship_continued
else
user.scholarship_approved
end
redirect_to admin_memberships_path
end

def remove_scholarship
user = User.find(params[:id])
user.scholarship_rejected_or_revoked
redirect_to admin_memberships_path
end

private

def user_params
params.require(:user).permit(:is_scholarship)
params.require(:user)
end
end
1 change: 1 addition & 0 deletions app/controllers/members/dues_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def update
end

def scholarship_request
current_user.request_scholarship
DuesMailer.scholarship_requested(current_user, params[:reason]).deliver_now

redirect_to members_user_dues_path, notice: "Your scholarship request has been submitted"
Expand Down
14 changes: 14 additions & 0 deletions app/models/concerns/admin_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,18 @@ def unmake_admin!
self.is_admin = false
save!
end

def scholarship_approved
update_attributes!({scholarship_since: DateTime.now, scholarship_last_checkin: DateTime.now})
end

def scholarship_rejected_or_revoked
update_attributes!({requested_scholarship: nil, scholarship_since: nil, scholarship_last_checkin: nil})
end

def scholarship_continued
return unless scholarship_since?

touch :scholarship_last_checkin
end
end
12 changes: 10 additions & 2 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ class User < ApplicationRecord
EMAIL_PATTERN = /\A.+@.+\Z/

attr_accessible :username, :name, :email, :profile_attributes, :pronounceable_name,
:application_attributes, :email_for_google, :dues_pledge, :is_scholarship, :voting_policy_agreement
:application_attributes, :email_for_google, :dues_pledge,
:requested_scholarship, :scholarship_since, :scholarship_last_checkin,
:voting_policy_agreement

validates :state, presence: true

Expand Down Expand Up @@ -164,6 +166,10 @@ def update_stripe_record
)
end

def request_scholarship
touch :requested_scholarship
end

def display_state
state.tr("_", " ")
end
Expand Down Expand Up @@ -219,12 +225,14 @@ def gravatar_email
# email :string
# email_for_google :string
# is_admin :boolean default(FALSE)
# is_scholarship :boolean default(FALSE)
# last_logged_in_at :datetime
# last_stripe_charge_succeeded :datetime
# membership_note :text
# name :string
# pronounceable_name :string
# requested_scholarship :datetime
# scholarship_last_checkin :datetime
# scholarship_since :datetime
# setup_complete :boolean
# state :string not null
# username :string
Expand Down
3 changes: 3 additions & 0 deletions app/service_objects/account_setup_reminder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ def send_emails
processed_at = user.application.processed_at
next unless processed_at

# if member requested a scholarship and it hasn't been approved yet, then don't send emails
next if user.requested_scholarship.present? and not user.scholarship_since.present?

if processed_at < 2.days.ago && processed_at > 4.days.ago
NewMembersMailer.three_day_reminder(user).deliver_now
elsif processed_at < 6.days.ago && processed_at > 8.days.ago
Expand Down
9 changes: 4 additions & 5 deletions app/views/admin/_new_member.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
.col-md-4
%ul.list-unstyled
%li
%b Approved on #{ new_member.application.processed_at.strftime("%b %-d") }
%b Approved on #{ new_member.application.processed_at? ? new_member.application.processed_at.strftime("%b %-d") : '---' }
%li
- if new_member.email_for_google
%b Google email:
Expand All @@ -21,12 +21,11 @@
.admin-warning
No Google email
%li
- if new_member.last_stripe_charge_succeeded
%b Stripe Payment Made On:
= new_member.last_stripe_charge_succeeded
- if new_member.last_stripe_charge_succeeded or new_member.scholarship_since?
Stripe charge succeeded OR Scholarship approved
- else
.admin-warning
Dues Not Set Up
Dues Not Set Up or Waiting on Scholarship
.col-md-4
= form_for :user, url: admin_save_membership_note_path do |f|
= f.hidden_field :id, value: new_member.id
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/dues.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
- if user.name.present?
= link_to user.name, members_user_path(user)
%td= user.email
%td= user.is_scholarship
%td= user.scholarship_since.present?
%td= user.stripe_customer_id.present? ? "Yes" : "No"
%td= user.last_stripe_charge_succeeded.strftime('%b %d %Y') if user.last_stripe_charge_succeeded
34 changes: 28 additions & 6 deletions app/views/admin/memberships/_members.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,36 @@
Not set
%td= user.display_state
%td
= user.is_scholarship ? "Yes" : "No"
= form_for user, url: admin_membership_path(user) do |f|
-# 'No' if no request or scholarship status. Button for enabling
-# 'Requested/Approved/Checkin' dates if any status. Buttons for continuing or removing
- if not user.requested_scholarship.present? and not user.scholarship_since.present?
= "No"
- else
%table
%tr
%td
= "Requested:"
%td
= "#{user.requested_scholarship.present? ? user.requested_scholarship.try(:strftime, '%Y-%m-%d') : '---'}"
%tr
%td
= "Approved:"
%td
= "#{user.scholarship_since.present? ? user.scholarship_since.try(:strftime, '%Y-%m-%d') : '---'}"
%tr
%td
= "Last Checkin:"
%td
= "#{user.scholarship_last_checkin.try(:strftime, '%Y-%m-%d')}"

= form_for user, url: admin_approve_or_continue_scholarship_path(user) do |f|
= f.hidden_field(:id)
= f.hidden_field(:is_scholarship, value: !user.is_scholarship)
- if user.is_scholarship
= f.submit "#{user.scholarship_since.present? ? 'Continue scholarship' : 'Allow scholarship'}", class: "btn", data: { confirm: "Are you sure? Note: This does not change the member's dues in Stripe."}

- if user.requested_scholarship.present? or user.scholarship_since.present?
= form_for user, url: admin_remove_scholarship_path(user) do |f|
= f.hidden_field(:id)
= f.submit "Remove scholarship", class: "btn", data: { confirm: "Are you sure? Note: This does not change the member's dues in Stripe." }
- else
= f.submit "Mark as on scholarship", class: "btn", data: { confirm: "Are you sure? Note: This does not change the member's dues in Stripe." }

%td= user.last_stripe_charge_succeeded.strftime('%b %d %Y') if user.last_stripe_charge_succeeded

Expand Down
2 changes: 1 addition & 1 deletion app/views/members/dues/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
%b
#{number_to_currency (@subscription.plan.amount / 100)}
per #{@subscription.plan.interval}, and your status is <b>#{@subscription.status}</b>.
- elsif current_user.is_scholarship?
- elsif current_user.scholarship_since.present?
%p You are receiving a scholarship for your dues payments.
- else
%p You don't have a Stripe subscription yet, or it may have been canceled. Please add your credit or debit card, or request a scholarship below! <3
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
patch "memberships/:id/change_membership_state" => "memberships#change_membership_state", :as => "change_membership_state"
patch "memberships/:id/make_admin" => "memberships#make_admin", :as => "make_admin"
patch "memberships/:id/unmake_admin" => "memberships#unmake_admin", :as => "unmake_admin"
patch "memberships/:id/approve_or_continue_scholarship" => "memberships#approve_or_continue_scholarship", :as => "approve_or_continue_scholarship"
patch "memberships/:id/remove_scholarship" => "memberships#remove_scholarship", :as => "remove_scholarship"
end

get "admin/new_members" => "admin#new_members"
Expand Down
34 changes: 34 additions & 0 deletions db/migrate/20221010052254_add_scholarship_since_to_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class AddScholarshipSinceToUser < ActiveRecord::Migration[6.0]
def change
# Currently have a boolean column is_scholarship
# Add a column requested_scholarship
# that can be used to show who's requested a scholarship (approved or waiting)
# Add a column scholarship_since
# to show date the scholarship was approved
# Add a column scholarship_last_checkin
# to show the last check-in and member requested to continue scholarship
# For default date values, if is_scholarship is true,
# will set dates to 2022-07-10 (as approximate time of last checkin)
# To revert this migration, will have to go back to single boolean column

reversible do |dir|
dir.up do
add_column :users, :requested_scholarship, :timestamp, default: nil
add_column :users, :scholarship_since, :timestamp, default: nil
add_column :users, :scholarship_last_checkin, :timestamp, default: nil

execute "UPDATE users SET requested_scholarship = '2022-07-10', scholarship_since = '2022-07-10', scholarship_last_checkin = '2022-07-10' WHERE is_scholarship = true"

remove_column :users, :is_scholarship
end

dir.down do
add_column :users, :is_scholarship, :boolean, default: false

execute "UPDATE users SET is_scholarship = true WHERE scholarship_since IS NOT NULL"

remove_columns :users, :requested_scholarship, :scholarship_since, :scholarship_last_checkin
end
end
end
end
6 changes: 4 additions & 2 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2022_01_29_183750) do
ActiveRecord::Schema.define(version: 2022_10_10_052254) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -112,9 +112,11 @@
t.text "membership_note"
t.string "stripe_customer_id"
t.datetime "last_stripe_charge_succeeded"
t.boolean "is_scholarship", default: false
t.boolean "voting_policy_agreement", default: false
t.string "pronounceable_name"
t.datetime "requested_scholarship"
t.datetime "scholarship_since"
t.datetime "scholarship_last_checkin"
end

create_table "votes", id: :serial, force: :cascade do |t|
Expand Down
50 changes: 42 additions & 8 deletions spec/controllers/admin/memberships_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,51 @@
end
end

describe "PUT update" do
subject { put :update, params: params }
describe "PATCH approve_scholarship" do
subject { patch :approve_or_continue_scholarship, params: params }
before { login_as(:member, is_admin: true) }

before { login_as(:voting_member, is_admin: true) }

context "marking a member as on scholarship" do
context "mark any member not on scholarship as on scholarship" do
let(:member) { create :member }
let(:params) { {id: member.id, user: {is_scholarship: true}} }
let(:params) { {id: member.id} }

it "should set scholarship_since and last_checkin" do
expect { subject }.to change { member.reload.scholarship_since }.from(nil).to be_within(1.second).of Time.now
expect(member.scholarship_last_checkin).to be_within(1.second).of Time.now
end
end

context "mark a scholarship member as continuing scholarship" do
let(:member) { create :member, scholarship_since: Time.now }
let(:params) { {id: member.id} }

it "should set scholarship_since and last_checkin" do
expect { subject }.not_to change { member.reload.scholarship_since }
expect(member.scholarship_last_checkin).to be_within(1.second).of Time.now
end
end
end

describe "PATCH remove_scholarship" do
subject { patch :remove_scholarship, params: params }
before { login_as(:member, is_admin: true) }

context "mark member requesting scholarship as rejected" do
let(:member) { create :member, requested_scholarship: Time.now}
let(:params) { {id: member.id} }

it "should remove scholarship request" do
expect { subject }.to change { member.reload.requested_scholarship }.to be_nil
end
end

context "marking a member as not on scholarship" do
let(:member) { create :member, scholarship_since: Time.now}
let(:params) { {id: member.id} }

it "should mark scholarship as true" do
expect { subject }.to change { member.reload.is_scholarship }.from(false).to(true)
it "should mark scholarship as false" do
expect { subject }.to change { member.reload.scholarship_since }.to be_nil
expect(member.scholarship_last_checkin).to be_nil
end
end
end
Expand Down
4 changes: 3 additions & 1 deletion spec/controllers/members/dues_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,12 @@
context "logged in as a member" do
before { login_as member }

it "sends an email" do
it "sends an email and marks as requested scholarship" do
expect { subject }.to change { ActionMailer::Base.deliveries.count }.by(1)
expect(ActionMailer::Base.deliveries.last.to).to eq(["[email protected]", member.email])
expect(ActionMailer::Base.deliveries.last.body).to include "Lemurs are pretty great"
expect(member.reload.requested_scholarship).not_to be_nil
expect(member.reload.requested_scholarship).to be_within(1.second).of Time.now
end
end
end
Expand Down
18 changes: 15 additions & 3 deletions spec/features/update_member_status_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,28 @@
it "allows members to be marked as on scholarship" do
visit admin_memberships_path
within(".user-#{member.id}") do
click_button "Mark as on scholarship"
click_button "Allow scholarship"
end

within(".user-#{member.id}") do
expect(page).to have_content "Yes"
expect(page).to have_content "Approved"
expect(page).to have_content "Last Checkin"
end
end

context "with a scholarship member" do
before { member.update_attributes(is_scholarship: true) }
before { member.update_attributes(scholarship_since: Time.now) }

it "allows members to be marked as continuing scholarship" do
visit admin_memberships_path
within(".user-#{member.id}") do
click_button "Continue scholarship"
end

within(".user-#{member.id}") do
expect(page).to have_content "Last Checkin:"
end
end

it "allows members to be marked as not on scholarship" do
visit admin_memberships_path
Expand Down
Loading