200 lines
7.4 KiB
Ruby
200 lines
7.4 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
|
|
field :organization
|
|
field :person_in_charge
|
|
field :tel_of_person_in_charge
|
|
field :department
|
|
field :contact_person
|
|
field :tel_of_contact_person
|
|
field :mobile_phone_of_contact_person
|
|
field :contact_person_Email
|
|
field :contact_person_department
|
|
field :enable_notes_selector , type: Boolean, default: false
|
|
field :notes_selector ,type: Hash, default: {}
|
|
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, interval = nil, recurring_end_date = nil)
|
|
available = false
|
|
return true if self.set_unavailibility == false
|
|
return true if self.weekdays.empty?
|
|
available = true if !self.start_date.nil? && (self.start_date > stime && self.start_date > etime)
|
|
available = 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?
|
|
if !available
|
|
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)
|
|
available = common_dates.nil?
|
|
end
|
|
if available
|
|
if !recurring_end_date.blank?
|
|
case interval
|
|
when 'week'
|
|
d_step = 1.week
|
|
when 'month'
|
|
d_step = 1.month
|
|
else
|
|
d_step = 0
|
|
end
|
|
if d_step != 0
|
|
if etime >= stime
|
|
(etime.to_i..recurring_end_date.to_i).step(d_step).to_a.each_with_index do|time_integer,index|
|
|
date_time = Time.at(time_integer).to_datetime
|
|
new_etime = date_time
|
|
new_stime = stime + (new_etime - etime)
|
|
available = self.is_available_for_hire?(new_stime, new_etime, nil, nil)
|
|
break if !available
|
|
end
|
|
else
|
|
available = false
|
|
end
|
|
end
|
|
end
|
|
return available
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
def not_yet_hired?(stime, etime, interval, recurring_end_date)
|
|
phires = self.p_hires
|
|
bookings_count = phires.where(:start_time.lte => stime,:end_time.gte => stime,:recurring => false).count
|
|
+ phires.where(:start_time.gte => stime,:end_time.lte => etime,:recurring => false).count
|
|
+phires.where(:start_time.lte => etime,:end_time.gte => etime,:recurring => false).count
|
|
available = true
|
|
if bookings_count != 0
|
|
available = false
|
|
end
|
|
if available
|
|
bookings = phires.where(:recurring_end_date.gte => stime, :recurring => true) + phires.where(:recurring => false,:recurring_end_date => nil) + phires.where(:recurring => false,:recurring_end_date.gte => stime)
|
|
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_interval == 'week') && booking.recurring_end_date.nil?
|
|
b_interval = nil
|
|
end
|
|
while true
|
|
if b_interval == 'month'
|
|
diff_month = booking.end_time.month - booking.start_time.month
|
|
diff_month = diff_month + 12 if diff_month < 0
|
|
e_month = stime_tp.month + diff_month
|
|
e_year = stime_tp.year + (booking.end_time.year-booking.start_time.year)
|
|
e_month = e_month - 12 if e_month >12
|
|
b_sdata = Time.local(stime_tp.year,stime_tp.month,booking.start_time.day,booking.start_time.hour,booking.start_time.minute).to_datetime
|
|
b_edata = Time.local(e_year,e_month,booking.end_time.day,booking.end_time.hour,booking.end_time.minute).to_datetime
|
|
elsif b_interval == 'week'
|
|
diff_day = booking.end_time - booking.start_time
|
|
if (booking.end_time.wday <= booking.start_time.wday && diff_day>1) || diff_day > 7
|
|
over_one_week = true
|
|
end
|
|
b_sdata_tp = stime_tp - stime_tp.wday.day + booking.start_time.wday.day
|
|
b_sdata = Time.local(b_sdata_tp.year,b_sdata_tp.month,b_sdata_tp.day,booking.start_time.hour,booking.start_time.minute).to_datetime
|
|
if over_one_week && etime_tp.wday <= booking.start_time.wday
|
|
b_sdata = b_sdata - 7.day
|
|
end
|
|
now_diff_day = etime_tp - stime_tp
|
|
if (etime_tp.wday <= stime_tp.wday && now_diff_day>1) || now_diff_day > 7
|
|
b_sdata = b_sdata + 7.day
|
|
end
|
|
b_edata_tp = b_sdata + (booking.end_time - booking.start_time).to_i.day
|
|
b_edata = Time.local(b_edata_tp.year,b_edata_tp.month,b_edata_tp.day,booking.end_time.hour,booking.end_time.minute).to_datetime
|
|
else
|
|
b_sdata = booking.start_time
|
|
b_edata = booking.end_time
|
|
end
|
|
sdata = stime_tp
|
|
edata = etime_tp
|
|
if etime_tp > booking.start_time
|
|
if (sdata <= b_sdata && edata >= b_sdata) || (sdata >= b_sdata && edata <= b_edata) || (sdata <= b_edata && edata >= b_edata)
|
|
available = false
|
|
end
|
|
end
|
|
stime_tp = stime_tp + d_step
|
|
etime_tp = etime_tp + d_step
|
|
break if recurring_end_date.blank? || d_step==0 || 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 |