osem-fcy/app/models/event.rb

354 lines
11 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
class Event < ApplicationRecord
2013-01-07 09:04:09 +01:00
include ActiveRecord::Transitions
2017-01-04 22:27:46 -05:00
include RevisionCount
has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id }
2014-02-23 16:09:09 +02:00
2013-01-07 09:04:09 +01:00
acts_as_commentable
after_create :set_week
2014-06-24 12:14:53 +03:00
has_many :event_users, dependent: :destroy
has_many :users, through: :event_users
has_many :speaker_event_users, -> { where(event_role: 'speaker') }, class_name: 'EventUser'
has_many :speakers, through: :speaker_event_users, source: :user
has_one :submitter_event_user, -> { where(event_role: 'submitter') }, class_name: 'EventUser'
has_one :submitter, through: :submitter_event_user, source: :user
2014-07-17 16:48:27 +03:00
has_many :votes, dependent: :destroy
2014-06-24 12:14:53 +03:00
has_many :voters, through: :votes, source: :user
has_many :commercials, as: :commercialable, dependent: :destroy
2018-02-23 11:52:27 +02:00
has_many :surveys, as: :surveyable, dependent: :destroy
2013-01-07 09:04:09 +01:00
belongs_to :event_type
2013-08-16 12:46:49 +03:00
2016-04-22 18:18:46 +03:00
has_many :events_registrations
has_many :registrations, through: :events_registrations
has_many :event_schedules, dependent: :destroy
2013-01-07 09:04:09 +01:00
belongs_to :track
2014-02-23 16:09:09 +02:00
belongs_to :difficulty_level
belongs_to :program
2013-01-07 09:04:09 +01:00
2014-06-24 12:14:53 +03:00
accepts_nested_attributes_for :event_users, allow_destroy: true
accepts_nested_attributes_for :speakers, allow_destroy: true
2014-06-23 19:07:50 +03:00
accepts_nested_attributes_for :users
2013-01-07 09:04:09 +01:00
before_create :generate_guid
2013-01-16 08:22:20 +01:00
2013-01-07 09:04:09 +01:00
validate :abstract_limit
validate :before_end_of_conference, on: :create
2014-06-24 12:14:53 +03:00
validates :title, presence: true
validates :abstract, presence: true
validates :event_type, presence: true
validates :program, presence: true
validates :speakers, presence: true
2016-04-22 18:18:46 +03:00
validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true }
validate :max_attendees_no_more_than_room_size
Implement track scheduling Add track association to schedule Show schedules in admin sidebar to track organizers Allow track organizers to manage the schedules of their tracks Don't allow self-organized track events to be dragged or unscheduled in a conference schedule Make scheduled events of self-organized tracks appear semitransparent in conference schedules Make the rooms of confirmed self_organized tracks appear semitransparent and don't allow events to be scheduled to it in the conference schedules during the dates of its track Create admin/SchedulesController#new action Add a button in admin/Schedules#index to create schedules for tracks Add self_organized scope to Track Modify Schedules#show to handle track schedules and show a unified schedule Allow track organizers to create new schedules for their tracks Correctly identify scheduled and unscheduled events in Schedules#events Fix Event#room and Event#time for when the event is scheduled in a track schedule Modify Program#selected_event_schedules to include the event_schedules of selected track schedules Modify Track#revoke_role_and_cleanup to destroy the track's schedules and revert its events' state to new Add tabs for conference and track schedules in admin/Schedules#index Add button to Create/Show a tracks schedule in Tracks#index and #show Fix concurrent_events in application_helper because of changes in Program#selected_event_schedules Do not take into account cfp_active in Event#valid_track Modify EventsController#get_tracks accordingly Enforce cfp_active of track to be enabled for proposals in ProposalsController#create and #update Add support for multiple schedules per track Add selected_schedule_id to Track Load EventSchedules of selected track schedules for conference schedules in admin/SchedulesController#show Modify SchedulesController#show to take into account only the selected track schedules Create Event#selected_schedule_id and use it in Event#scheduled? and Event#time Validate that an EventSchedule for an event of a self-organized track belongs to one of the track's schedules Add 'Manage' button in Tracks#index, #show that sends you to the admin side of things Add admin/TracksController#update_selected_schedule to update the selected_schedule_id of tracks
2017-08-09 18:12:20 +03:00
validate :valid_track
2013-01-07 09:04:09 +01:00
2014-04-23 15:45:55 +02:00
scope :confirmed, -> { where(state: 'confirmed') }
2016-07-13 18:36:22 +05:30
scope :canceled, -> { where(state: 'canceled') }
scope :withdrawn, -> { where(state: 'withdrawn') }
scope :highlighted, -> { where(is_highlight: true) }
2013-07-16 18:42:22 +02:00
2014-06-24 12:14:53 +03:00
state_machine initial: :new do
2013-01-07 09:04:09 +01:00
state :new
state :withdrawn
state :unconfirmed
state :confirmed
state :canceled
state :rejected
2014-06-06 10:23:01 +02:00
event :restart do
transitions to: :new, from: [:rejected, :withdrawn, :canceled]
2013-01-07 09:04:09 +01:00
end
event :withdraw do
2014-06-06 10:23:01 +02:00
transitions to: :withdrawn, from: [:new, :unconfirmed, :confirmed]
2013-01-07 09:04:09 +01:00
end
event :accept do
2014-06-06 10:23:01 +02:00
transitions to: :unconfirmed, from: [:new], on_transition: :process_acceptance
2013-01-07 09:04:09 +01:00
end
event :confirm do
2014-06-06 10:23:01 +02:00
transitions to: :confirmed, from: :unconfirmed, on_transition: :process_confirmation
2013-01-07 09:04:09 +01:00
end
event :cancel do
2014-06-06 10:23:01 +02:00
transitions to: :canceled, from: [:unconfirmed, :confirmed]
2013-01-07 09:04:09 +01:00
end
event :reject do
2014-06-06 10:23:01 +02:00
transitions to: :rejected, from: [:new], on_transition: :process_rejection
2013-01-07 09:04:09 +01:00
end
end
2016-04-22 18:18:46 +03:00
##
# Checkes if the event has a start_time and a room for the selected schedule if there is any
2016-04-22 18:18:46 +03:00
# ====Returns
# * +true+ or +false+
def scheduled?
Implement track scheduling Add track association to schedule Show schedules in admin sidebar to track organizers Allow track organizers to manage the schedules of their tracks Don't allow self-organized track events to be dragged or unscheduled in a conference schedule Make scheduled events of self-organized tracks appear semitransparent in conference schedules Make the rooms of confirmed self_organized tracks appear semitransparent and don't allow events to be scheduled to it in the conference schedules during the dates of its track Create admin/SchedulesController#new action Add a button in admin/Schedules#index to create schedules for tracks Add self_organized scope to Track Modify Schedules#show to handle track schedules and show a unified schedule Allow track organizers to create new schedules for their tracks Correctly identify scheduled and unscheduled events in Schedules#events Fix Event#room and Event#time for when the event is scheduled in a track schedule Modify Program#selected_event_schedules to include the event_schedules of selected track schedules Modify Track#revoke_role_and_cleanup to destroy the track's schedules and revert its events' state to new Add tabs for conference and track schedules in admin/Schedules#index Add button to Create/Show a tracks schedule in Tracks#index and #show Fix concurrent_events in application_helper because of changes in Program#selected_event_schedules Do not take into account cfp_active in Event#valid_track Modify EventsController#get_tracks accordingly Enforce cfp_active of track to be enabled for proposals in ProposalsController#create and #update Add support for multiple schedules per track Add selected_schedule_id to Track Load EventSchedules of selected track schedules for conference schedules in admin/SchedulesController#show Modify SchedulesController#show to take into account only the selected track schedules Create Event#selected_schedule_id and use it in Event#scheduled? and Event#time Validate that an EventSchedule for an event of a self-organized track belongs to one of the track's schedules Add 'Manage' button in Tracks#index, #show that sends you to the admin side of things Add admin/TracksController#update_selected_schedule to update the selected_schedule_id of tracks
2017-08-09 18:12:20 +03:00
event_schedules.find_by(schedule_id: selected_schedule_id).present?
end
2016-04-22 18:18:46 +03:00
def registration_possible?
2016-05-15 14:01:30 +03:00
return false unless require_registration && state == 'confirmed'
return true if max_attendees.nil?
2016-04-22 18:18:46 +03:00
registrations.count < max_attendees
end
2016-07-05 16:44:53 +03:00
##
# Finds the rating of the user for the event
# ====Returns
# * +integer+ -> the rating of the user for the event
def user_rating(user)
(vote = votes.find_by(user: user)) ? vote.rating : 0
end
##
# Checks if the event has votes
# If a user is provided, it checks if the event has votes by the user
# ====Returns
# * +true+ -> If the event has votes (optionally, by the user)
# * +false+ -> If the event does not have any votes (optionally, by the user)
def voted?(user=nil)
return votes.where(user: user).any? if user
votes.any?
2013-08-16 12:46:49 +03:00
end
2014-06-23 19:07:50 +03:00
2013-08-16 12:46:49 +03:00
def average_rating
@total_rating = 0
2014-06-26 15:43:24 +03:00
votes.each do |vote|
@total_rating += vote.rating
2013-08-16 12:46:49 +03:00
end
2014-06-26 15:43:24 +03:00
@total = votes.size
@total_rating > 0 ? number_with_precision(@total_rating / @total.to_f, precision: 2, strip_insignificant_zeros: true) : 0
2013-08-16 12:46:49 +03:00
end
# get event speakers with the event sumbmitter at the first position
# if the submitter is also a speaker for this event
def speakers_ordered
speakers_list = speakers.to_a
if speakers_list.reject! { |speaker| speaker == submitter }
speakers_list.unshift(submitter)
2013-01-07 09:04:09 +01:00
end
speakers_list
2013-01-07 09:04:09 +01:00
end
2014-02-23 16:09:09 +02:00
2013-01-07 09:04:09 +01:00
def transition_possible?(transition)
2014-06-26 15:43:24 +03:00
self.class.state_machine.events_for(current_state).include?(transition)
2013-01-07 09:04:09 +01:00
end
2014-06-06 10:23:01 +02:00
def process_confirmation
if program.conference.email_settings.send_on_confirmed_without_registration? &&
program.conference.email_settings.confirmed_without_registration_body &&
program.conference.email_settings.confirmed_without_registration_subject
if program.conference.registrations.where(user_id: submitter.id).first.nil?
Mailbot.confirm_reminder_mail(self).deliver_later
2013-02-12 19:17:19 +01:00
end
end
end
2014-02-23 16:09:09 +02:00
2013-01-07 09:04:09 +01:00
def process_acceptance(options)
if program.conference.email_settings.send_on_accepted &&
program.conference.email_settings.accepted_body &&
program.conference.email_settings.accepted_subject &&
!options[:send_mail].blank?
Mailbot.acceptance_mail(self).deliver_later
end
end
2013-01-07 09:04:09 +01:00
def process_rejection(options)
if program.conference.email_settings.send_on_rejected &&
program.conference.email_settings.rejected_body &&
program.conference.email_settings.rejected_subject &&
!options[:send_mail].blank?
Mailbot.rejection_mail(self).deliver_later
end
2013-01-07 09:04:09 +01:00
end
def abstract_word_count
2015-04-17 15:37:21 +02:00
abstract.to_s.split.size
2013-01-07 09:04:09 +01:00
end
2014-02-23 16:09:09 +02:00
def self.get_state_color(state)
2015-04-17 16:33:30 +02:00
color = {
new: '#0000FF', # blue
withdrawn: '#FF8000', # orange
confirmed: '#00FF00', # green
unconfirmed: '#FFFF00', # yellow
rejected: '#FF0000', # red
canceled: '#848484' # grey
}[state.to_sym]
color || '#00FFFF' # azure
end
def update_state(transition, mail = false, subject = false, send_mail = false, send_mail_param)
alert = ''
if mail && send_mail_param && subject && send_mail
alert = 'Update Email Subject before Sending Mails'
end
begin
if mail
send(transition,
send_mail: send_mail_param)
else
send(transition)
end
save
# If the event was previously scheduled, and then withdrawn or cancelled
# its event_schedule will have enabled set to false
# If the event is now confirmed again, we want it to be available for scheduling
Rails.logger.debug "transition is #{transition}"
if transition == :confirm
Rails.logger.debug "schedules #{EventSchedule.unscoped.where(event: self, enabled: false)}"
EventSchedule.unscoped.where(event: self, enabled: false).destroy_all
end
rescue Transitions::InvalidTransition => e
alert = "Update state failed. #{e.message}"
end
alert
end
def speaker_names
speakers.map(&:name).join(', ')
end
# Returns emails of all the speaker belongs to a particular event
def speaker_emails
2017-10-13 23:33:43 +05:30
speakers.map(&:email).join(', ')
end
##
#
# Returns +Hash+
def progress_status
{
registered: speakers.all? { |speaker| program.conference.user_registered? speaker },
commercials: commercials.any?,
biographies: speakers.all? { |speaker| !speaker.biography.blank? },
subtitle: !subtitle.blank?,
track: (!track.blank? unless program.tracks.empty?),
difficulty_level: !difficulty_level.blank?,
title: true,
abstract: true
}.with_indifferent_access
end
##
# Returns the progress of the proposal's set up
#
# ====Returns
# * +String+ -> Progress in Percent
def calculate_progress
result = progress_status
(100 * result.values.count(true) / result.values.compact.count).to_s
end
##
# Returns the room in which the event is scheduled
#
def room
# We use try(:selected_schedule_id) because this function is used for
# validations so program could not be present there
Implement track scheduling Add track association to schedule Show schedules in admin sidebar to track organizers Allow track organizers to manage the schedules of their tracks Don't allow self-organized track events to be dragged or unscheduled in a conference schedule Make scheduled events of self-organized tracks appear semitransparent in conference schedules Make the rooms of confirmed self_organized tracks appear semitransparent and don't allow events to be scheduled to it in the conference schedules during the dates of its track Create admin/SchedulesController#new action Add a button in admin/Schedules#index to create schedules for tracks Add self_organized scope to Track Modify Schedules#show to handle track schedules and show a unified schedule Allow track organizers to create new schedules for their tracks Correctly identify scheduled and unscheduled events in Schedules#events Fix Event#room and Event#time for when the event is scheduled in a track schedule Modify Program#selected_event_schedules to include the event_schedules of selected track schedules Modify Track#revoke_role_and_cleanup to destroy the track's schedules and revert its events' state to new Add tabs for conference and track schedules in admin/Schedules#index Add button to Create/Show a tracks schedule in Tracks#index and #show Fix concurrent_events in application_helper because of changes in Program#selected_event_schedules Do not take into account cfp_active in Event#valid_track Modify EventsController#get_tracks accordingly Enforce cfp_active of track to be enabled for proposals in ProposalsController#create and #update Add support for multiple schedules per track Add selected_schedule_id to Track Load EventSchedules of selected track schedules for conference schedules in admin/SchedulesController#show Modify SchedulesController#show to take into account only the selected track schedules Create Event#selected_schedule_id and use it in Event#scheduled? and Event#time Validate that an EventSchedule for an event of a self-organized track belongs to one of the track's schedules Add 'Manage' button in Tracks#index, #show that sends you to the admin side of things Add admin/TracksController#update_selected_schedule to update the selected_schedule_id of tracks
2017-08-09 18:12:20 +03:00
if track.try(:self_organized?)
track.room
else
event_schedules.find_by(schedule_id: program.try(:selected_schedule_id)).try(:room)
end
end
##
# Returns the start time at which this event is scheduled
#
def time
Implement track scheduling Add track association to schedule Show schedules in admin sidebar to track organizers Allow track organizers to manage the schedules of their tracks Don't allow self-organized track events to be dragged or unscheduled in a conference schedule Make scheduled events of self-organized tracks appear semitransparent in conference schedules Make the rooms of confirmed self_organized tracks appear semitransparent and don't allow events to be scheduled to it in the conference schedules during the dates of its track Create admin/SchedulesController#new action Add a button in admin/Schedules#index to create schedules for tracks Add self_organized scope to Track Modify Schedules#show to handle track schedules and show a unified schedule Allow track organizers to create new schedules for their tracks Correctly identify scheduled and unscheduled events in Schedules#events Fix Event#room and Event#time for when the event is scheduled in a track schedule Modify Program#selected_event_schedules to include the event_schedules of selected track schedules Modify Track#revoke_role_and_cleanup to destroy the track's schedules and revert its events' state to new Add tabs for conference and track schedules in admin/Schedules#index Add button to Create/Show a tracks schedule in Tracks#index and #show Fix concurrent_events in application_helper because of changes in Program#selected_event_schedules Do not take into account cfp_active in Event#valid_track Modify EventsController#get_tracks accordingly Enforce cfp_active of track to be enabled for proposals in ProposalsController#create and #update Add support for multiple schedules per track Add selected_schedule_id to Track Load EventSchedules of selected track schedules for conference schedules in admin/SchedulesController#show Modify SchedulesController#show to take into account only the selected track schedules Create Event#selected_schedule_id and use it in Event#scheduled? and Event#time Validate that an EventSchedule for an event of a self-organized track belongs to one of the track's schedules Add 'Manage' button in Tracks#index, #show that sends you to the admin side of things Add admin/TracksController#update_selected_schedule to update the selected_schedule_id of tracks
2017-08-09 18:12:20 +03:00
event_schedules.find_by(schedule_id: selected_schedule_id).try(:start_time)
end
##
# Returns true or false, if the event is already over or not
#
# ====Returns
# * +true+ -> If the event is over
# * +false+ -> If the event is not over yet
def ended?
event_schedule = event_schedules.find_by(schedule_id: selected_schedule_id)
return false unless event_schedule
event_schedule.end_time < Time.current
end
2017-01-04 22:27:46 -05:00
def conference
program.conference
end
private
2016-04-22 18:18:46 +03:00
##
# 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)
2016-04-22 18:18:46 +03:00
end
2013-01-07 09:04:09 +01:00
def abstract_limit
# If we don't have an event type, there is no need to count anything
return unless event_type && abstract
2014-06-26 15:43:24 +03:00
len = abstract.split.size
max_words = event_type.maximum_abstract_length
min_words = event_type.minimum_abstract_length
errors.add(:abstract, "cannot have less than #{min_words} words") if len < min_words
errors.add(:abstract, "cannot have more than #{max_words} words") if len > max_words
2013-01-07 09:04:09 +01:00
end
2014-07-21 14:27:32 +02:00
# TODO: create a module to be mixed into model to perform same operation
# venue.rb has same functionality which can be shared
# TODO: rename guid to UUID as guid is specifically Microsoft term
2013-01-07 09:04:09 +01:00
def generate_guid
2014-07-21 14:27:32 +02:00
loop do
@guid = SecureRandom.urlsafe_base64
break unless self.class.where(guid: guid).any?
2014-07-21 14:27:32 +02:00
end
self.guid = @guid
2013-01-07 09:04:09 +01:00
end
def set_week
update!(week: created_at.strftime('%W'))
end
def before_end_of_conference
2017-04-06 23:19:58 -04:00
errors
.add(:created_at, "can't be after the conference end date!") if program.conference&.end_date &&
(Date.today > program.conference.end_date)
end
def conference_id
program.conference_id
end
##
Implement track scheduling Add track association to schedule Show schedules in admin sidebar to track organizers Allow track organizers to manage the schedules of their tracks Don't allow self-organized track events to be dragged or unscheduled in a conference schedule Make scheduled events of self-organized tracks appear semitransparent in conference schedules Make the rooms of confirmed self_organized tracks appear semitransparent and don't allow events to be scheduled to it in the conference schedules during the dates of its track Create admin/SchedulesController#new action Add a button in admin/Schedules#index to create schedules for tracks Add self_organized scope to Track Modify Schedules#show to handle track schedules and show a unified schedule Allow track organizers to create new schedules for their tracks Correctly identify scheduled and unscheduled events in Schedules#events Fix Event#room and Event#time for when the event is scheduled in a track schedule Modify Program#selected_event_schedules to include the event_schedules of selected track schedules Modify Track#revoke_role_and_cleanup to destroy the track's schedules and revert its events' state to new Add tabs for conference and track schedules in admin/Schedules#index Add button to Create/Show a tracks schedule in Tracks#index and #show Fix concurrent_events in application_helper because of changes in Program#selected_event_schedules Do not take into account cfp_active in Event#valid_track Modify EventsController#get_tracks accordingly Enforce cfp_active of track to be enabled for proposals in ProposalsController#create and #update Add support for multiple schedules per track Add selected_schedule_id to Track Load EventSchedules of selected track schedules for conference schedules in admin/SchedulesController#show Modify SchedulesController#show to take into account only the selected track schedules Create Event#selected_schedule_id and use it in Event#scheduled? and Event#time Validate that an EventSchedule for an event of a self-organized track belongs to one of the track's schedules Add 'Manage' button in Tracks#index, #show that sends you to the admin side of things Add admin/TracksController#update_selected_schedule to update the selected_schedule_id of tracks
2017-08-09 18:12:20 +03:00
# Allow only confirmed tracks that belong to the same program as the event
#
def valid_track
return unless track&.program && program
Implement track scheduling Add track association to schedule Show schedules in admin sidebar to track organizers Allow track organizers to manage the schedules of their tracks Don't allow self-organized track events to be dragged or unscheduled in a conference schedule Make scheduled events of self-organized tracks appear semitransparent in conference schedules Make the rooms of confirmed self_organized tracks appear semitransparent and don't allow events to be scheduled to it in the conference schedules during the dates of its track Create admin/SchedulesController#new action Add a button in admin/Schedules#index to create schedules for tracks Add self_organized scope to Track Modify Schedules#show to handle track schedules and show a unified schedule Allow track organizers to create new schedules for their tracks Correctly identify scheduled and unscheduled events in Schedules#events Fix Event#room and Event#time for when the event is scheduled in a track schedule Modify Program#selected_event_schedules to include the event_schedules of selected track schedules Modify Track#revoke_role_and_cleanup to destroy the track's schedules and revert its events' state to new Add tabs for conference and track schedules in admin/Schedules#index Add button to Create/Show a tracks schedule in Tracks#index and #show Fix concurrent_events in application_helper because of changes in Program#selected_event_schedules Do not take into account cfp_active in Event#valid_track Modify EventsController#get_tracks accordingly Enforce cfp_active of track to be enabled for proposals in ProposalsController#create and #update Add support for multiple schedules per track Add selected_schedule_id to Track Load EventSchedules of selected track schedules for conference schedules in admin/SchedulesController#show Modify SchedulesController#show to take into account only the selected track schedules Create Event#selected_schedule_id and use it in Event#scheduled? and Event#time Validate that an EventSchedule for an event of a self-organized track belongs to one of the track's schedules Add 'Manage' button in Tracks#index, #show that sends you to the admin side of things Add admin/TracksController#update_selected_schedule to update the selected_schedule_id of tracks
2017-08-09 18:12:20 +03:00
errors.add(:track, 'is invalid') unless track.confirmed? && track.program == program
end
##
# Return the id of the selected schedule
#
# ====Returns
# * +Integer+ -> selected_schedule_id of self-organized track or program
def selected_schedule_id
if track.try(:self_organized?)
track.selected_schedule_id
else
program.selected_schedule_id
end
end
2013-05-07 17:00:26 +02:00
end