From 3366262e6289e41d5035a591d9eb67d23aa1bcab Mon Sep 17 00:00:00 2001 From: Bohung Date: Tue, 7 Sep 2021 13:07:09 +0800 Subject: [PATCH] Fix bugs. --- .../property_hire_calendar_frontend.js | 7 +- app/controllers/property_hires_controller.rb | 74 +++++++++------ app/models/p_hire.rb | 92 ++++++++++--------- app/models/property.rb | 27 ++++-- app/models/property_hire_setting.rb | 3 + .../admin/property_hires/_time_form.html.erb | 2 +- app/views/property_hires/hire.html.erb | 35 ++++++- config/locales/en.yml | 1 + config/locales/zh_tw.yml | 1 + 9 files changed, 157 insertions(+), 85 deletions(-) diff --git a/app/assets/javascripts/property_hire_calendar_frontend.js b/app/assets/javascripts/property_hire_calendar_frontend.js index a48237e..13355fd 100644 --- a/app/assets/javascripts/property_hire_calendar_frontend.js +++ b/app/assets/javascripts/property_hire_calendar_frontend.js @@ -179,8 +179,8 @@ var Calendar = function(dom,property_id,currentView){ window.calEvent = calEvent; var start_time = calEvent.event.start; var date_str = window.getDateString(start_time,std_date_format); + c.dialog.hide(); var allow_times = calEvent.event._def.extendedProps.allow_times; - console.log(date_str) window.pick_hire_date(date_str,allow_times); }else{ c.dialog.dismiss(); @@ -392,7 +392,10 @@ var EventDialog = function(calendar,event){ event_quick_view.height(new_height); } } - + this.hide = function(){ + calendar.calendar_dom.find('.fc-popover-close').click(); + $(event_quick_view).hide(); + } this.dismiss = function(){ if(event_quick_view) event_quick_view.remove(); diff --git a/app/controllers/property_hires_controller.rb b/app/controllers/property_hires_controller.rb index 994e2ef..a570860 100644 --- a/app/controllers/property_hires_controller.rb +++ b/app/controllers/property_hires_controller.rb @@ -7,7 +7,6 @@ class PropertyHiresController < ApplicationController url_to_show = OrbitHelper.url_to_show(property.to_param) if property.can_be_hired hire_url = url_to_show + "?method=hire" - puts url_to_show actions << { "text" => t("property_hire.hire"), "btn-class" => "btn-primary", @@ -175,6 +174,9 @@ class PropertyHiresController < ApplicationController start_time = booking_p[:date] end_time = start_time time_setting = PropertyDaySetting.find(time_setting_id) + if booking_p[:recurring_end_date].present? + booking_p[:recurring_end_date] = DateTime.parse(booking_p[:recurring_end_date].strftime('%Y-%m-%d') + time_setting.end_time + Time.zone.to_s) + end end data = check_for_availability(start_time,end_time,booking_p[:property_id], booking_p[:recurring_interval], booking_p[:recurring_end_date], time_setting_id) property = Property.find(booking_p[:property_id]) rescue nil @@ -233,15 +235,16 @@ class PropertyHiresController < ApplicationController if params[:start].present? && params[:end].present? 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,params[:property_id]) + events = PHire.monthly_event(sdt,edt,params[:property_id],property.set_availability) + re = PHire.recurring_event(sdt,edt,params[:property_id],property.set_availability) events = events.map{|e| e.as_json} allevents = events.inject(re, :<<) - @need_check_events = allevents.map{|e| [Date.parse(e[:start].split("T")[0]),e[:s_id]]} + allevents = allevents.sort_by{|e| e[:start]} + @need_check_events = allevents.map{|e| [e[:date],e[:s_id]]} if property.set_availability all_day_settings = property.property_day_settings.asc(:key).group_by(&:day).map{|d,settings| [d,settings.map{|s| [s.start_time,s.end_time,s.id.to_s,s.title,s.reservation_limit]}]}.to_h if all_day_settings.count != 0 - time_now = Time.now + time_now = Time.zone.now get_start_time = [sdt,time_now].max get_end_time = edt if property.set_unavailibility @@ -266,7 +269,6 @@ class PropertyHiresController < ApplicationController @display_title = I18n.t("property_hire.reserve") @allevents = [] start_wday = startt.wday - end_flag = false start_date = startt.to_date @start_date = start_date end_date = endt.to_date @@ -275,21 +277,26 @@ class PropertyHiresController < ApplicationController @all_day_settings = all_day_settings @startt = startt @endt = endt - print all_day_settings - puts nil - def generate_events(start_wday,end_wday,type=0) + def generate_events(start_wday,end_wday,type=0,start_validate=false) if type == 0 - (start_wday..end_wday).each do |wday| + (start_wday..end_wday).each_with_index do |wday,i| wday_str = wday.to_s - is_start_day = (start_wday == wday) + is_start_day = (i == 0 && start_validate) if @all_day_settings.has_key?(wday_str) check_time = nil check_time = @first_check_time if is_start_day - i = @need_check_events.index{|e| e[0] > @start_date} - if i.nil? - i = -1 - elsif i != -1 - i -= 1 + i = -1 + if @need_check_events.count == 1 + if @need_check_events[0][0] <= @start_date + i = 0 + end + else + i = @need_check_events.index{|e| e[0] > @start_date} + if i.nil? + i = -1 + elsif i != -1 + i -= 1 + end end check_events = [] if i != -1 @@ -306,10 +313,10 @@ class PropertyHiresController < ApplicationController end end if flag - if s[3] == 0 #reservation_limit == 0 => no limit + if s[4] == 0 #reservation_limit == 0 => no limit true else - @need_check_events.select{|e| e[1] == s[2] }.count <= s[3] + check_events.select{|e| e[1] == s[2] }.count < s[4] end else false @@ -322,19 +329,24 @@ class PropertyHiresController < ApplicationController end @start_date += 1.day if @start_date > @end_date - end_flag = true break end end else @all_day_settings.each do |wday_str,settings| - tmp_date = @start_date + wday_str.to_i.send("day") - check_time = "00:00" - i = @need_check_events.index{|e| e[0] > tmp_date} - if i.nil? - i = -1 - elsif i != -1 - i -= 1 + tmp_date = @start_date + wday_str.to_i.send("day") + i = -1 + if @need_check_events.count == 1 + if @need_check_events[0][0] <= tmp_date + i = 0 + end + else + i = @need_check_events.index{|e| e[0] > tmp_date} + if i.nil? + i = -1 + elsif i != -1 + i -= 1 + end end check_events = [] if i != -1 @@ -343,7 +355,11 @@ class PropertyHiresController < ApplicationController @need_check_events = @need_check_events[(i+1)..-1] if check_events.count != 0 settings = settings.select do |s| - @need_check_events.select{|e| e[1] == s[2] }.count == 0 + if s[4] == 0 #reservation_limit == 0 => no limit + true + else + check_events.select{|e| e[1] == s[2] }.count < s[4] + end end end if settings.count != 0 @@ -361,11 +377,11 @@ class PropertyHiresController < ApplicationController end_wday = end_date_wday only_first_week = true end - generate_events(start_wday,end_wday) + generate_events(start_wday,end_wday,0,true) unless only_first_week all_days = all_days - (end_wday - start_wday) while all_days > 6 do - generate_events(0,6) + generate_events(0,6,1) all_days -= 7 end generate_events(0,all_days) diff --git a/app/models/p_hire.rb b/app/models/p_hire.rb index f0c708b..0d974e0 100644 --- a/app/models/p_hire.rb +++ b/app/models/p_hire.rb @@ -3,7 +3,7 @@ class PHire include Mongoid::Timestamps INTERVALS = ["week", "month"] - + field :date, type: Date field :start_time, type: DateTime field :end_time, type: DateTime field :hiring_person_email @@ -30,18 +30,36 @@ class PHire has_many :p_hire_field_values, :autosave => true, :dependent => :destroy accepts_nested_attributes_for :p_hire_field_values, allow_destroy: true def as_json(options = {}) + startt = self.start_time + endt = self.end_time + recurring = false + datet = self.date + if options[:startt] + startt = options[:startt] + end + if options[:endt] + endt = options[:endt] + end + if options[:datet] + datet = options[:datet] + end + if options[:recurring] + recurring = options[:recurring] + end { :id => self.id.to_s, :title => self.reason_for_hire, :hiring_person_id => self.hiring_person_id, :hiring_person_name => self.hiring_person_name, :note => self.note_for_hire || "", - :start => self.start_time.to_json.gsub('"',''), - :end => self.end_time.to_json.gsub('"',''), + :start => startt.to_json.gsub('"',''), + :end => endt.to_json.gsub('"',''), :allDay => (self.end_time - self.start_time >= 1), :color => (self.passed ? "#3788d8" : "#FC4040"), :error_message => (self.passed ? nil : "Not approved"), - :s_id=>self.property_day_setting_id.to_s + :s_id=>self.property_day_setting_id.to_s, + :date=>datet, + :recurring=>recurring } end @@ -57,11 +75,15 @@ class PHire return MemberProfile.find(self.hiring_person_id) rescue nil end - def self.monthly_event(start_date,end_date,property_id) - 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) + def self.monthly_event(start_date,end_date,property_id,date_ony=false) + events = 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) + if date_ony + events = events.where(:date.ne=>nil) + end + events end - def self.recurring_event(start_date,end_date,property_id) + def self.recurring_event(start_date,end_date,property_id,date_ony=false) @property = Property.find(property_id) rescue nil @recurring = [] if @property != nil @@ -74,44 +96,28 @@ class PHire unavailable_end_date = DateTime.parse(unavailable_end_date.strftime("%Y-%m-%d " + unavailable_end_time.to_s + Time.zone.to_s)) rescue nil unavailable_weekdays = @property.weekdays.collect{|w| w.to_i} @recurring_events = self.where(:property_id => property_id, :recurring_end_date.gte => start_date) + if date_ony + @recurring_events = @recurring_events.where(:date.ne=>nil) + end @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 unavailable && (unavailable_start_date <= @start_date) && (unavailable_end_date >= @end_date) && !((@start_date.strftime("%w").to_i .. @end_date.strftime("%w").to_i).to_a & unavailable_weekdays).empty? - startt = DateTime.parse(@start_date.strftime("%Y-%m-%d " + unavailable_start_time + Time.zone.to_s)) - endt = DateTime.parse(@end_date.strftime("%Y-%m-%d " + unavailable_end_time + Time.zone.to_s)) - next if !((startt..endt) & (@start_date..@end_date)).blank? - end - if @start_date < re.recurring_end_date - @recurring << {:id => re.id.to_s, :hiring_person_name => re.hirer_name ,:title=>re.reason_for_hire, :note=>re.reason_for_hire, :start=>@start_date.to_json.gsub('"',''), :end => @end_date.to_json.gsub('"',''), :allDay => (re.end_time - re.start_time >= 1), :recurring => re.recurring, :color => (re.passed ? "#3788d8" : "#FC4040"), :error_message => (re.passed ? nil : "Not approved"),:s_id=>re.property_day_setting_id.to_s} - end + datet = re.date + interval = 1.send(re.recurring_interval) rescue 0 + if interval != 0 + @start_date = re.start_time + recurring_end_date = re.recurring_end_date + end_date = [recurring_end_date,end_date].min + @end_date = re.end_time + while @start_date <= end_date do + if unavailable && (unavailable_start_date <= @start_date) && (unavailable_end_date >= @end_date) && !((@start_date.strftime("%w").to_i .. @end_date.strftime("%w").to_i).to_a & unavailable_weekdays).empty? + startt = DateTime.parse(@start_date.strftime("%Y-%m-%d " + unavailable_start_time + Time.zone.to_s)) + endt = DateTime.parse(@end_date.strftime("%Y-%m-%d " + unavailable_end_time + Time.zone.to_s)) + next if !((startt..endt) & (@start_date..@end_date)).blank? 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.month - ed = ed + @i.month - if unavailable && !(unavailable_start_date > ed) && !(unavailable_end_date < sd) && !((sd.strftime("%w") .. ed.strftime("%w")).to_a & unavailable_weekdays).empty? - startt = DateTime.parse(sd.strftime("%Y-%m-%d " + unavailable_start_time + Time.zone.to_s)) - endt = DateTime.parse(ed.strftime("%Y-%m-%d " + unavailable_end_time + Time.zone.to_s)) - next if !((startt..endt) & (sd..ed)).blank? - end - if sd < re.recurring_end_date - @recurring << {:id => re.id.to_s, :title=>re.reason_for_hire, :note=>re.reason_for_hire, :start=>sd.to_json.gsub('"',''), :end => ed.to_json.gsub('"',''), :allDay => false, :recurring => re.recurring, :color => "#FC4040"} - end - # end + @recurring << re.as_json({:startt=>@start_date,:endt=>@end_date,:datet=>datet}) + @start_date += interval + @end_date += interval + datet += interval if datet + end end end end diff --git a/app/models/property.rb b/app/models/property.rb index ec13589..03c978c 100644 --- a/app/models/property.rb +++ b/app/models/property.rb @@ -223,8 +223,7 @@ class Property 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 + Property.time_iterate(etime,recurring_end_date,d_step).each do |date_time| new_etime = date_time new_stime = stime + (new_etime - etime) available = self.is_available_for_hire?(new_stime, new_etime, nil, nil) @@ -294,7 +293,7 @@ class Property tmp = {} stime_date = stime.strftime("%Y-%m-%d") bookings = bookings.each_with_index do |booking,i| - if booking.wday != stime.wday + if booking.date.wday != stime.wday next end b_interval = booking.recurring_interval @@ -314,8 +313,8 @@ class Property if b_interval.present? b_interval = (1).send(b_interval) b_sdata = booking.start_time.utc - b_datas = (b_sdata..b_recurring_end_date).step(b_interval).to_a - all_stime_datas = (stime..b_recurring_end_date).step(b_interval).to_a.map{|t| t.utc.strftime("%Y-%m-%d")} + b_datas = Property.time_iterate(b_sdata,b_recurring_end_date,b_interval) + all_stime_datas = Property.time_iterate(stime,b_recurring_end_date,b_interval).map{|t| t.utc.strftime("%Y-%m-%d")} b_datas.each do |b_data| booking_date = b_data.utc.strftime("%Y-%m-%d") if all_stime_datas.include?(booking_date) @@ -345,7 +344,7 @@ class Property b_datas = [] if b_interval.present? b_interval = (1).send(b_interval) - b_datas = (b_edata..b_recurring_end_date).step(b_interval).to_a + b_datas = Property.time_iterate(b_edata,b_recurring_end_date,b_interval) b_datas = b_datas.map{|b_end| [b_end-b_delta,b_end]} start_index = b_datas.count b_datas.each_with_index do |(b_start,b_end),i| @@ -378,9 +377,19 @@ class Property end def self.time_iterate(start_time, end_time, step, &block) - begin - yield(start_time, end_time) - end while (start_time += step) <= end_time + times = [] + if block_given? + begin + times << start_time + yield(start_time, end_time) + end while (start_time += step) <= end_time + else + start_time = start_time.clone + begin + times << start_time + end while (start_time += step) <= end_time + end + times end def carousel_image_width (self.custom_carousel_image_width.blank? ? PropertyHireSetting.last.carousel_image_width : self.custom_carousel_image_width) rescue "75%" diff --git a/app/models/property_hire_setting.rb b/app/models/property_hire_setting.rb index fb02388..782c196 100644 --- a/app/models/property_hire_setting.rb +++ b/app/models/property_hire_setting.rb @@ -9,4 +9,7 @@ class PropertyHireSetting def self.auto_approve_enabled? self.first.auto_approve rescue false end + after_save do + Property.init_class_variables + end end \ No newline at end of file diff --git a/app/views/admin/property_hires/_time_form.html.erb b/app/views/admin/property_hires/_time_form.html.erb index 9aef44f..d056e36 100644 --- a/app/views/admin/property_hires/_time_form.html.erb +++ b/app/views/admin/property_hires/_time_form.html.erb @@ -1,6 +1,6 @@
<% key = (defined?(key) && key) ? key : "new_key" - day = (defined?(day) && day) ? key : "new_day" + day = (defined?(day) && day) ? day : "new_day" %>