diff --git a/app/models/event_schedule.rb b/app/models/event_schedule.rb index cb630acd..fbf5de69 100644 --- a/app/models/event_schedule.rb +++ b/app/models/event_schedule.rb @@ -11,6 +11,8 @@ class EventSchedule < ActiveRecord::Base validates :start_time, presence: true validates :event, uniqueness: { scope: :schedule } + validate :not_overlapping + scope :confirmed, -> { joins(:event).where('state = ?', 'confirmed') } scope :canceled, -> { joins(:event).where('state = ?', 'canceled') } scope :withdrawn, -> { joins(:event).where('state = ?', 'withdrawn') } @@ -36,4 +38,15 @@ class EventSchedule < ActiveRecord::Base def conference_id schedule.program.conference_id end + + def not_overlapping + if room + room.event_schedules.where(schedule: schedule).where.not(id: id).each do |e| + if (e.start_time <= start_time && e.end_time > start_time) || (e.end_time >= end_time && e.start_time < end_time) || (e.start_time > start_time && e.start_time < end_time) + errors.add(:event, "can't be scheduled at the same time than other event in the same room") + break + end + end + end + end end diff --git a/spec/models/event_schedule_spec.rb b/spec/models/event_schedule_spec.rb index 28b04ddf..33ce4edb 100644 --- a/spec/models/event_schedule_spec.rb +++ b/spec/models/event_schedule_spec.rb @@ -17,5 +17,32 @@ describe EventSchedule do it { is_expected.to validate_presence_of(:event) } it { is_expected.to validate_presence_of(:room) } it { is_expected.to validate_presence_of(:start_time) } + + describe '#not_overlapping' do + let!(:event) { create(:event, event_type: create(:event_type, length: 60)) } + let!(:event2) { create(:event, event_type: create(:event_type, length: 30), program: event.program) } + let!(:schedule) { create(:schedule, program: event.program) } + let!(:room) { create(:room, venue: create(:venue, conference: event.program.conference)) } + let!(:event_schedule) { create(:event_schedule, schedule: schedule, event: event, room: room, start_time: event.program.conference.start_date.tomorrow.to_time + 60.minutes) } + + describe "can't be scheduled at the same time than other event in the same room" do + it 'case 1' do + expect(build(:event_schedule, schedule: schedule, event: event2, room: room, start_time: event_schedule.start_time - 15.minutes)).to_not be_valid + end + + it 'case 2' do + expect(build(:event_schedule, schedule: schedule, event: event2, room: room, start_time: event_schedule.start_time + 45.minutes)).to_not be_valid + end + + it 'case 3' do + expect(build(:event_schedule, schedule: schedule, event: event2, room: room, start_time: event_schedule.start_time + 15.minutes)).to_not be_valid + end + + it 'case 4' do + event2.event_type = create(:event_type, length: 120) + expect(build(:event_schedule, schedule: schedule, event: event2, room: room, start_time: event_schedule.start_time - 30.minutes)).to_not be_valid + end + end + end end end