property_hire/app/models/property.rb

156 lines
5.1 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(:start_time.lte => stime,:end_time.gte => stime,:recurring => false)
.or(:start_time.gte => stime,:end_time.lte => etime,:recurring => false)
.or(:start_time.lte => etime,:end_time.gte => etime,:recurring => false)
available = true
if bookings.count != 0
available = false
end
if available
bookings = self.p_hires.where(:recurring_end_date.gte => stime, :recurring => true).or(:recurring => false)
case interval
when 'week'
d_step = 1.week
when 'month'
d_step = 1.month
else
d_step = 0
end
bookings.each do |booking|
stime_tp = stime
etime_tp = etime
b_interval = booking.recurring_interval
if b_interval == 'month'
b_sdata = booking.start_time.day*10000 + booking.start_time.hour*100 + booking.start_time.minute
b_edata = booking.end_time.day*10000 + booking.end_time.hour*100 + booking.end_time.minute
elsif b_interval == 'week'
b_sdata = booking.start_time.wday*10000 + booking.start_time.hour*100 + booking.start_time.minute
b_edata = booking.end_time.wday*10000 + booking.end_time.hour*100 + booking.end_time.minute
else
b_sdata = booking.start_time
b_edata = booking.end_time
end
while true
if b_interval == 'month'
sdata = stime_tp.day*10000 + stime_tp.hour*100 + stime_tp.minute
edata = etime_tp.day*10000 + etime_tp.hour*100 + etime_tp.minute
elsif b_interval == 'week'
sdata = stime_tp.wday*10000 + stime_tp.hour*100 + stime_tp.minute
edata = etime_tp.wday*10000 + etime_tp.hour*100 + etime_tp.minute
else
sdata = stime_tp
edata = etime_tp
end
if (sdata <= b_sdata && edata >= b_sdata) || (sdata >= b_sdata && edata <= b_edata) || (sdata <= b_edata && edata >= b_edata)
available = false
end
stime_tp = stime_tp + d_step
etime_tp = etime_tp + d_step
break if recurring_end_date.nil? || recurring_end_date < stime_tp
end
break if available == false
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