2015-05-05 03:10:25 +02:00
|
|
|
class Availability < ActiveRecord::Base
|
2016-03-23 18:39:41 +01:00
|
|
|
has_many :machines_availabilities, dependent: :destroy
|
|
|
|
has_many :machines, through: :machines_availabilities
|
|
|
|
accepts_nested_attributes_for :machines, allow_destroy: true
|
|
|
|
|
|
|
|
has_many :trainings_availabilities, dependent: :destroy
|
|
|
|
has_many :trainings, through: :trainings_availabilities
|
|
|
|
|
|
|
|
has_many :slots
|
|
|
|
has_many :reservations, through: :slots
|
2015-05-05 03:10:25 +02:00
|
|
|
|
|
|
|
has_one :event
|
|
|
|
|
2016-03-23 18:39:41 +01:00
|
|
|
has_many :availability_tags, dependent: :destroy
|
|
|
|
has_many :tags, through: :availability_tags
|
|
|
|
accepts_nested_attributes_for :tags, allow_destroy: true
|
|
|
|
|
|
|
|
scope :machines, -> { where(available_type: 'machines') }
|
|
|
|
scope :trainings, -> { where(available_type: 'training') }
|
|
|
|
|
|
|
|
attr_accessor :is_reserved, :slot_id, :can_modify
|
|
|
|
|
2016-04-05 09:57:09 +02:00
|
|
|
validates :start_at, :end_at, presence: true
|
|
|
|
validate :length_must_be_1h_minimum, unless: proc { end_at.blank? or start_at.blank? }
|
2016-03-23 18:39:41 +01:00
|
|
|
validate :should_be_associated
|
|
|
|
|
|
|
|
def safe_destroy
|
|
|
|
if available_type == 'machines'
|
|
|
|
reservations = Reservation.where(reservable_type: 'Machine', reservable_id: machine_ids).joins(:slots).where('slots.availability_id = ?', id)
|
|
|
|
else
|
|
|
|
reservations = Reservation.where(reservable_type: 'Training', reservable_id: training_ids).joins(:slots).where('slots.availability_id = ?', id)
|
|
|
|
end
|
|
|
|
if reservations.size == 0
|
|
|
|
# this update may not call any rails callbacks, that's why we use direct SQL update
|
|
|
|
update_column(:destroying, true)
|
|
|
|
destroy
|
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def title
|
|
|
|
if available_type == 'machines'
|
|
|
|
machines.map(&:name).join(' - ')
|
|
|
|
else
|
|
|
|
trainings.map(&:name).join(' - ')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# return training reservations is complete?
|
|
|
|
# if haven't defined a nb_total_places, places are unlimited
|
|
|
|
def is_completed
|
|
|
|
return false if nb_total_places.blank?
|
|
|
|
nb_total_places <= slots.where(canceled_at: nil).size
|
|
|
|
end
|
|
|
|
|
|
|
|
def nb_total_places
|
|
|
|
if read_attribute(:nb_total_places).present?
|
|
|
|
read_attribute(:nb_total_places)
|
|
|
|
else
|
|
|
|
trainings.first.nb_total_places unless trainings.empty?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def length_must_be_1h_minimum
|
|
|
|
if end_at < (start_at + 1.hour)
|
2016-04-04 17:42:45 +02:00
|
|
|
errors.add(:end_at, I18n.t('availabilities.must_be_at_least_1_hour_after_the_start_date'))
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def should_be_associated
|
|
|
|
if available_type == 'machines' and machine_ids.count == 0
|
2016-04-04 17:42:45 +02:00
|
|
|
errors.add(:machine_ids, I18n.t('availabilities.must_be_associated_with_at_least_1_machine'))
|
2016-03-23 18:39:41 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-05-05 03:10:25 +02:00
|
|
|
end
|