Skip to content
This repository was archived by the owner on Jul 24, 2020. It is now read-only.

Commit bd43812

Browse files
committed
extract checkout/checking functionality
resolves #1608 --create manage route for managing users' reservations --extract checkin/checkout functionality to manage controller --extract as much functionality to checkoutHelper service object as possible --replace set_reservation before action with ||= --put repeated before_action into application controller
1 parent cef35d9 commit bd43812

22 files changed

+879
-749
lines changed

app/controllers/application_controller.rb

+7
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ def skip_authentication?
143143
.include?(params[:action]) && !guests_disabled?)
144144
end
145145

146+
def set_user
147+
@user = User.find(params[:user_id])
148+
return unless @user.role == 'banned'
149+
flash[:error] = 'This user is banned and cannot check out equipment.'
150+
params[:banned] = true
151+
end
152+
146153
#-------- end before_filter methods --------#
147154

148155
def update_cart # rubocop:disable MethodLength, AbcSize

app/controllers/manage_controller.rb

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# frozen_string_literal: true
2+
# rubocop:disable ClassLength
3+
class ManageController < ApplicationController
4+
load_and_authorize_resource
5+
before_action :set_user, only: [:show, :checkout]
6+
before_action :set_reservation, only: [:send_receipt]
7+
8+
private
9+
10+
def set_reservation
11+
@reservation = Reservation.find(params[:receipt_id])
12+
end
13+
14+
def check_for_banned_user
15+
if @user.role == 'banned'
16+
flash[:error] = 'Banned users cannot check out equipment.'
17+
redirect_to(root_path) && return
18+
end
19+
true
20+
end
21+
22+
def check_terms_of_service
23+
unless @user.terms_of_service_accepted ||
24+
params[:terms_of_service_accepted].present?
25+
flash[:error] = 'You must confirm that the user accepts the Terms of '\
26+
'Service.'
27+
redirect_to(:back) && return
28+
end
29+
true
30+
end
31+
32+
def handle_overdue_reservations
33+
if @user.overdue_reservations?
34+
if can? :override, :checkout_errors
35+
# Admins can ignore this
36+
flash[:notice] = 'Admin Override: Equipment has been checked out '\
37+
'successfully, even though the reserver has overdue equipment.'
38+
else
39+
# Everyone else is redirected
40+
flash[:error] = 'Could not check out the equipment, because the '\
41+
'reserver has reservations that are overdue.'
42+
redirect_to(:back) && return
43+
end
44+
end
45+
true
46+
end
47+
48+
def approve_checkout
49+
# check for banned user
50+
return unless check_for_banned_user
51+
52+
# check terms of service
53+
return unless check_terms_of_service
54+
55+
# Overdue validation
56+
return unless handle_overdue_reservations
57+
true
58+
end
59+
60+
def check_nonemptiness_of(checked_out_reservations)
61+
if checked_out_reservations.empty?
62+
flash[:error] = 'No reservation selected.'
63+
redirect_to(:back) && return
64+
end
65+
true
66+
end
67+
68+
def check_validity_of(checked_in_reservations)
69+
unless checked_in_reservations
70+
flash[:error] = 'One of the items you tried to check in has already '\
71+
'been checked in.'
72+
redirect_to(:back) && return
73+
end
74+
true
75+
end
76+
77+
def check_uniqueness_of(checked_out_reservations)
78+
unless Reservation.unique_equipment_items?(checked_out_reservations)
79+
flash[:error] = 'The same equipment item cannot be simultaneously '\
80+
'checked out in multiple reservations.'
81+
redirect_to(:back) && return
82+
end
83+
true
84+
end
85+
86+
def prep_receipt_page(check_in_set:, check_out_set:, user: nil)
87+
@check_in_set = check_in_set
88+
@check_out_set = check_out_set
89+
@user = user if user
90+
render('receipt', layout: 'application_with_search_sidebar') && return
91+
end
92+
93+
public
94+
95+
def show # initializer
96+
@check_out_set = @user.due_for_checkout.includes(:equipment_model)
97+
@check_in_set = @user.due_for_checkin.includes(:equipment_model)
98+
99+
render :show, layout: 'application'
100+
end
101+
102+
def checkout
103+
return unless approve_checkout
104+
105+
checked_out_reservations =
106+
CheckoutHelper.preprocess_checkout(params[:reservations],
107+
@user, current_user)
108+
109+
return unless check_nonemptiness_of(checked_out_reservations)
110+
return unless check_uniqueness_of(checked_out_reservations)
111+
112+
## Save reservations
113+
Reservation.transaction do
114+
begin
115+
checked_out_reservations.each do |r|
116+
CheckoutHelper.checkout_reservation(r, params[:reservations])
117+
end
118+
rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid => e
119+
flash[:error] = "Checking out your reservation failed: #{e.message}"
120+
redirect_to manage_reservations_for_user_path(@user)
121+
raise ActiveRecord::Rollback
122+
end
123+
end
124+
125+
CheckoutHelper.update_tos(@user)
126+
CheckoutHelper.send_checkout_receipts(checked_out_reservations)
127+
prep_receipt_page(check_in_set: [], check_out_set: checked_out_reservations)
128+
end
129+
130+
def checkin
131+
# see comments for checkout, this method proceeds in a similar way
132+
checked_in_reservations =
133+
CheckoutHelper.preproccess_checkins(params[:reservations], current_user)
134+
135+
return unless check_validity_of(checked_in_reservations)
136+
137+
return unless check_nonemptiness_of(checked_in_reservations)
138+
## Save reservations
139+
Reservation.transaction do
140+
begin
141+
checked_in_reservations.each do |r|
142+
CheckoutHelper.checkin_reservation(r, params[:reservations])
143+
end
144+
rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid => e
145+
flash[:error] = "Checking in your reservation failed: #{e.message}"
146+
redirect_to :back
147+
raise ActiveRecord::Rollback
148+
end
149+
end
150+
151+
prep_receipt_page(check_in_set: checked_in_reservations, check_out_set: [],
152+
user: checked_in_reservations.first.reserver)
153+
end
154+
155+
def send_receipt
156+
if UserMailer.reservation_status_update(@reservation, 'checked out')
157+
.deliver_now
158+
flash[:notice] = 'Successfully delivered receipt email.'
159+
else
160+
flash[:error] = 'Unable to deliver receipt email. Please contact '\
161+
'administrator for more support.'
162+
end
163+
redirect_to @reservation
164+
end
165+
end

0 commit comments

Comments
 (0)