diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index 301dd585..37633e22 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -191,7 +191,7 @@ module Admin # Set also in proposals controller :title, :subtitle, :event_type_id, :abstract, :description, :require_registration, :difficulty_level_id, # Set only in admin/events controller - :track_id, :state, :language, :start_time, :is_highlight, :max_attendees, + :track_id, :state, :language, :is_highlight, :max_attendees, # Not used anymore? :proposal_additional_speakers, :user, :users_attributes) end diff --git a/app/controllers/api/v1/events_controller.rb b/app/controllers/api/v1/events_controller.rb index a942f189..eb77cd4f 100644 --- a/app/controllers/api/v1/events_controller.rb +++ b/app/controllers/api/v1/events_controller.rb @@ -5,7 +5,7 @@ module Api respond_to :json def index - events = Event.includes(:track, :room, :event_type, event_users: :user) + events = Event.includes(:track, :event_type, event_users: :user) if @conference events = events.where(program: @conference.program) diff --git a/app/models/event.rb b/app/models/event.rb index 676bbd26..5cfa372a 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -16,9 +16,9 @@ class Event < ActiveRecord::Base has_many :events_registrations has_many :registrations, through: :events_registrations + has_many :event_schedules, dependent: :destroy belongs_to :track - belongs_to :room belongs_to :difficulty_level belongs_to :program @@ -71,11 +71,19 @@ class Event < ActiveRecord::Base end ## - # Checkes if the event has a start_time and a room + # Checkes if the event has a start_time and a room for the selected schedule if there is any # ====Returns # * +true+ or +false+ def scheduled? - room.present? && start_time.present? + selected_event_schedule.try(:start_time).present? && selected_event_schedule.try(:room).present? + end + + ## + # Checkes if the event has a start_time and a room for the selected one if there is any. + # ====Returns + # * +true+ or +false+ + def unscheduled? + state == 'confirmed' && (!selected_event_schedule.try(:start_time).present? || !selected_event_schedule.try(:room).present?) end def registration_possible? @@ -132,7 +140,7 @@ class Event < ActiveRecord::Base def as_json(options) json = super(options) - json[:room_guid] = room.try(:guid) + json[:room_guid] = scheduled_room.try(:guid) json[:track_color] = track.try(:color) || '#FFFFFF' json[:length] = event_type.try(:length) || EventType::LENGTH_STEP @@ -245,7 +253,21 @@ class Event < ActiveRecord::Base # Returns end of the event # def end_time - self.start_time + self.event_type.length.minutes + self.scheduled_start_time + self.event_type.length.minutes + end + + ## + # Returns the room in which the event is scheduled + # + def scheduled_room + selected_event_schedule.try(:room) + end + + ## + # Returns the start time at which this event is scheduled + # + def scheduled_start_time + selected_event_schedule.try(:start_time) end ## @@ -257,11 +279,16 @@ class Event < ActiveRecord::Base private + # returns the event_schedule for this event and for the selected_schedule + def selected_event_schedule + event_schedules.find_by(schedule_id: program.try(:selected_schedule)) + end + ## # Do not allow, for the event, more attendees than the size of the room def max_attendees_no_more_than_room_size - return unless room && max_attendees_changed? - errors.add(:max_attendees, "cannot be more than the room's capacity (#{room.size})") if max_attendees && (max_attendees > room.size) + return unless scheduled_room && max_attendees_changed? + errors.add(:max_attendees, "cannot be more than the room's capacity (#{scheduled_room.size})") if max_attendees && (max_attendees > scheduled_room.size) end def abstract_limit diff --git a/app/models/event_schedule.rb b/app/models/event_schedule.rb new file mode 100644 index 00000000..d0748e26 --- /dev/null +++ b/app/models/event_schedule.rb @@ -0,0 +1,5 @@ +class EventSchedule < ActiveRecord::Base + belongs_to :schedule + belongs_to :event + belongs_to :room +end diff --git a/app/models/program.rb b/app/models/program.rb index b7b82dc2..83f0cfba 100644 --- a/app/models/program.rb +++ b/app/models/program.rb @@ -7,6 +7,7 @@ class Program < ActiveRecord::Base has_many :event_types, dependent: :destroy has_many :tracks, dependent: :destroy has_many :difficulty_levels, dependent: :destroy + has_many :schedules, dependent: :destroy has_many :events, dependent: :destroy do def require_registration where(require_registration: true, state: :confirmed) @@ -26,12 +27,12 @@ class Program < ActiveRecord::Base where(state: :confirmed) end - def scheduled - where.not(start_time: nil).where.not(room: nil).order(start_time: :asc) + def scheduled(schedule_id) + joins(:event_schedules).where('event_schedules.schedule_id = ? AND event_schedules.start_time IS NOT NULL AND event_schedules.room_id IS NOT NULL', schedule_id) end def unscheduled - confirmed.where('start_time IS NULL OR room_id IS NULL') + select(&:unscheduled?) end def highlights diff --git a/app/models/room.rb b/app/models/room.rb index 02e6ea7f..87dfb848 100644 --- a/app/models/room.rb +++ b/app/models/room.rb @@ -1,6 +1,6 @@ class Room < ActiveRecord::Base belongs_to :venue - has_many :events, dependent: :nullify + has_many :event_schedules, dependent: :nullify before_create :generate_guid diff --git a/app/models/schedule.rb b/app/models/schedule.rb new file mode 100644 index 00000000..c23351fe --- /dev/null +++ b/app/models/schedule.rb @@ -0,0 +1,4 @@ +class Schedule < ActiveRecord::Base + belongs_to :program + has_many :event_schedules, dependent: :destroy +end diff --git a/app/serializers/conference_serializer.rb b/app/serializers/conference_serializer.rb index b2b80c28..2059f37c 100644 --- a/app/serializers/conference_serializer.rb +++ b/app/serializers/conference_serializer.rb @@ -22,23 +22,23 @@ class ConferenceSerializer < ActiveModel::Serializer def rooms if object.venue - object.venue.rooms.includes(:events).map do |room| { id: room.id, - size: room.size, - events: room.events.map do |event| { guid: event.title, - title: event.title, - subtitle: event.subtitle, - abstract: event.abstract, - description: event.description, - is_highlight: event.is_highlight, - require_registration: event.require_registration, - start_time: event.start_time, - event_type_id: event.event_type.id, - difficulty_level_id: event.difficulty_level_id, - track_id: event.track_id, - speaker_names: event.speaker_names + object.venue.rooms.map do |room| { id: room.id, + size: room.size, + events: room.event_schedules.map do |event_schedule| { guid: event_schedule.event.title, + title: event_schedule.event.title, + subtitle: event_schedule.event.subtitle, + abstract: event_schedule.event.abstract, + description: event_schedule.event.description, + is_highlight: event_schedule.event.is_highlight, + require_registration: event_schedule.event.require_registration, + start_time: event_schedule.start_time, + event_type_id: event_schedule.event.event_type.id, + difficulty_level_id: event_schedule.event.difficulty_level_id, + track_id: event_schedule.event.track_id, + speaker_names: event_schedule.event.speaker_names } - end - } + end + } end else [] diff --git a/app/serializers/event_schedule_serializer.rb b/app/serializers/event_schedule_serializer.rb new file mode 100644 index 00000000..94042aa0 --- /dev/null +++ b/app/serializers/event_schedule_serializer.rb @@ -0,0 +1,14 @@ +class EventScheduleSerializer < ActiveModel::Serializer + include ActionView::Helpers::TextHelper + + attributes :date, :room + + def date + t = object.start_time + t.blank? ? '' : %( #{I18n.l t, format: :short}#{t.formatted_offset(false)} ) + end + + def room + object.room.try(:guid) + end +end diff --git a/app/serializers/event_serializer.rb b/app/serializers/event_serializer.rb index 93729e16..2984706c 100644 --- a/app/serializers/event_serializer.rb +++ b/app/serializers/event_serializer.rb @@ -1,11 +1,11 @@ class EventSerializer < ActiveModel::Serializer include ActionView::Helpers::TextHelper - attributes :guid, :title, :length, :date, :language, :abstract, :speaker_ids, :type, :room, :track + attributes :guid, :title, :length, :scheduled_date, :language, :abstract, :speaker_ids, :type, :scheduled_room, :track - def date - t = object.start_time - t.blank? ? '' : %{ #{I18n.l t, format: :short}#{t.formatted_offset(false)} } + def scheduled_date + t = object.scheduled_start_time + t.blank? ? '' : %( #{I18n.l t, format: :short}#{t.formatted_offset(false)} ) end def speaker_ids @@ -17,8 +17,8 @@ class EventSerializer < ActiveModel::Serializer object.event_type.try(:title) end - def room - object.room.try(:guid) + def scheduled_room + object.scheduled_room.try(:guid) end def track diff --git a/app/views/admin/events/_proposal.html.haml b/app/views/admin/events/_proposal.html.haml index 04405676..9877250c 100644 --- a/app/views/admin/events/_proposal.html.haml +++ b/app/views/admin/events/_proposal.html.haml @@ -106,18 +106,18 @@ %td = @event.language - - unless @event.room.nil? + - unless @event.scheduled_room.nil? %tr %td %b Room %td - = @event.room.name - - unless @event.start_time.nil? + = @event.scheduled_room.name + - unless @event.scheduled_start_time.nil? %tr %td %b Scheduled time %td - = @event.start_time + = @event.scheduled_start_time %tr %td %b Submitter diff --git a/app/views/admin/events/registrations.html.haml b/app/views/admin/events/registrations.html.haml index 21042349..4a8d27bd 100644 --- a/app/views/admin/events/registrations.html.haml +++ b/app/views/admin/events/registrations.html.haml @@ -11,7 +11,7 @@ for = @event.title - - if @event.room && (@event_registrations.length > @event.room.size) + - if @event.scheduled_room && (@event_registrations.length > @event.scheduled_room.size) %b Attention: You have more registrations than the capacity of the room! diff --git a/app/views/admin/tracks/show.html.haml b/app/views/admin/tracks/show.html.haml index 240b9725..18dca9c7 100644 --- a/app/views/admin/tracks/show.html.haml +++ b/app/views/admin/tracks/show.html.haml @@ -27,5 +27,4 @@ %td = event.state %td - = event.start_time - + = event.scheduled_start_time diff --git a/app/views/conference/schedule.xml.haml b/app/views/conference/schedule.xml.haml index 32083649..e85ddf14 100644 --- a/app/views/conference/schedule.xml.haml +++ b/app/views/conference/schedule.xml.haml @@ -19,7 +19,7 @@ %date= event.start_time.iso8601 %start= event.start_time.strftime('%H:%M') %duration= length_timestamp(event.event_type.length) - %room= event.room.name + %room= event.scheduled_room.name %type= event.event_type.name %language= ISO_639.find_by_english_name(event.language).third if event.language %slug= "#{event.id} #{event.title}".parameterize diff --git a/app/views/conference_registrations/_registration_info.html.haml b/app/views/conference_registrations/_registration_info.html.haml index 0bf15c71..672e2911 100644 --- a/app/views/conference_registrations/_registration_info.html.haml +++ b/app/views/conference_registrations/_registration_info.html.haml @@ -11,7 +11,7 @@ .text-muted = registered_text(event) - if event.scheduled? - (Scheduled on: #{event.start_time.to_date}) + (Scheduled on: #{event.scheduled_start_time.to_date}) %br diff --git a/app/views/proposal/_proposal_form.html.haml b/app/views/proposal/_proposal_form.html.haml index 4df88438..fd46b220 100644 --- a/app/views/proposal/_proposal_form.html.haml +++ b/app/views/proposal/_proposal_form.html.haml @@ -49,7 +49,7 @@ = f.inputs 'Enable pre-registration' do = f.input :require_registration, label: 'Require participants to register to your event' - - message = @event.room ? "Value must be between 1 and #{@event.room.size}" : 'Check room capacity after scheduling.' + - message = @event.scheduled_room ? "Value must be between 1 and #{@event.scheduled_room.size}" : 'Check room capacity after scheduling.' = f.input :max_attendees, hint: 'The maximum number of participants. ' + message - if current_user.has_any_role? :admin, { name: :organizer, resource: @conference }, { name: :cfp, resource: @conference } diff --git a/app/views/proposal/show.html.haml b/app/views/proposal/show.html.haml index 1dc45052..aaa1d379 100644 --- a/app/views/proposal/show.html.haml +++ b/app/views/proposal/show.html.haml @@ -67,15 +67,15 @@ %dl#proposal-info .col-md-12 %dt Date: - %dd= @event.start_time.strftime("%Y %B %e %H:%M") if @event.start_time + %dd= @event.scheduled_start_time.strftime("%Y %B %e %H:%M") if @event.scheduled_start_time.present? .col-md-12 %dt Duration: %dd= show_time(@event.event_type.length) .col-md-12 %dt Room: %dd - - if @event.room - = @event.room.name + - if @event.scheduled_room + = @event.scheduled_room.name .col-md-12 %dt Conference: %dd= @event.program.conference.title diff --git a/db/migrate/20160704091928_create_schedules.rb b/db/migrate/20160704091928_create_schedules.rb new file mode 100644 index 00000000..9afea760 --- /dev/null +++ b/db/migrate/20160704091928_create_schedules.rb @@ -0,0 +1,9 @@ +class CreateSchedules < ActiveRecord::Migration + def change + create_table :schedules do |t| + t.belongs_to :program, index: true + t.timestamps null: false + end + add_column :programs, :selected_schedule, :integer # Selected schedule ID + end +end diff --git a/db/migrate/20160704092023_create_event_schedules.rb b/db/migrate/20160704092023_create_event_schedules.rb new file mode 100644 index 00000000..3762f7e2 --- /dev/null +++ b/db/migrate/20160704092023_create_event_schedules.rb @@ -0,0 +1,11 @@ +class CreateEventSchedules < ActiveRecord::Migration + def change + create_table :event_schedules do |t| + t.belongs_to :event, index: true + t.belongs_to :schedule, index: true + t.belongs_to :room, index: true + t.datetime :start_time + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 120ea7e5..50c0eb92 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160624151257) do +ActiveRecord::Schema.define(version: 20160704092023) do create_table "ahoy_events", force: :cascade do |t| t.uuid "visit_id", limit: 16 @@ -176,6 +176,19 @@ ActiveRecord::Schema.define(version: 20160624151257) do t.text "cfp_dates_updated_body" end + create_table "event_schedules", force: :cascade do |t| + t.integer "event_id" + t.integer "schedule_id" + t.integer "room_id" + t.datetime "start_time" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "event_schedules", ["event_id"], name: "index_event_schedules_on_event_id" + add_index "event_schedules", ["room_id"], name: "index_event_schedules_on_room_id" + add_index "event_schedules", ["schedule_id"], name: "index_event_schedules_on_schedule_id" + create_table "event_types", force: :cascade do |t| t.string "title", null: false t.integer "length", default: 30 @@ -261,6 +274,7 @@ ActiveRecord::Schema.define(version: 20160624151257) do t.boolean "blind_voting", default: false t.datetime "voting_start_date" t.datetime "voting_end_date" + t.integer "selected_schedule" end create_table "qanswers", force: :cascade do |t| @@ -335,6 +349,14 @@ ActiveRecord::Schema.define(version: 20160624151257) do t.integer "venue_id", null: false end + create_table "schedules", force: :cascade do |t| + t.integer "program_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "schedules", ["program_id"], name: "index_schedules_on_program_id" + create_table "splashpages", force: :cascade do |t| t.integer "conference_id" t.boolean "public" diff --git a/lib/tasks/several_schedules.rake b/lib/tasks/several_schedules.rake new file mode 100644 index 00000000..d1c9d81c --- /dev/null +++ b/lib/tasks/several_schedules.rake @@ -0,0 +1,24 @@ +namespace :data do + desc 'Move the start_time and room attributes from Event to EventSchedule' + + task move_events_attributes: :environment do + Program.all.each do |program| + schedule = Schedule.create(program: program) + program.selected_schedule = schedule.id + program.save + program.events.each do |event| + unless event.start_time.nil? && event.room_id.nil? + # we can not use .room as this relation has been removed + EventSchedule.create(event: event, + schedule: schedule, + start_time: event.start_time, + room_id: event.room_id) + event.start_time = nil + event.room_id = nil + event.save + end + end + end + puts 'The start_time and room attributes has been moved from Event to EventSchedule' + end +end