class PropertyHiresController < ApplicationController include Admin::PropertyHiresHelper FrontendMethods = ["hire", "view_calendar", "hire_success"] def index properties = Property.can_display.filter_by_categories.sort_order url = "/#{I18n.locale}#{OrbitHelper.page.get_url}" data = index_data(properties, url) headers = [ { "column" => t("property_hire.title") }, { "column" => "" }, { "column" => t("property_hire.location") }, { "column" => t("property_hire.actions") } ] { "properties" => data, "headers" => headers, "extras" => { "first_property_id" => data.first["id"] }, "manage_booking_btn" => (OrbitHelper.current_user.nil? ? false : true), "manage_booking" => t("property_hire.manage_booking"), "manage_booking_url" => "/" + OrbitHelper.get_site_locale.to_s + "/admin/property_hires/my_bookings", "total_pages" => (properties.total_pages rescue 1) } end def index_data(properties, url) ma = ModuleApp.find_by_key("property_hire") is_user_manager = OrbitHelper.current_user && (OrbitHelper.current_user.is_admin? || OrbitHelper.current_user.is_manager?(ma) || OrbitHelper.current_user.is_sub_manager?(ma)) data = properties.collect do |property| actions = [] url_to_show = "#{url}/#{property.to_param}?method=hire" hire_url = nil if (property.can_be_hired_frontend && property.can_reserve) || is_user_manager hire_url = url_to_show actions << { "text" => t("property_hire.hire"), "btn-class" => "btn-primary", "link" => hire_url } end if (!property.disable_view_calendar_page && property.can_be_show_frontend && property.can_reserve) || is_user_manager actions << { "text" => t("property_hire.view_calendar"), "btn-class" => "btn-info", "link" => url_to_show } end if property.disable_content_page if hire_url url_to_show = hire_url end end { "title" => property.title, "id" => property.id.to_s, "image" => (property.image.url.blank? ? '" style="display: none;' : property.image.url), "image-thumb" => (property.image.thumb.url.blank? ? '" style="display: none;' : property.image.thumb.url), "url_to_show" => url_to_show, "location" => property.get_location_name, "actions" => actions } end end def widget properties = Property.filter_by_widget_categories.sort_order.can_display url = OrbitHelper.get_current_widget.get_read_more_page_url data = index_data(properties, url) headers = [ { "column" => t("property_hire.title") }, { "column" => t("property_hire.location") }, { "column" => t("property_hire.actions") } ] { "properties" => data, "headers" => headers, "total_pages" => (properties.total_pages rescue 1) } end def show params = OrbitHelper.params property = Property.where(:uid => params[:uid]).first rescue nil page = Page.where(:page_id => params[:page_id]).first return {} if property.nil? data = [] data << { "header" => t("property_hire.title"), "value" => property.title } if !property.property_usage.blank? data << { "header" => t("property_hire.property_usage"), "value" => property.property_usage } end if !property.note.blank? data << { "header" => t("property_hire.note"), "value" => property.note } end if !property.property_number.blank? data << { "header" => t("property_hire.property_number"), "value" => property.property_number } end data << { "header" => t("property_hire.can_be_hired"), "value" => (property.can_be_hired ? "Yes" : "No") } if !property.purchase_date.to_s.blank? data << { "header" => t("property_hire.purchase_date"), "value" => property.purchase_date.strftime("%Y-%m-%d") } end if property.owners.blank? owners = property.other_owner else owners = property.owner_profiles.collect{|mp| mp.name}.join(",") end if !owners.blank? data << { "header" => t("property_hire.owners"), "value" => owners } end if !property.owner_email.blank? data << { "header" => t("property_hire.owner_email"), "value" => property.owner_email } end if !property.owner_phone.blank? data << { "header" => t("property_hire.owner_phone"), "value" => property.owner_phone } end if !property.price.blank? data << { "header" => t("property_hire.price"), "value" => property.price } end if !property.get_location_name.blank? data << { "header" => t("property_hire.location"), "value" => property.get_location_name } end actions = [] url_to_show = OrbitHelper.url_to_show(property.to_param) if property.can_be_hired_frontend actions << { "text" => t("property_hire.hire"), "btn-class" => "btn-primary", "link" => url_to_show + "?method=hire" } end if !property.disable_view_calendar_page && property.can_be_show_frontend actions << { "text" => t("property_hire.view_calendar"), "btn-class" => "btn-info", "link" => url_to_show + "?method=view_calendar" } end { "data" => data, "actions" => actions, "extras" => { "image" => property.image.url, "image-thumb" => property.image.thumb.url, "back_url" => page.url } } end def view_calendar params = OrbitHelper.params property = Property.where(:uid => params[:uid]).first rescue nil if property.disable_view_calendar_page || !property.can_be_show_frontend return nil end page = Page.where(:page_id => params[:page_id]).first return {} if property.nil? { "property" => property, "url" => page.url, "current_user" => OrbitHelper.current_user } end def hire_success params = OrbitHelper.params @property = Property.where(:uid => params[:uid]).first rescue nil page = OrbitHelper.page rescue Page.where(:page_id => params[:page_id]).first back_button_text = I18n.t("property_hire.go_to_infos_page") back_url = (page.url + (params[:slug].present? ? "/#{params[:slug]}" : "") rescue "#") if @property.disable_content_page back_url += "?method=hire" if params[:slug].present? back_button_text = I18n.t("property_hire.back_to_hire_page") end {"back_url"=>back_url,"back_button_text"=>back_button_text} end def make_booking booking_p = booking_params time_setting_id = booking_p[:time] start_time = booking_p[:start_time] end_time = booking_p[:end_time] time_setting = nil is_admin_page = (params[:url] == "admin") if time_setting_id.present? 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].split(" ")[0] + ' ' + time_setting.end_time + Time.zone.to_s) end booking_p[:start_time] = booking_p[:date] + " " + time_setting.start_time booking_p[:end_time] = booking_p[:date] + " " + time_setting.end_time booking_p[:property_day_setting_id] = booking_p[:time] booking_p.delete(:time) end property = Property.find(booking_p[:property_id]) rescue nil begin index_page = is_admin_page ? "/#{I18n.locale}/admin/property_hires/#{property.to_param}" : "/#{I18n.locale}#{params[:url]}/#{property.to_param}" rescue index_page = is_admin_page ? "/#{I18n.locale}/admin/property_hires" : "/#{I18n.locale}#{params[:url]}" end hire_page = is_admin_page ? request.referer : "#{index_page}?method=hire" need_validate = (PropertyHireSetting.first.allow_no_logins_user rescue false) && current_user.nil? session.delete(:hire_data) if need_validate unless gotcha_valid? session[:hire_data] = booking_p session["hire-save-msg"] = I18n.t("property_hire.recaptcha.errors.verification_failed") if property.nil? redirect_to index_page and return else redirect_to hire_page and return end end end phire_id = params[:phire_id] || params[:p_hire][:id] if params[:url] == "admin" phire_id = booking_p[:id] 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) if data["success"] == true error_messages = property.check_require_fields(booking_p) if error_messages.present? data["msg"] = error_messages data["success"] = false end end if data["success"] == true hire = nil if phire_id hire = PHire.find(phire_id) rescue nil if hire.nil? hire = PHire.new(booking_p) else hire.update_attributes(booking_p) end else hire = PHire.new(booking_p) end hire.passed = true if PropertyHireSetting.auto_approve_enabled? hire.save if !property.nil? && !is_admin_page email = property.get_owner_emails email << hire.hiring_person_email email = email.select{|e| e.present?} Admin::PropertyHiresHelper::HireMethod.send_mail('p_hire',email,property.id,nil,hire.id,(current_user.id rescue nil)) end redirect_to index_page + "?method=hire_success" else session[:hire_data] = booking_p session["hire-save-msg"] = data["msg"] if property.nil? redirect_to index_page else redirect_to hire_page end end end def hire params = OrbitHelper.params property = Property.where(:uid => params[:uid]).first rescue nil if !property.can_be_hired_frontend return nil end page = Page.where(:page_id => params[:page_id]).first return {} if property.nil? hire = nil session = OrbitHelper.request.session rescue {} recover = false if (session[:hire_data] rescue false) begin if session[:hire_data][:property_id] != property.id.to_s session.delete(:hire_data) hire = PHire.new(:id=>nil) else hire = PHire.new({:id=>nil}.merge(session[:hire_data])) recover = true end rescue => e puts e.to_s hire = PHire.new(:id=>nil) end else hire = PHire.new(:id=>nil) end allow_no_logins_user = PropertyHireSetting.first.allow_no_logins_user all_day_settings = property.all_day_settings.map{|d,settings| [d,settings.map{|s| [s.id.to_s,s.title]}]}.to_h ma = ModuleApp.find_by_key("property_hire") is_user_manager = OrbitHelper.current_user && (OrbitHelper.current_user.is_admin? || OrbitHelper.current_user.is_manager?(ma) || OrbitHelper.current_user.is_sub_manager?(ma)) { "hire" => hire, "property" => property, "page" => page.url, "is_user_manager" => is_user_manager, "current_user" => OrbitHelper.current_user, "allow_no_logins_user" => allow_no_logins_user, "carousel_display_style" => "width: #{property.carousel_image_width};", "all_day_settings" => all_day_settings, "recover" => recover } end def check_availability time_setting_id = params[:time_setting_id] data = check_for_availability params[:stime], params[:etime], params[:property_id], params[:interval], params[:recurring_end_date], time_setting_id render :json => data.to_json end def get_bookings events =[] allevents = [] property = @property = Property.find(params[:property_id]) rescue nil unless property.nil? 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],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, :<<) allevents = allevents.sort_by{|e| e[:start]} @need_check_events = allevents.map{|e| [e[:date],e[:s_id]]} @special_unavailable_dates = property.special_unavailable_dates.map{|dt| Date.parse(dt)} ma = ModuleApp.find_by_key("property_hire") is_user_manager = OrbitHelper.current_user && (OrbitHelper.current_user.is_admin? || OrbitHelper.current_user.is_manager?(ma) || OrbitHelper.current_user.is_sub_manager?(ma)) if property.set_availability && params[:display_hire_event] == "true" check_setting = property.set_unavailibility && (property.property_day_settings.where(:enable=>false).count != 0) @check_start_time = property.start_time.blank? ? "00:00" : property.start_time @check_end_time = property.end_time.blank? ? "24:00" : property.end_time @check_start_date = property.start_date ? property.start_date.to_date : nil @check_end_date = property.end_date ? property.end_date.to_date : nil if check_setting if (@check_start_date && @check_start_date > edt) || (@check_end_date && @check_end_date < sdt) check_setting = false end end all_day_settings = property.all_day_settings.map{|d,settings| [d,settings.map{|s| [s.start_time,s.end_time,s.id.to_s,s.title,s.reservation_limit,s.enable]}]}.to_h if all_day_settings.count != 0 time_now = Time.zone.now if is_user_manager get_start_time = property.p_open_start_time get_end_time = property.p_open_end_time else get_start_time = [sdt,time_now].max get_end_time = edt end if property.set_unavailibility if property.can_hire_before_months != 0 get_end_time = [time_now + (property.can_hire_before_months).send("month"),edt].min end end if property.can_reserve || is_user_manager allevents += generate_all_reserve_buttons(get_start_time,get_end_time,all_day_settings,check_setting) end end end if @special_unavailable_dates.count > 0 allevents += special_unavailable_dates_labels(property) end end end respond_to do |format| format.html { render json: allevents.to_json }# index.html.erb format.json { render json: allevents.to_json } end end def special_unavailable_dates_labels(property) events = [] @special_unavailable_dates.each_with_index do |dt, idx| events << {:title=>property.special_unavailable_dates_title[idx][OrbitHelper.get_site_locale], :start=>dt.to_s, :end => (dt + 1.day).to_s, :allDay => true, :color => "#d33535", :classNames=>["special_unavailable_btn"], :note => ""} end events end def reserve_calendar_event(date,title,allow_times) available = true if @special_unavailable_dates.include?(date) available = false end need_check_unavailable = (@check_start_date.nil? || date >= @check_start_date) && (@check_end_date.nil? || date <= @check_end_date) if need_check_unavailable if @property.hours_restriction > 0 && @is_user_manager === false check = false sd = nil ed = nil case @property.hours_restriction_duration when "week" weeknumber = date.strftime("%U").to_i if @weeknumber != weeknumber sd = date - date.wday ed = date + (6 - date.wday) @weeknumber = weeknumber check = true end when "month" if @monthnumber != date.month sd = Date.new(date.year, date.month, 1) ed = sd.next_month.prev_day @monthnumber = date.month check = true end end if check === true @user_total_hired_hours = @property.get_user_total_user_hired_hours(OrbitHelper.current_user.id.to_s, sd, ed) end if @user_total_hired_hours >= @property.hours_restriction available = false end end end if available if need_check_unavailable available = date > (DateTime.now + (@property.need_hire_before).send(@property.need_hire_before_unit)) end end if @check_setting && allow_times.select{|a| !a[5]}.count != 0 available = !need_check_unavailable if available available = @property.weekdays.include?(date.wday.to_s) ? false : true end unless available allow_times = allow_times.select do |allow_time| if allow_time[5] true elsif (allow_time[0] > @check_end_time || allow_time[1] < @check_start_time) true elsif false end end available = (allow_times.count != 0) end end if available {:title=>title, :start=>date.to_s, :end => (date + 1.day).to_s, :allDay => true, :color => "#3788d8",:allow_times=>allow_times,:classNames=>["reserve_btn"]} else {} end end def generate_all_reserve_buttons(startt,endt,all_day_settings,check_setting=false) @check_setting = check_setting @display_title = I18n.t("property_hire.reserve") @allevents = [] startt = startt.in_time_zone(Time.zone) endt = endt.in_time_zone(Time.zone) start_wday = startt.wday start_date = startt.to_date @start_date = start_date end_date = endt.to_date @end_date = end_date @first_check_time = startt.strftime("%H:%M") @all_day_settings = all_day_settings @startt = startt @endt = endt @weeknumber = 0 @monthnumber = 0 ma = ModuleApp.find_by_key("property_hire") @is_user_manager = OrbitHelper.current_user && (OrbitHelper.current_user.is_admin? || OrbitHelper.current_user.is_manager?(ma) || OrbitHelper.current_user.is_sub_manager?(ma)) def generate_events(start_wday,end_wday,type=0,start_validate=false) if type == 0 (start_wday..end_wday).each_with_index do |wday,i| wday_str = wday.to_s 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? if @need_check_events.length != 0 && @need_check_events[-1][0] <= @start_date i = @need_check_events.length - 1 else i = -1 end elsif i != -1 i -= 1 end check_events = [] if i != -1 check_events = @need_check_events[0..i] end @need_check_events = @need_check_events[(i+1)..-1] settings = @all_day_settings[wday_str] if check_events.count != 0 settings = settings.select do |s| flag = true if check_time if check_time > s[1] flag = false end end if flag if s[4] == 0 #reservation_limit == 0 => no limit true else check_events.select{|e| e[1] == s[2] }.count < s[4] end else false end end end if settings.count != 0 @allevents << reserve_calendar_event(@start_date,@display_title,settings) end end @start_date += 1.day if @start_date > @end_date break end end else @all_day_settings.each do |wday_str,settings| tmp_date = @start_date + wday_str.to_i.send("day") i = @need_check_events.index{|e| e[0] > tmp_date} if i.nil? if @need_check_events.length != 0 && @need_check_events[-1][0] <= tmp_date i = @need_check_events.length - 1 else i = -1 end elsif i != -1 i -= 1 end check_events = [] if i != -1 check_events = @need_check_events[0..i] end @need_check_events = @need_check_events[(i+1)..-1] if check_events.count != 0 settings = settings.select do |s| 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 @allevents << reserve_calendar_event(tmp_date,@display_title,settings) end end @start_date += 7.day end end all_days = (end_date-start_date).to_i end_wday = 6 end_date_wday = end_date.wday only_first_week = false if (start_wday + all_days <= 6) end_wday = end_date_wday only_first_week = true end 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,1) all_days -= 7 end generate_events(0,all_days) end @allevents end private def booking_params p_hire_params = params.require(:p_hire).permit! property = Property.find(params[:p_hire][:property_id]) rescue Property.last if(property.enable_notes_selector rescue false) note_texts = "" property.notes_selector.each do |index,sub_hash| name = sub_hash["name"][I18n.locale.to_s] name = sub_hash["name"].values.select{|v| v.present?}.first.to_s if name.blank? values = sub_hash["value"][I18n.locale.to_s] values = sub_hash["value"].values.select{|v| v.present?}.first.to_s if values.blank? value_text = p_hire_params["notes_selector"][index.to_s].to_a.map{|i| values[i.to_i]}.join(",") rescue "" value_text = I18n.t("property_hire.none") if value_text.blank? note_texts += (name + ":"+value_text) note_texts += "
".html_safe end p_hire_params["note_for_hire"] = note_texts p_hire_params.delete("notes_selector") end return p_hire_params end end