module ActsAsBookable::Bookable::Core::InstanceMethods
Public Instance Methods
Accept a booking by a booker. This is an alias method, equivalent to @booker.book!(@bookable, opts)
@param booker The booker model @param opts The booking options
Example:
@room.be_booked!(@user, from: Date.today, to: Date.tomorrow, amount: 2)
# File lib/acts_as_bookable/bookable/core.rb, line 269 def be_booked!(booker, opts={}) booker.book!(self, opts) end
# File lib/acts_as_bookable/bookable/core.rb, line 283 def booker? self.class.booker? end
Check availability of current bookable
@param opts The booking options @return true if the bookable is available for given options, otherwise return false
Example:
@room.check_availability!(from: Date.today, to: Date.tomorrow, amount: 2)
# File lib/acts_as_bookable/bookable/core.rb, line 252 def check_availability(opts) begin check_availability!(opts) rescue ActsAsBookable::AvailabilityError false end end
Check availability of current bookable, raising an error if the bookable is not available
@param opts The booking options @return true if the bookable is available for given options @raise ActsAsBookable::AvailabilityError
if the bookable is not available for given options
Example:
@room.check_availability!(from: Date.today, to: Date.tomorrow, amount: 2)
# File lib/acts_as_bookable/bookable/core.rb, line 164 def check_availability!(opts) # validates options self.validate_booking_options!(opts) # Capacity check (done first because it doesn't require additional queries) if self.booking_opts[:capacity_type] != :none # Amount > capacity if opts[:amount] > self.capacity raise ActsAsBookable::AvailabilityError.new ActsAsBookable::T.er('.availability.amount_gt_capacity', model: self.class.to_s) end end ## # Time check # if self.booking_opts[:time_type] == :range time_check_ok = true # If it's bookable across recurrences, just check start time and end time if self.booking_opts[:bookable_across_occurrences] # Check start time if !(ActsAsBookable::TimeUtils.time_in_schedule?(self.schedule, opts[:time_start])) time_check_ok = false end # Check end time if !(ActsAsBookable::TimeUtils.time_in_schedule?(self.schedule, opts[:time_end])) time_check_ok = false end # If it's not bookable across recurrences, check if the whole interval is included in an occurrence else # Check the whole interval if !(ActsAsBookable::TimeUtils.interval_in_schedule?(self.schedule, opts[:time_start], opts[:time_end])) time_check_ok = false end end # If something went wrong unless time_check_ok raise ActsAsBookable::AvailabilityError.new ActsAsBookable::T.er('.availability.unavailable_interval', model: self.class.to_s, time_start: opts[:time_start], time_end: opts[:time_end]) end end if self.booking_opts[:time_type] == :fixed if !(ActsAsBookable::TimeUtils.time_in_schedule?(self.schedule, opts[:time])) raise ActsAsBookable::AvailabilityError.new ActsAsBookable::T.er('.availability.unavailable_time', model: self.class.to_s, time: opts[:time]) end end ## # Real capacity check (calculated with overlapped bookings) # overlapped = ActsAsBookable::Booking.overlapped(self, opts) # If capacity_type is :closed cannot book if already booked (no matter if amount < capacity) if (self.booking_opts[:capacity_type] == :closed && !overlapped.empty?) raise ActsAsBookable::AvailabilityError.new ActsAsBookable::T.er('.availability.already_booked', model: self.class.to_s) end # if capacity_type is :open, check if amount <= maximum amount of overlapped booking if (self.booking_opts[:capacity_type] == :open && !overlapped.empty?) # if time_type is :range, split in sub-intervals and check the maximum sum of amounts against capacity for each sub-interval if (self.booking_opts[:time_type] == :range) # Map overlapped bookings to a set of intervals with amount intervals = overlapped.map { |e| {time_start: e.time_start, time_end: e.time_end, amount: e.amount} } # Make subintervals from overlapped bookings and check capacity for each of them ActsAsBookable::TimeUtils.subintervals(intervals) do |a,b,op| case op when :open res = {amount: a[:amount] + b[:amount]} when :close res = {amount: a[:amount] - b[:amount]} end raise ActsAsBookable::AvailabilityError.new ActsAsBookable::T.er('.availability.already_booked', model: self.class.to_s) if (res[:amount] > self.capacity) res end # else, just sum the amounts (fixed times are not intervals and they overlap if are the same) else if(overlapped.sum(:amount) + opts[:amount] > self.capacity) raise ActsAsBookable::AvailabilityError.new ActsAsBookable::T.er('.availability.already_booked', model: self.class.to_s) end end end true end
Check if options passed for booking this Bookable
are valid
@raise ActsAsBookable::OptionsInvalid
if options are not valid @param opts The booking options
# File lib/acts_as_bookable/bookable/core.rb, line 279 def validate_booking_options!(opts) self.class.validate_booking_options!(opts) end