Skip to content

Commit

Permalink
Canceling a hold cleans up associated appointments
Browse files Browse the repository at this point in the history
If a hold is canceled by a member, it is removed from any associated
appointments. If it was the only item in the appointment, the
appointment is also canceled.
  • Loading branch information
stephanieminn authored and jim committed Oct 3, 2023
1 parent 62cf92a commit 58f41fc
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 4 deletions.
4 changes: 3 additions & 1 deletion app/controllers/account/holds_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ def create
end

def destroy
current_member.active_holds.find(params[:id]).destroy!
hold = current_member.active_holds.find(params[:id])
hold.cancel!

redirect_to account_holds_path
end

Expand Down
10 changes: 8 additions & 2 deletions app/helpers/holds_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,15 @@ def render_hold_status(hold)
end

def render_remove_link(hold)
unless hold.appointment.present?
link_to("Remove Hold", account_hold_path(hold), class: "btn", method: :delete, data: {confirm: "Are you sure you want to remove this hold?"})
message = "Are you sure you want to remove this hold?"

if hold.appointment.present?
message <<
" It will also be removed from your appointment."\
" If it's the only item in your appointment, your appointment will be canceled."
end

link_to("Remove Hold", account_hold_path(hold), class: "btn", method: :delete, data: {confirm: message})
end

def place_in_line_for(hold)
Expand Down
10 changes: 9 additions & 1 deletion app/models/appointment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,18 @@ def merge!(other_appointment)
end
end

def cancel_if_no_items!
destroy! if no_items?
end

private

def no_items?
holds.empty? && loans.empty?
end

def item_present
if holds.empty? && loans.empty?
if no_items?
errors.add(:base, "Please select an item to pick-up or return for your appointment")
end
end
Expand Down
9 changes: 9 additions & 0 deletions app/models/hold.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ def start!(now = Time.current)
)
end

def cancel!
if appointment.present?
appointment_hold.destroy!
appointment.cancel_if_no_items!
end

destroy!
end

# A hold that timed out
def expired?(now = Time.current)
started? && expires_at < now
Expand Down
4 changes: 4 additions & 0 deletions test/factories/appointments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
ends_at { "2020-09-23 12:14:27" }
comment { "My Comment" }
member

factory :appointment_with_holds do
holds { [association(:hold, creator: member.user)] }
end
end
end
9 changes: 9 additions & 0 deletions test/models/appointment_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,13 @@ class AppointmentTest < ActiveSupport::TestCase
assert_equal [loan, loan2], original.loans
assert_equal "First notes\n\nSecond notes", original.comment
end

test "#cancel_if_no_items!" do
appointment = create(:appointment_with_holds)
appointment.holds.destroy_all

appointment.cancel_if_no_items!

assert appointment.destroyed?
end
end
51 changes: 51 additions & 0 deletions test/system/remove_holds_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require "application_system_test_case"

class RemoveHoldsTest < ApplicationSystemTestCase
setup do
@member = create(:verified_member_with_membership)
login_as @member.user
end

test "removes hold if it doesn't have an appointment" do
@held_item = create(:item)
@hold = create(:hold, item: @held_item, member: @member)

visit account_holds_path
accept_confirm { click_link "Remove Hold" }

assert_text "You have no items on hold"
end

test "removes hold from associated appointment if appointment has more than one item" do
@held_item = create(:item)
@borrowed_item = create(:item)

@hold = create(:hold, item: @held_item, member: @member)
@loan = create(:loan, item: @borrowed_item, member: @member)

create(:event, calendar_id: Event.appointment_slot_calendar_id, start: 27.hours.since.beginning_of_hour, finish: 28.hours.since.beginning_of_hour)
@appointment = create(:appointment, member: @member, starts_at: Time.now + 1.day, ends_at: Time.now + 1.day + 2.hours, holds: [@hold], loans: [@loan])

visit account_holds_path
accept_confirm { click_link "Remove Hold" }
click_on "Appointments"

appointment_card = find("li.appointment")
within(appointment_card) do
assert_no_text @held_item.name
assert_text @borrowed_item.name
end
end

test "removes hold and cancels associated appointment if it's the only item" do
held_item = create(:item)
hold = create(:hold, item: held_item, member: @member)
create(:appointment, member: @member, starts_at: Time.now + 1.day, ends_at: Time.now + 1.day + 2.hours, holds: [hold])

visit account_holds_path
accept_confirm { click_link "Remove Hold" }
click_on "Appointments"

assert_text "You have no scheduled appointments"
end
end

0 comments on commit 58f41fc

Please sign in to comment.