|
| 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