added recurring hiring.
This commit is contained in:
parent
0e655ebb61
commit
93ac6d254e
|
@ -145,7 +145,7 @@ class PropertyHiresController < ApplicationController
|
||||||
|
|
||||||
def make_booking
|
def make_booking
|
||||||
booking_p = booking_params
|
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
|
property = Property.find(booking_p[:property_id]) rescue nil
|
||||||
if data["success"] == true
|
if data["success"] == true
|
||||||
hire = PHire.new(booking_p)
|
hire = PHire.new(booking_p)
|
||||||
|
@ -176,7 +176,7 @@ class PropertyHiresController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_availability
|
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
|
render :json => data.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -188,11 +188,13 @@ class PropertyHiresController < ApplicationController
|
||||||
sdt = Time.at(params[:start].to_i)
|
sdt = Time.at(params[:start].to_i)
|
||||||
edt = Time.at(params[:end].to_i)
|
edt = Time.at(params[:end].to_i)
|
||||||
events = PHire.monthly_event(sdt,edt,params[:property_id])
|
events = PHire.monthly_event(sdt,edt,params[:property_id])
|
||||||
|
re = PHire.recurring_event(sdt,edt)
|
||||||
|
allevents = events.inject(re, :<<)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html # index.html.erb
|
format.html # index.html.erb
|
||||||
format.json { render json: events.to_json }
|
format.json { render json: allevents.to_json }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
module Admin::PropertyHiresHelper
|
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)
|
property = Property.find(pid)
|
||||||
return {"success" => false, "msg" => "Values are not ok."} if property.nil? || stime.blank? || etime.blank?
|
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
|
stime = DateTime.parse(stime + Time.zone.to_s) rescue nil
|
||||||
etime = DateTime.parse(etime + 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 = {}
|
data = {}
|
||||||
return {"success" => false, "msg" => "Starting time cannot be greater than ending time."} if stime > etime
|
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_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}
|
data = {"success" => true}
|
||||||
else
|
else
|
||||||
data = {"success" => false, "msg" => "Property is already hired during this time."}
|
data = {"success" => false, "msg" => "Property is already hired during this time."}
|
||||||
|
|
|
@ -2,6 +2,8 @@ class PHire
|
||||||
include Mongoid::Document
|
include Mongoid::Document
|
||||||
include Mongoid::Timestamps
|
include Mongoid::Timestamps
|
||||||
|
|
||||||
|
INTERVALS = ["week", "month"]
|
||||||
|
|
||||||
field :start_time, type: DateTime
|
field :start_time, type: DateTime
|
||||||
field :end_time, type: DateTime
|
field :end_time, type: DateTime
|
||||||
field :hiring_person_email
|
field :hiring_person_email
|
||||||
|
@ -11,6 +13,9 @@ class PHire
|
||||||
field :reason_for_hire
|
field :reason_for_hire
|
||||||
field :note_for_hire
|
field :note_for_hire
|
||||||
field :passed, type: Boolean, default: false
|
field :passed, type: Boolean, default: false
|
||||||
|
field :recurring, type: Boolean, :default => false
|
||||||
|
field :recurring_end_date, type: DateTime
|
||||||
|
field :recurring_interval
|
||||||
|
|
||||||
belongs_to :property
|
belongs_to :property
|
||||||
|
|
||||||
|
@ -39,7 +44,59 @@ class PHire
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.monthly_event(start_date,end_date,property_id)
|
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
|
||||||
|
|
||||||
end
|
end
|
|
@ -81,8 +81,8 @@ class Property
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_already_hired?(stime, etime)
|
def is_already_hired?(stime, etime, interval, recurring_end_date)
|
||||||
bookings = self.p_hires.where(:end_time.gte => stime)
|
bookings = self.p_hires.where(:end_time.gte => stime, :recurring => false)
|
||||||
available = true
|
available = true
|
||||||
bookings.each do |booking|
|
bookings.each do |booking|
|
||||||
common_time = (booking.start_time..booking.end_time) & (stime..etime)
|
common_time = (booking.start_time..booking.end_time) & (stime..etime)
|
||||||
|
@ -91,12 +91,36 @@ class Property
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
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
|
return available
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.time_iterate(start_time, end_time, step, &block)
|
def self.time_iterate(start_time, end_time, step, &block)
|
||||||
begin
|
begin
|
||||||
yield(start_time)
|
yield(start_time, end_time)
|
||||||
end while (start_time += step) <= end_time
|
end while (start_time += step) <= end_time
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -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;"} %>
|
<%= 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;"} %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- ############# recurring ############# -->
|
||||||
|
<div class="form-group">
|
||||||
|
<%= f.label :recurring, t("property_hires.recurring"), :class => "col-sm-2 control-label" %>
|
||||||
|
<div class="col-sm-1">
|
||||||
|
<%= f.check_box :recurring %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="recurring-block" <%= hire.recurring ? "" : "style=display:none;" %>>
|
||||||
|
<div class="form-group">
|
||||||
|
<%= f.label :recurring_interval, t("property_hires.recurring_interval"), :class => "col-sm-2 control-label" %>
|
||||||
|
<div class="col-sm-1">
|
||||||
|
<%= f.select :recurring_interval, PHire::INTERVALS.collect{|int| [t("property_hire.recurring_interval_types.#{int}"), int] }, {:prompt => "Select interval"}, {:data => {"fv-validation" => "requiredifrecurring;" , "fv-messages" => "Cannot be empty;"}} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<%= f.label :recurring_end_date, t("property_hires.recurring_end_date"), :class => "col-sm-2 control-label" %>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<%= f.datetime_picker :recurring_end_date, :no_label => true, :new_record => hire.new_record?, :data=>{"fv-validation" => "requiredifrecurring;", "fv-messages" => "Cannot be empty;"} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-offset-2 col-sm-5">
|
<div class="col-sm-offset-2 col-sm-5">
|
||||||
<div id="property-avaialable-alert" style="margin-bottom: 5px; padding: 10px; display: none;" class="alert alert-success" role="alert"><b>Hooray! </b>This property is available.</div>
|
<div id="property-avaialable-alert" style="margin-bottom: 5px; padding: 10px; display: none;" class="alert alert-success" role="alert"><b>Hooray! </b>This property is available.</div>
|
||||||
<div id="property-unavaialable-alert" style="margin-bottom: 5px; padding: 10px; display: none;" class="alert alert-danger" role="alert"><b>Sorry! </b><span> This property is available.</span></div>
|
<div id="property-unavaialable-alert" style="margin-bottom: 5px; padding: 10px; display: none;" class="alert alert-danger" role="alert"><b>Sorry! </b><span> This property is available.</span></div>
|
||||||
|
<div id="values-alert" style="margin-bottom: 5px; padding: 10px; display: none;" class="alert alert-warning" role="alert"><b>Please! </b><span> Select an interval time and recurring event end date.</span></div>
|
||||||
</div>
|
</div>
|
||||||
<% if property.set_unavailibility %>
|
<% if property.set_unavailibility %>
|
||||||
<div class="col-sm-offset-2 col-sm-5">
|
<div class="col-sm-offset-2 col-sm-5">
|
||||||
|
@ -116,13 +140,29 @@
|
||||||
var el = $(this),
|
var el = $(this),
|
||||||
url = $(this).attr("href"),
|
url = $(this).attr("href"),
|
||||||
spinner = $("#spinner");
|
spinner = $("#spinner");
|
||||||
el.hide();
|
|
||||||
spinner.show();
|
|
||||||
$(".alert").hide();
|
$(".alert").hide();
|
||||||
|
data = {
|
||||||
|
"stime" : $("#p_hire_start_time").val(),
|
||||||
|
"etime" : $("#p_hire_end_time").val(),
|
||||||
|
"property_id" : property_id
|
||||||
|
}
|
||||||
|
if($("#p_hire_recurring").is(":checked")){
|
||||||
|
var interval = $("#p_hire_recurring_interval").val(),
|
||||||
|
recurring_end_date = $("#p_hire_recurring_end_date").val();
|
||||||
|
if(interval == "" || recurring_end_date == ""){
|
||||||
|
$("#values-alert").show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data["interval"] = interval;
|
||||||
|
data["recurring_end_date"] = recurring_end_date;
|
||||||
|
}
|
||||||
|
spinner.show();
|
||||||
|
el.hide();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
"url" : url,
|
"url" : url,
|
||||||
"type" : "post",
|
"type" : "get",
|
||||||
"data" : {"stime" : $("#p_hire_start_time").val(), "etime" : $("#p_hire_end_time").val(), "property_id" : property_id},
|
"data" : data,
|
||||||
"dataType" : "json"
|
"dataType" : "json"
|
||||||
}).done(function(data){
|
}).done(function(data){
|
||||||
if(data.success){
|
if(data.success){
|
||||||
|
@ -146,6 +186,21 @@
|
||||||
hireForm.validate_functions.checkForDates = function(value,element){
|
hireForm.validate_functions.checkForDates = function(value,element){
|
||||||
return value == "1";
|
return value == "1";
|
||||||
}
|
}
|
||||||
|
hireForm.validate_functions.requiredifrecurring = function(value, element){
|
||||||
|
if($("#p_hire_recurring").is(":checked")){
|
||||||
|
return value != "";
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#p_hire_recurring").on("click",function(){
|
||||||
|
if($(this).is(":checked")){
|
||||||
|
$("#recurring-block").slideDown();
|
||||||
|
}else{
|
||||||
|
$("#recurring-block").slideUp();
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
en:
|
en:
|
||||||
property_hire:
|
property_hire:
|
||||||
|
recurring: Recurring
|
||||||
|
recurring_interval: Recurring Interval
|
||||||
|
recurring_interval_types:
|
||||||
|
month: Month
|
||||||
|
week: Week
|
||||||
|
recurring_end_date: Recurring End Date
|
||||||
save: Save
|
save: Save
|
||||||
property_hire: Property
|
property_hire: Property
|
||||||
manage_locations: Manage Locations
|
manage_locations: Manage Locations
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
zh_tw:
|
zh_tw:
|
||||||
property_hire:
|
property_hire:
|
||||||
|
recurring: Recurring
|
||||||
|
recurring_interval: Recurring Interval
|
||||||
|
recurring_interval_types:
|
||||||
|
month: Month
|
||||||
|
week: Week
|
||||||
|
recurring_end_date: Recurring End Date
|
||||||
save: Save
|
save: Save
|
||||||
property_hire: Property
|
property_hire: Property
|
||||||
manage_locations: Manage Locations
|
manage_locations: Manage Locations
|
||||||
|
|
|
@ -2,7 +2,7 @@ Rails.application.routes.draw do
|
||||||
|
|
||||||
locales = Site.find_by(site_active: true).in_use_locales rescue I18n.available_locales
|
locales = Site.find_by(site_active: true).in_use_locales rescue I18n.available_locales
|
||||||
scope "(:locale)", locale: Regexp.new(locales.join("|")) do
|
scope "(:locale)", locale: Regexp.new(locales.join("|")) do
|
||||||
post "/xhr/property_hires/check_availability" => "property_hires#check_availability"
|
get "/xhr/property_hires/check_availability" => "property_hires#check_availability"
|
||||||
post "/xhr/property_hires/make_booking" => "property_hires#make_booking"
|
post "/xhr/property_hires/make_booking" => "property_hires#make_booking"
|
||||||
get "/xhr/property_hires/get_bookings" => "property_hires#get_bookings"
|
get "/xhr/property_hires/get_bookings" => "property_hires#get_bookings"
|
||||||
namespace :admin do
|
namespace :admin do
|
||||||
|
|
Loading…
Reference in New Issue