jam-cloud/ruby/lib/jam_ruby/models/rsvp_request.rb

258 lines
8.2 KiB
Ruby

module JamRuby
class RsvpRequest < ActiveRecord::Base
belongs_to :user, :class_name => "JamRuby::User"
has_many :rsvp_requests_rsvp_slots, :class_name => "JamRuby::RsvpRequestRsvpSlot", :foreign_key => "rsvp_request_id"
has_many :rsvp_slots, :class_name => "JamRuby::RsvpSlot", :through => :rsvp_requests_rsvp_slots
validates :user, presence: true
validates :canceled, :inclusion => {:in => [nil, true, false]}
# pulls all instruments from the associated rsvp_slots
def instrument_list
rsvp_slots.map(&:instrument)
end
def self.index(music_session, user=nil, options={})
query = RsvpRequest
.includes(:user)
.joins(
%Q{
INNER JOIN
rsvp_requests_rsvp_slots rrrs
ON
rrrs.rsvp_request_id = rsvp_requests.id
INNER JOIN
rsvp_slots rs
ON rs.id = rrrs.rsvp_slot_id
}
)
.where(
%Q{
rs.music_session_id = '#{music_session.id}'
}
)
if options[:status] == 'approved'
query = query.where("rrrs.chosen = true")
elsif options[:status] == 'pending'
query = query.where("rrrs.chosen is null")
end
query = query.where("rsvp_requests.user_id = ?", user.id) unless user.nil?
return query.uniq
end
def self.create(params, user)
music_session = MusicSession.find_by_id(params[:session_id])
# verify music session exists
if music_session.nil?
raise StateError, "Invalid session."
end
# verify slot IDs exist in request
if params[:rsvp_slots].blank?
raise StateError, "You must select at least 1 slot."
end
# verify invitation exists for this user and session
invitation = Invitation.where("music_session_id = ? AND receiver_id = ?", music_session.id, user.id)
if invitation.first.nil? && !music_session.open_rsvps && music_session.creator.id != user.id
raise PermissionError, "Only a session invitee can create an RSVP for this session."
end
RsvpRequest.transaction do
@rsvp = RsvpRequest.new
@rsvp.user = user
slot_ids = params[:rsvp_slots]
instruments = []
# for each slot requested, do the following:
# (1) verify slot exists in db
# (2) verify slot is not already chosen
# (3) verify user has not already requested this slot
# (4) create RsvpRequestRsvpSlot
# (5) create RsvpRequest
slot_ids.each do |id|
rsvp_slot = RsvpSlot.where(:id => id).first
# verify slot exists in db
if rsvp_slot.nil?
raise StateError, "Invalid slot #{id}."
end
# verify user has not already submitted RSVP request for this slot
user_slot = RsvpRequest.joins(:rsvp_requests_rsvp_slots)
.where(:user_id => user.id)
.where(rsvp_requests_rsvp_slots: {rsvp_slot_id: id})
if !user_slot.blank?
raise StateError, "You have already submitted an RSVP request for this slot."
end
chosen_slot = rsvp_slot.rsvp_requests_rsvp_slots.where("chosen = true").first
# verify this slot was not already chosen
if !chosen_slot.nil?
raise StateError, "The #{rsvp_slot.instrument_id} slot has already been approved by the session organizer."
else
rsvp_request_rsvp_slot = RsvpRequestRsvpSlot.new
rsvp_request_rsvp_slot.rsvp_request = @rsvp
rsvp_request_rsvp_slot.rsvp_slot = rsvp_slot
rsvp_request_rsvp_slot.chosen = true if params[:autoapprove] == true
rsvp_request_rsvp_slot.save
instruments << rsvp_slot.instrument_id
end
end
@rsvp.save
unless params[:message].blank?
session_info_comment = SessionInfoComment.new
session_info_comment.music_session = music_session
session_info_comment.user = user
session_info_comment.comment = params[:message]
session_info_comment.save
Notification.send_scheduled_session_comment(music_session, user, params[:message])
end
Notification.send_scheduled_session_rsvp(music_session, user, instruments)
@rsvp
end
end
def self.update(params, user)
rsvp_request_id = params[:id]
music_session = MusicSession.find_by_id(params[:session_id])
# verify music session exists
if music_session.nil?
raise StateError, "Invalid session."
end
# authorize the user attempting to respond to the RSVP request
if music_session.creator.id != user.id
raise PermissionError, "Only the session organizer can accept or decline and RSVP request."
end
rsvp_request = RsvpRequest.find_by_id(rsvp_request_id)
if rsvp_request.nil?
raise StateError, "Invalid RSVP request."
end
RsvpRequest.transaction do
rsvp_responses = params[:rsvp_responses]
if !rsvp_responses.blank?
instruments = []
accepted_slot = false
rsvp_responses.each do |r|
request_slot_id = r[:request_slot_id]
request_slot = RsvpRequestRsvpSlot.find_by_id(request_slot_id)
if request_slot.nil?
raise StateError, "Invalid request slot #{request_slot_id}."
end
rsvp_slot = RsvpSlot.find_by_id(request_slot.rsvp_slot_id)
if rsvp_slot.nil?
raise StateError, "Slot does not exist"
end
if rsvp_slot.chosen && r[:accept]
raise StateError, "The #{rsvp_slot.instrument_id} slot has already been approved for another user."
end
if r[:accept]
accepted_slot = true
request_slot.chosen = true
request_slot.save
instruments << rsvp_slot.instrument_id
else
request_slot.chosen = false
request_slot.save
end
end
# send notification if at least 1 slot was approved
if accepted_slot
Notification.send_scheduled_session_rsvp_approved(music_session, user, instruments)
end
else
raise StateError, "Invalid request."
end
end
end
def self.cancel(params, user)
if params[:id].blank?
raise StateError, "RSVP request ID is required."
end
if params[:session_id].blank?
raise StateError, "Session ID is required."
end
music_session = MusicSession.find(params[:session_id])
rsvp_request = RsvpRequest.find(params[:id])
if music_session.creator.id != user.id && rsvp_request.user_id != user.id
raise PermissionError, "Only the session organizer or RSVP creator can cancel the RSVP."
end
RsvpRequest.transaction do
case params[:cancelled]
when 'yes'
rsvp_request.canceled = true
rsvp_request.cancel_all = false
when 'all'
rsvp_request.canceled = true
rsvp_request.cancel_all = true
end
rsvp_request.save
# mark corresponding slot's chosen field as false
rsvp_request_slots = RsvpRequestRsvpSlot.where("rsvp_request_id = ?", rsvp_request.id)
rsvp_request_slots.each do |slot|
if slot.chosen
slot.chosen = false
slot.save
end
end
# send notification
if music_session.creator.id == user.id
Notification.send_scheduled_session_rsvp_cancelled_org(music_session, user)
else
Notification.send_scheduled_session_rsvp_cancelled(music_session, user)
end
unless params[:message].blank?
session_info_comment = SessionInfoComment.new
session_info_comment.music_session = music_session
session_info_comment.user = user
session_info_comment.comment = params[:message]
session_info_comment.save
Notification.send_scheduled_session_comment(music_session, user, params[:message])
end
end
end
end
end