property_hire/app/models/property.rb

145 lines
4.0 KiB
Ruby

class Property
include Mongoid::Document
include Mongoid::Timestamps
include OrbitTag::Taggable
include OrbitCategory::Categorizable
include Slug
field :title, as: :slug_title, :localize => true
field :property_usage, :localize => true
field :note, :localize => true
field :property_number
field :can_be_hired, type: Boolean, default: true
field :purchase_date, type: DateTime
field :owners, type: Array, :default => []
field :other_owner
field :owner_email
field :owner_phone
field :price
field :other_location
mount_uploader :image, ImageUploader
# unavailibility fields
field :set_unavailibility, type: Boolean, default: false
field :start_time
field :end_time
field :weekdays, type: Array, default: []
field :start_date, type: DateTime
field :end_date, type: DateTime
field :description, :localize => true
field :unavailibility_note, :localize => true
belongs_to :property_location
has_many :p_hires
has_many :hire_email_sets, :autosave => true, :dependent => :destroy, :inverse_of => :property
accepts_nested_attributes_for :hire_email_sets, :allow_destroy => true
WEEKDAYS = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
]
def get_location_name
return self.property_location.nil? ? self.other_location : self.property_location.title
end
def owner_profiles
MemberProfile.find(self.owners) rescue []
end
def is_available_for_hire?(stime, etime)
return true if self.set_unavailibility == false
return true if self.weekdays.empty?
return true if !self.start_date.nil? && (self.start_date > stime && self.start_date > etime)
return true if !self.end_date.nil? && self.end_date < stime
startt = self.start_date.nil? ? self.created_at : self.start_date
endt = self.end_date.nil? && !startt.nil? ? (startt + 5.years) : self.end_date
weekdays = self.weekdays.collect{|w| w.to_i}
if !startt.nil?
common_dates = (startt..endt) & (stime..etime)
return true if common_dates.nil?
time_weekdays = []
Property.time_iterate(common_dates.min, common_dates.max, 1.day) do |t|
time_weekdays << t.wday
end
time_weekdays.uniq!
weekdays = weekdays & time_weekdays
return true if weekdays.blank?
startt = DateTime.parse(stime.strftime("%Y-%m-%d " + self.start_time + Time.zone.to_s))
endt = DateTime.parse(etime.strftime("%Y-%m-%d " + self.end_time + Time.zone.to_s))
common_dates = (startt..endt) & (stime..etime)
if common_dates.nil?
return true
else
return false
end
end
end
def is_already_hired?(stime, etime, interval, recurring_end_date)
bookings = self.p_hires.where(:end_time.gte => stime, :recurring => false)
available = true
bookings.each do |booking|
common_time = (booking.start_time..booking.end_time) & (stime..etime)
if !common_time.nil?
available = false
break
end
end
if available
case interval
when "week"
stepu = 1.week
when "month"
stepu = 1.month
else
stepu = 0
end
bookings = self.p_hires.where(:recurring_end_date.gte => stime, :recurring => true)
bookings.each do |booking|
booking.time_iterate do |st,et|
tst = stime
tet = etime
if stepu != 0
begin
common_time = (tst..tet) & (st..et)
available = false if !common_time.nil?
tet += stepu
break if !available
break if tst > st
end while (tst += stepu) <= recurring_end_date
else
common_time = (tst..tet) & (st..et)
available = false if !common_time.nil?
break if !available
end
break if !available
end
break if !available
end
end
return available
end
def self.time_iterate(start_time, end_time, step, &block)
begin
yield(start_time, end_time)
end while (start_time += step) <= end_time
end
end