diff --git a/app/controllers/property_hires_controller.rb b/app/controllers/property_hires_controller.rb index ca567b3..f8126bb 100644 --- a/app/controllers/property_hires_controller.rb +++ b/app/controllers/property_hires_controller.rb @@ -145,7 +145,7 @@ class PropertyHiresController < ApplicationController def make_booking booking_p = booking_params - data = check_for_availability(booking_p[:start_time],booking_p[:end_time],booking_p[:property_id]) + data = check_for_availability(booking_p[:start_time],booking_p[:end_time],booking_p[:property_id], booking_p[:recurring_interval], booking_p[:recurring_end_date]) property = Property.find(booking_p[:property_id]) rescue nil if data["success"] == true hire = PHire.new(booking_p) @@ -176,7 +176,7 @@ class PropertyHiresController < ApplicationController end def check_availability - data = check_for_availability params[:stime], params[:etime], params[:property_id] + data = check_for_availability params[:stime], params[:etime], params[:property_id], params[:interval], params[:recurring_end_date] render :json => data.to_json end @@ -188,11 +188,13 @@ class PropertyHiresController < ApplicationController sdt = Time.at(params[:start].to_i) edt = Time.at(params[:end].to_i) events = PHire.monthly_event(sdt,edt,params[:property_id]) + re = PHire.recurring_event(sdt,edt) + allevents = events.inject(re, :<<) end end respond_to do |format| format.html # index.html.erb - format.json { render json: events.to_json } + format.json { render json: allevents.to_json } end end diff --git a/app/helpers/admin/property_hires_helper.rb b/app/helpers/admin/property_hires_helper.rb index 749208b..f51613a 100644 --- a/app/helpers/admin/property_hires_helper.rb +++ b/app/helpers/admin/property_hires_helper.rb @@ -1,14 +1,15 @@ module Admin::PropertyHiresHelper - def check_for_availability(stime, etime, pid) + def check_for_availability(stime, etime, pid, interval, recurring_end_date) property = Property.find(pid) return {"success" => false, "msg" => "Values are not ok."} if property.nil? || stime.blank? || etime.blank? stime = DateTime.parse(stime + Time.zone.to_s) rescue nil etime = DateTime.parse(etime + Time.zone.to_s) rescue nil + recurring_end_date = DateTime.parse(recurring_end_date + Time.zone.to_s) rescue nil data = {} return {"success" => false, "msg" => "Starting time cannot be greater than ending time."} if stime > etime if property.is_available_for_hire?(stime, etime) - if property.is_already_hired?(stime, etime) + if property.is_already_hired?(stime, etime, interval, recurring_end_date) data = {"success" => true} else data = {"success" => false, "msg" => "Property is already hired during this time."} diff --git a/app/models/p_hire.rb b/app/models/p_hire.rb index 9f6cdd0..f737f0b 100644 --- a/app/models/p_hire.rb +++ b/app/models/p_hire.rb @@ -2,6 +2,8 @@ class PHire include Mongoid::Document include Mongoid::Timestamps + INTERVALS = ["week", "month"] + field :start_time, type: DateTime field :end_time, type: DateTime field :hiring_person_email @@ -11,6 +13,9 @@ class PHire field :reason_for_hire field :note_for_hire field :passed, type: Boolean, default: false + field :recurring, type: Boolean, :default => false + field :recurring_end_date, type: DateTime + field :recurring_interval belongs_to :property @@ -39,7 +44,59 @@ class PHire end def self.monthly_event(start_date,end_date,property_id) - self.where(:property_id => property_id).any_of(:start_time.gte => start_date, :end_time.gte => start_date).and(:start_time.lte => end_date).asc(:start_time) + self.where(:property_id => property_id, :recurring => false).any_of(:start_time.gte => start_date, :end_time.gte => start_date).and(:start_time.lte => end_date).asc(:start_time) + end + + def self.recurring_event(start_date,end_date) + @recurring_events = self.where(:recurring => true) + @recurring = [] + @recurring_events.each do |re| + case re.recurring_interval + when "week" + @start_date = re.start_time + @end_date = re.end_time + @i = TimeDifference.between(re.start_time,end_date).in_weeks.to_i + (0..@i).each do |i| + if i > 0 + @start_date += 7 + @end_date += 7 + end + if @start_date < re.recurring_end_date + @recurring << {:id => re.id.to_s, :title=>re.reason_for_hire, :note=>re.reason_for_hire, :start=>@start_date, :end => @end_date, :allDay => false, :recurring => re.recurring, :color => "#FC4040"} + end + end + when "month" + # if !(start_date..end_date).cover?(re.start_time) + sd = re.start_time + ed = re.end_time + @i = TimeDifference.between(re.start_time,end_date).in_months.to_i + @start_date = sd + # debugger + sd = sd >> @i + ed = ed >> @i + if sd < re.recurring_end_date + @recurring << {:id => re.id.to_s, :title=>re.reason_for_hire, :note=>re.reason_for_hire, :start=>sd, :end => ed, :allDay => false, :recurring => re.recurring, :color => "#FC4040"} + end + # end + end + end + @recurring + end + + def time_iterate(&block) + start_time = self.start_time + end_time = self.end_time + recurring_end_date = self.recurring_end_date + case self.recurring_interval + when "week" + step_interval = 1.week + when "month" + step_interval = 1.month + end + begin + yield(start_time, end_time) + end_time += step_interval + end while (start_time += step_interval) <= recurring_end_date end end \ No newline at end of file diff --git a/app/models/property.rb b/app/models/property.rb index 8569a8e..59306d5 100644 --- a/app/models/property.rb +++ b/app/models/property.rb @@ -81,8 +81,8 @@ class Property end end - def is_already_hired?(stime, etime) - bookings = self.p_hires.where(:end_time.gte => stime) + 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) @@ -91,12 +91,36 @@ class Property break end end + if available + case interval + when "week" + stepu = 1.week + when "month" + stepu = 1.month + 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 + 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 + 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) + yield(start_time, end_time) end while (start_time += step) <= end_time end diff --git a/app/views/property_hires/hire.html.erb b/app/views/property_hires/hire.html.erb index 63a83a8..4a157ec 100644 --- a/app/views/property_hires/hire.html.erb +++ b/app/views/property_hires/hire.html.erb @@ -39,10 +39,34 @@ <%= f.datetime_picker :end_time, :no_label => true, :new_record => hire.new_record?, :data=>{"picker-type" => "range", "range" => "end", "fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %> + +