441 lines
20 KiB
Plaintext
441 lines
20 KiB
Plaintext
<% OrbitHelper.render_css_in_head(["basic/bootstrap-datetimepicker.css","property_hire_fullcalendar.css","property_hire_calendar"]) %>
|
|
<%= javascript_include_tag "validator.js" %>
|
|
<script src="https://polyfill.io/v3/polyfill.min.js?features=Intl.DateTimeFormat,Intl.DateTimeFormat.~locale.en,Intl.NumberFormat.~locale.en"></script>
|
|
<script type="text/javascript" src="/assets/property_hire_fullcalendar.min.js"></script>
|
|
<script type="text/javascript" src="/assets/property_hire_calendar_frontend.js"></script>
|
|
<%
|
|
data = action_data
|
|
hire = data["hire"]
|
|
property = data["property"]
|
|
url = data["page"]
|
|
current_user = data["current_user"]
|
|
%>
|
|
<% if !property.can_be_hired %>
|
|
<script type="text/javascript">
|
|
alert("This property is unavailable for hire.");
|
|
window.location.href = "<%= "/" + I18n.locale.to_s + url %>";
|
|
</script>
|
|
<% end %>
|
|
<% if current_user.nil? %>
|
|
<script type="text/javascript">
|
|
alert("Please login before you hire.");
|
|
window.location.href = "<%= "/" + I18n.locale.to_s + url %>";
|
|
</script>
|
|
<% else %>
|
|
<h3 class="property_title"><%= property.title %></h3>
|
|
<% if session["hire-save-msg"].present? %>
|
|
<div id="property-unavaialable-alert" class="alert alert-danger" role="alert"><b>Sorry! </b><span> <%= session["hire-save-msg"] %></span></div>
|
|
<% session.delete("hire-save-msg") %>
|
|
<% end %>
|
|
<div id="orbit_calendar">
|
|
<div id="sec1">
|
|
<div class="btn-toolbar" id="navigation">
|
|
<div id="calendar-nav">
|
|
<div class="btn-group">
|
|
<button class="btn btn-default btn-sm" id="prev_month_btn">
|
|
<i class="icon-chevron-left"></i>
|
|
</button>
|
|
<button class="btn btn-default btn-sm" id="next_month_btn">
|
|
<i class="icon-chevron-right"></i>
|
|
</button>
|
|
<button class="btn btn-default btn-sm" id="today_btn">Today</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-inline" id="range_selection"></div>
|
|
</div>
|
|
<div id='sec3' class="btn-toolbar">
|
|
<div class="btn-group calendar_mode">
|
|
<button class="btn btn-default mode_switch btn-sm" data-mode="timeGridDay" >day</button>
|
|
<button class="btn btn-default mode_switch btn-sm" data-mode="timeGridWeek" >week</button>
|
|
<button class="btn btn-default active mode_switch btn-sm" data-mode="dayGridMonth" >month</button>
|
|
</div>
|
|
<button id="refresh_btn" class="btn btn-default btn-sm">
|
|
<i class="icons-cycle"></i>
|
|
</button>
|
|
</div>
|
|
<div id="view_holder">
|
|
<h3 id="current_title" class="current_day_title"></h3>
|
|
<div id="calendar"></div>
|
|
<div id="calendar_agenda"></div>
|
|
</div>
|
|
</div>
|
|
<div id="event_quick_view" class="modal" style="width: 300px; display:none; margin:0 0 0 0;"></div>
|
|
<div id="calendar-loading"></div>
|
|
<script type="text/javascript">
|
|
var property_id = "<%= property.id.to_s %>";
|
|
var calendar = new Calendar("#calendar",property_id);
|
|
function change_pick(target){
|
|
if( $(target).attr("id") == "pick_recurring_end_date"){
|
|
if($('#p_hire_recurring_interval').val() == ""){
|
|
alert("<%=t("property_hire.please_select_recurring_interval")%>");
|
|
$('#p_hire_recurring_interval').focus();
|
|
return;
|
|
}
|
|
$("#calendar").data("recurring_interval", $('#p_hire_recurring_interval').val());
|
|
}
|
|
$("#hidden_timepicker").addClass("hide");
|
|
$("#calendar").data("target","#"+$(target).attr("id"));
|
|
$("#calendar").data("title", $(target).parents(".col-sm-10").prev("label").text().replace("*",""));
|
|
$("#calendar").addClass("active_picker");
|
|
document.getElementById("main-content").scrollIntoView();
|
|
}
|
|
$("#calendar").on("select_time",function(ev,date_str){
|
|
$("#hidden_date").text(date_str);
|
|
$("#hidden_title").text($("#calendar").data("title"));
|
|
$('#hidden_timepicker .time_picker').addClass("pull-left");
|
|
$("#hidden_timepicker").removeClass("hide");
|
|
var target = $('#timepicker');
|
|
var window_width = $(window).width();
|
|
var window_height = $(window).height();
|
|
var target_offset = target.offset();
|
|
scrollTo(target_offset.left - window_width / 2, target_offset.top - window_height / 2);
|
|
$('#timepicker').trigger('focus');
|
|
})
|
|
$("#calendar").on("init_time",function(ev,time_str){
|
|
$('#timepicker').val(time_str);
|
|
})
|
|
function set_datetimepicker(){
|
|
var date_time = $("#hidden_date").text() + " " + $('#timepicker').val();
|
|
var start_date, end_date, interval = null, recurring_end_date = null;
|
|
var target = $("#calendar").data("target");
|
|
if(target == "#pick_start_date"){
|
|
start_date = date_time;
|
|
end_date = $("#p_hire_end_time").val();
|
|
}else if(target == "#pick_end_date"){
|
|
end_date = date_time;
|
|
start_date = $("#p_hire_start_time").val();
|
|
}else if(target == "#pick_recurring_end_date"){
|
|
start_date = $("#p_hire_start_time").val();
|
|
end_date = $("#p_hire_end_time").val();
|
|
interval = $("#p_hire_recurring_interval").val();
|
|
recurring_end_date = date_time;
|
|
}
|
|
end_date = (end_date == "" ? null : end_date);
|
|
start_date = (start_date == "" ? null : start_date);
|
|
if(start_date != null && end_date != null && $("#p_hire_start_time").val() != "" && $("#p_hire_end_time").val() != ""){
|
|
if(start_date > end_date){
|
|
if(target == "#pick_start_date"){
|
|
end_date = start_date.split(" ")[0] + " " + end_date.split(" ")[1];
|
|
$("#p_hire_end_time").val(end_date);
|
|
}else{
|
|
start_date = end_date.split(" ")[0] + " " + start_date.split(" ")[1];
|
|
$("#p_hire_start_time").val(start_date);
|
|
}
|
|
}
|
|
}
|
|
console.log(start_date)
|
|
var check_only = (start_date == null || end_date == null);
|
|
if(check_available(start_date,end_date,interval,recurring_end_date,check_only)){
|
|
var target = $($("#calendar").data("target"));
|
|
target.prev().find("input").val(date_time);
|
|
$("#hidden_timepicker").addClass("hide");
|
|
$("#calendar").removeClass("active_picker");
|
|
var window_width = $(window).width();
|
|
var window_height = $(window).height();
|
|
var target_offset = target.offset();
|
|
scrollTo(target_offset.left - window_width / 2, target_offset.top - window_height / 2);
|
|
}else{
|
|
if(window.check_message !== ""){
|
|
alert(window.check_message.replace(/<br>/g,"\n"));
|
|
}else{
|
|
alert('<%=t("property_hire.unavailability")%>');
|
|
}
|
|
}
|
|
}
|
|
function goto_calendar(){
|
|
$("#hidden_timepicker").addClass("hide");
|
|
var target = $("#calendar");
|
|
var window_width = $(window).width();
|
|
var window_height = $(window).height();
|
|
var target_offset = target.offset();
|
|
scrollTo(target_offset.left - window_width / 2, target_offset.top - window_height / 2);
|
|
}
|
|
</script>
|
|
<div id="hidden_timepicker" class="hide">
|
|
<span id="hidden_title" class="pull-left" style="margin-right: 1em;font-weight: bold;"></span>
|
|
<div style="display: grid;">
|
|
<span id="hidden_date" class="pull-left" style="margin-right: 1em;"></span>
|
|
<%= fields_for :timepicker do |f|%>
|
|
<%= f.time_picker :timepicker, :no_label => true, :new_record => hire.new_record?,:format=>"HH:mm", :class => "pull-left", :data=>{"picker-type" => "range", "range" => "end", "fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
|
<% end %>
|
|
<div class="pull-left btn-group" style="margin-top: 0.5em;">
|
|
<button id="confirm_date" class="btn btn-primary btn-sm" style="margin-right: 0.5em;" onclick="set_datetimepicker()"><%=t("property_hire.confirm")%></button>
|
|
<button id="cancel_date" class="btn btn-primary btn-sm" onclick="goto_calendar()"><%=t("property_hire.cancel")%></button>
|
|
</div>
|
|
</div>
|
|
<div style="clear: both;"></div>
|
|
<hr>
|
|
</div>
|
|
<%= form_for hire, :url => "/xhr/property_hires/make_booking", html: { class: "form-horizontal" } do |f| %>
|
|
<div class="form-group">
|
|
<%= f.label :start_time, "*"+t("property_hire.start_time"), :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-10">
|
|
<%= f.datetime_picker :start_time, :no_label => true, :new_record => hire.new_record?,:class => "pull-left", :data=>{"picker-type" => "range", "range" => "start", "fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
|
<button type="button" id="pick_start_date" onclick="change_pick(this)" class="btn btn-primary btn-sm pull-left" style="margin-left: 1em;"><%=t("property_hire.pick_from_calendar")%></button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<%= f.label :end_time, "*"+t("property_hire.end_time"), :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-10">
|
|
<%= f.datetime_picker :end_time, :no_label => true, :new_record => hire.new_record?,:class => "pull-left", :data=>{"picker-type" => "range", "range" => "end", "fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
|
<button type="button" id="pick_end_date" onclick="change_pick(this)" class="btn btn-primary btn-sm pull-left" style="margin-left: 1em;"><%=t("property_hire.pick_from_calendar")%></button>
|
|
</div>
|
|
</div>
|
|
<!-- ############# recurring ############# -->
|
|
<div class="form-group">
|
|
<%= f.label :recurring, t("property_hire.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_hire.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 => t('property_hire.select_interval')}, {:data => {"fv-validation" => "requiredifrecurring;" , "fv-messages" => "Cannot be empty;"}} %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<%= f.label :recurring_end_date, "*"+t("property_hire.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?, :class=>"pull-left", :data=>{"fv-validation" => "requiredifrecurring;", "fv-messages" => "Cannot be empty;"} %>
|
|
<button type="button" id="pick_recurring_end_date" onclick="change_pick(this)" class="btn btn-primary btn-sm pull-left" style="margin-left: 1em;"><%=t("property_hire.pick_from_calendar")%></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<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-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">
|
|
<% hint1 = t("property_hire.please_select_recurring_interval_and_recurring_end_time",:default=>"") %>
|
|
<% if hint1 == ""%>
|
|
<b>Please! </b><span> Select an interval time and recurring event end date.</span>
|
|
<% else %>
|
|
<span><b><%=hint1%></b></span>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<% if property.set_unavailibility %>
|
|
<div class="col-sm-offset-2 col-sm-5">
|
|
<b><%= t("property_hire.Unavailibility_Schedule") %></b>
|
|
<div>
|
|
<%= property.render_unavailable_message%>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="" class="col-sm-2 control-label"></label>
|
|
<div class="col-sm-10">
|
|
<a href="/xhr/property_hires/check_availability" id="check-avail-btn" class="btn btn-primary"><%= t('property_hire.check_availibility') %></a>
|
|
<img style="display: none;" width="40" src="/assets/spin.gif" id="spinner" />
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<%= f.label :hiring_person_email, "*"+t("property_hire.hiring_person_email"), :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-5">
|
|
<%= f.text_field :hiring_person_email, :class => "form-control", :value => current_user.member_profile.email, :data => {"fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<%= f.label :hiring_person_number, "*"+t("property_hire.hiring_person_number"), :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-5">
|
|
<%= f.text_field :hiring_person_number, :class => "form-control", :value => current_user.member_profile.mobile_no, :data => {"fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<%= f.label :hiring_person_name, "*"+t("property_hire.hiring_person_name"), :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-5">
|
|
<%= f.text_field :hiring_person_name, :class => "form-control", :value => (current_user.name rescue ""), :data => {"fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
|
<%= f.hidden_field :hiring_person_id, :value => (current_user.member_profile.id.to_s rescue "") %>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<%= f.label :reason_for_hire, "*"+t("property_hire.reason_for_hire"), :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-5">
|
|
<%= f.text_field :reason_for_hire, :class => "form-control", :data => {"fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
|
</div>
|
|
</div>
|
|
<% if(property.enable_notes_selector rescue false) %>
|
|
<% 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? %>
|
|
<% type = sub_hash["type"] %>
|
|
<div class="form-group">
|
|
<%= f.label "notes_selector[#{index}]", name, :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-5">
|
|
<% values.each_with_index do |v,i| %>
|
|
<label class="checkbox-inline">
|
|
<input type="<%=type%>" name="p_hire[notes_selector][<%=index.to_s%>][]" value="<%=i%>" <%= (type=="radio" && i == 0) ? "checked=\"checked\"" : "" %>>
|
|
<%=v%>
|
|
</label>
|
|
<% end %>
|
|
<% if type == "checkbox" && (values.count > 1) %>
|
|
<small class="help-block"><%= t("property_hire.checkbox_hint") %></small>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<% else %>
|
|
<div class="form-group">
|
|
<%= f.label :note_for_hire, t("property_hire.note_for_hire"), :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-5">
|
|
<%= f.text_area :note_for_hire, :class => "form-control" %>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<% fields_name = ["organization" ,"person_in_charge" , "tel_of_person_in_charge" , "department" , "contact_person" , "tel_of_contact_person" , "mobile_phone_of_contact_person" , "contact_person_Email" , "contact_person_department"] %>
|
|
<% fields_name.each do |field_name| %>
|
|
<% if(property[field_name]["enable"] == "1" rescue false) %>
|
|
<% required = (property[field_name]["required"] == "true" rescue false) %>
|
|
<div class="form-group">
|
|
<%= f.label field_name, (required ? "*" : "") + property.custom_text(field_name,"name"), :class => "col-sm-2 control-label" %>
|
|
<div class="col-sm-5">
|
|
<% placeholder = property.custom_text(field_name,"placeholder") %>
|
|
<% if required %>
|
|
<%= f.text_field field_name, :class => "form-control", :placeholder => placeholder, :data => {"fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
|
<% else %>
|
|
<%= f.text_field field_name, :class => "form-control", :placeholder => placeholder %>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<% end %>
|
|
<% if property.p_hire_fields_enabled.count != 0 %>
|
|
<% p_hire = PHire.new(:id=>nil) %>
|
|
<% @form_index = 0 %>
|
|
<% property.p_hire_fields_enabled.asc(:_id).each do |rf| %>
|
|
<div class="form-group">
|
|
<%= rf.block_helper(property,@form_index,false,"p_hire",p_hire, rf.to_require) %>
|
|
</div>
|
|
<% @form_index = @form_index +1 %>
|
|
<% end %>
|
|
<% end %>
|
|
<div class="form-group">
|
|
<div class="col-sm-offset-2 col-sm-10">
|
|
<%= f.submit t("property_hire.save"), :class => "btn btn-primary" %>
|
|
<%= f.hidden_field :property_id, :value => property.id %>
|
|
<input type="hidden" name="url" value="<%= url %>" />
|
|
<input type="hidden" id="dates_validated" name="dates_validated" value="0" data-fv-validation="checkForDates;" data-fv-messages="Please make sure first if dates are available.;">
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<div style="height: 50px;"></div>
|
|
<script type="text/javascript">
|
|
var property_id = "<%= property.id.to_s %>";
|
|
var check_available = function(stime,etime,interval,recurring_end_date,check_only,property_id){
|
|
var el = $("#check-avail-btn"),
|
|
url = $("#check-avail-btn").attr("href"),
|
|
spinner = $("#spinner");
|
|
stime = stime || etime;
|
|
etime = etime || stime;
|
|
property_id = property_id || window.property_id;
|
|
var timezone = new Date().toString().match(/([-\+][0-9]+)\s/)[1];
|
|
data = {
|
|
"stime": stime,
|
|
"etime": etime,
|
|
"property_id": property_id,
|
|
"locale": "<%=I18n.locale%>",
|
|
"timezone": timezone
|
|
}
|
|
data["interval"] = interval;
|
|
data["recurring_end_date"] = recurring_end_date;
|
|
var flag = false;
|
|
window.check_message = "";
|
|
$.ajax({
|
|
"url" : url,
|
|
"type" : "get",
|
|
"data" : data,
|
|
"dataType" : "json",
|
|
"async": false
|
|
}).done(function(data){
|
|
if(data.success){
|
|
$("#dates_validated").val("1");
|
|
$("#property-unavaialable-alert").hide();
|
|
flag = true;
|
|
if(!check_only){
|
|
$("#property-avaialable-alert").show();
|
|
}
|
|
}else{
|
|
$("#dates_validated").val("0");
|
|
$("#property-avaialable-alert").hide();
|
|
window.check_message = data.msg;
|
|
window.check_message = window.check_message.replace(/{(.*)}/,function(v){
|
|
return getDateString(new Date(RegExp.$1),datetime_format,is_chinese);
|
|
})
|
|
if(!check_only){
|
|
$("#property-unavaialable-alert").find("span").html(window.check_message);
|
|
$("#property-unavaialable-alert").show();
|
|
}
|
|
}
|
|
spinner.hide();
|
|
el.show();
|
|
})
|
|
return flag;
|
|
}
|
|
$("#check-avail-btn").on("click",function(){
|
|
var el = $(this),
|
|
url = $(this).attr("href"),
|
|
spinner = $("#spinner");
|
|
$(".alert").hide();
|
|
var stime = $("#p_hire_start_time").val(),
|
|
etime = $("#p_hire_end_time").val();
|
|
var interval = null, recurring_end_date = null, is_recurring = false;;
|
|
if($("#p_hire_recurring").is(":checked")){
|
|
is_recurring = true;
|
|
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;
|
|
}
|
|
}
|
|
spinner.show();
|
|
el.hide();
|
|
check_available(stime,etime,interval,recurring_end_date);
|
|
return false;
|
|
})
|
|
|
|
$("#unavailable-schedule").on("click",function(){
|
|
|
|
})
|
|
|
|
var hireForm = new FormValidator($("#new_p_hire"));
|
|
hireForm.validate_functions.checkForDates = function(value,element){
|
|
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(){
|
|
$("#dates_validated").val("0");
|
|
$("#property-avaialable-alert").hide();
|
|
$("#property-unavaialable-alert").hide();
|
|
|
|
if($(this).is(":checked")){
|
|
$("#recurring-block").slideDown();
|
|
}else{
|
|
$("#recurring-block").slideUp();
|
|
}
|
|
})
|
|
</script>
|
|
<% end %>
|
|
|
|
|
|
|
|
|
|
|
|
|