class Event < ActiveRecord::Base include NotifyWith::NotificationAttachedObject has_one :event_image, as: :viewable, dependent: :destroy accepts_nested_attributes_for :event_image, allow_destroy: true has_many :event_files, as: :viewable, dependent: :destroy accepts_nested_attributes_for :event_files, allow_destroy: true, reject_if: :all_blank belongs_to :category validates :category, presence: true has_many :reservations, as: :reservable, dependent: :destroy has_and_belongs_to_many :event_themes, join_table: :events_event_themes, dependent: :destroy has_many :event_price_categories, dependent: :destroy has_many :price_categories, through: :event_price_categories accepts_nested_attributes_for :event_price_categories, allow_destroy: true belongs_to :age_range belongs_to :availability, dependent: :destroy accepts_nested_attributes_for :availability attr_accessor :recurrence, :recurrence_end_at after_create :event_recurrence before_save :update_nb_free_places # update event updated_at for index cache after_save -> { self.touch } def name title end def themes self.event_themes end def recurrence_events Event.includes(:availability).where('events.recurrence_id = ? AND events.id != ? AND availabilities.start_at >= ?', recurrence_id, id, Time.now).references(:availabilities) end def safe_destroy reservations = Reservation.where(reservable_type: 'Event', reservable_id: id) if reservations.size == 0 destroy else false end end ## # @deprecated # DEPRECATED: Please use event_price_categories instead. # This method is for backward compatibility only, do not use in new code def reduced_amount if ActiveRecord::Base.connection.column_exists?(:events, :reduced_amount) read_attribute(:reduced_amount) else pc = PriceCategory.find_by(name: I18n.t('price_category.reduced_fare')) reduced_fare = event_price_categories.where(price_category: pc).first if reduced_fare.nil? nil else reduced_fare.amount end end end # def reservations # Reservation.where(reservable: self) # end private def event_recurrence if recurrence.present? and recurrence != 'none' case recurrence when 'day' on = nil when 'week' on = availability.start_at.wday when 'month' on = availability.start_at.day when 'year' on = [availability.start_at.month, availability.start_at.day] else end r = Recurrence.new(every: recurrence, on: on, starts: availability.start_at+1.day, until: recurrence_end_at) r.events.each do |date| days_diff = availability.end_at.day - availability.start_at.day start_at = DateTime.new(date.year, date.month, date.day, availability.start_at.hour, availability.start_at.min, availability.start_at.sec, availability.start_at.zone) end_date = date + days_diff.days end_at = DateTime.new(end_date.year, end_date.month, end_date.day, availability.end_at.hour, availability.end_at.min, availability.end_at.sec, availability.end_at.zone) if event_image ei = EventImage.new(attachment: event_image.attachment) end efs = event_files.map do |f| EventFile.new(attachment: f.attachment) end event_price_cats = [] event_price_categories.each do |epc| event_price_cats.push(EventPriceCategory.new(price_category_id: epc.price_category_id, amount: epc.amount)) end event = Event.new({ recurrence: 'none', title: title, description: description, event_image: ei, event_files: efs, availability: Availability.new(start_at: start_at, end_at: end_at, available_type: 'event'), availability_id: nil, category_id: category_id, age_range_id: age_range_id, event_themes: event_themes, amount: amount, event_price_categories: event_price_cats, nb_total_places: nb_total_places, recurrence_id: id }) event.save end update_columns(recurrence_id: id) end end def update_nb_free_places if nb_total_places.nil? self.nb_free_places = nil else reserved_places = reservations.map(&:total_booked_seats).inject(0){|sum, t| sum + t } self.nb_free_places = (nb_total_places - reserved_places) end end end