2018-05-07 16:47:29 -07:00
# frozen_string_literal: true
2017-09-05 22:23:34 +03:00
class EventSchedule < ApplicationRecord
2017-02-12 17:57:55 +02:00
default_scope { where ( enabled : true ) }
2016-07-08 13:28:02 +02:00
belongs_to :schedule
belongs_to :event
belongs_to :room
2016-07-13 01:33:56 +02:00
2016-08-18 00:32:16 +05:30
has_paper_trail ignore : [ :updated_at ] , meta : { conference_id : :conference_id }
2016-07-26 16:20:31 +02:00
validates :schedule , presence : true
validates :event , presence : true
validates :room , presence : true
validates :start_time , presence : true
2016-08-15 16:08:02 +02:00
validates :event , uniqueness : { scope : :schedule }
2017-04-22 01:20:05 +05:30
validate :start_after_end_hour
validate :start_before_start_hour
2017-08-09 18:12:20 +03:00
validate :same_room_as_track
2017-08-08 16:18:11 +03:00
validate :during_track
2017-08-09 18:12:20 +03:00
validate :valid_schedule
2016-07-26 16:20:31 +02:00
2016-07-20 23:20:47 +02:00
scope :confirmed , - > { joins ( :event ) . where ( 'state = ?' , 'confirmed' ) }
scope :canceled , - > { joins ( :event ) . where ( 'state = ?' , 'canceled' ) }
scope :withdrawn , - > { joins ( :event ) . where ( 'state = ?' , 'withdrawn' ) }
2016-07-26 16:20:31 +02:00
delegate :guid , to : :room , prefix : true
2016-07-20 23:20:47 +02:00
##
# Returns end of the event
#
def end_time
start_time + event . event_type . length . minutes
end
##
2017-02-12 19:10:03 +05:30
# Returns event schedules that are scheduled in the same room and start_time as event
2016-07-20 23:20:47 +02:00
#
2017-02-12 19:10:03 +05:30
def intersecting_event_schedules
2017-02-12 17:57:55 +02:00
EventSchedule . unscoped . where ( room : room , start_time : start_time , schedule : schedule ) . where . not ( id : id )
2016-07-20 23:20:47 +02:00
end
2016-08-18 00:32:16 +05:30
2016-08-15 17:17:57 +05:30
def replacement?
2017-02-12 19:10:03 +05:30
event . state == 'confirmed' && ( ! intersecting_event_schedules . canceled . empty? || ! intersecting_event_schedules . withdrawn . empty? )
2016-08-15 17:17:57 +05:30
end
2016-08-18 00:32:16 +05:30
private
2017-04-22 01:20:05 +05:30
def start_after_end_hour
return unless event && start_time && event . program && event . program . conference && event . program . conference . end_hour
errors . add ( :start_time , " can't be after the conference end hour ( #{ event . program . conference . end_hour } ) " ) if start_time . hour > = event . program . conference . end_hour
end
def start_before_start_hour
return unless event && start_time && event . program && event . program . conference && event . program . conference . start_hour
errors . add ( :start_time , " can't be before the conference start hour ( #{ event . program . conference . start_hour } ) " ) if start_time . hour < event . program . conference . start_hour
end
2016-08-18 00:32:16 +05:30
def conference_id
schedule . program . conference_id
end
2017-08-08 16:18:11 +03:00
##
2017-08-09 18:12:20 +03:00
# Validates that the event is scheduled in the same room as its track
2017-08-08 16:18:11 +03:00
#
2017-08-09 18:12:20 +03:00
def same_room_as_track
return unless event . try ( :track ) . try ( :room )
errors . add ( :room , " must be the same as the track's room ( #{ event . track . room . name } ) " ) unless event . track . room == room
2017-08-08 16:18:11 +03:00
end
##
2017-08-09 18:12:20 +03:00
# Validates that the event is scheduled within its track's time slot
2017-08-08 16:18:11 +03:00
#
def during_track
2017-08-09 18:12:20 +03:00
return unless event . try ( :track ) && start_time
if event . track . try ( :start_date ) && event . track . start_date > start_time
2017-08-08 16:18:11 +03:00
errors . add ( :start_time , " can't be before the track's start date ( #{ event . track . start_date } ) " )
end
2017-08-09 18:12:20 +03:00
if event . track . try ( :end_date ) && event . track . end_date + 1 . day < end_time
2017-08-08 16:18:11 +03:00
errors . add ( :end_time , " can't be after the track's end date ( #{ event . track . end_date } ) " )
end
end
2017-08-09 18:12:20 +03:00
##
# Validates that the event is scheduled in its self-organized tracks's schedules
#
def valid_schedule
return unless event . try ( :track ) . try ( :self_organized? ) && schedule
errors . add ( :schedule , " must be one of #{ event . track . name } track's schedules " ) unless event . track . schedules . include? ( schedule )
end
2016-07-08 13:28:02 +02:00
end