Compare commits
127 Commits
revert-e1e
...
master
Author | SHA1 | Date |
---|---|---|
rulingcom | f71fcdcefa | |
邱博亞 | e190f1e23c | |
rulingcom | 420ce3b065 | |
rulingcom | aa19dd1416 | |
邱博亞 | 703c5322ca | |
邱博亞 | eb8b951253 | |
rulingcom | 7080cf7d4d | |
邱博亞 | 4d02ff8729 | |
邱博亞 | bd8f88afa3 | |
邱博亞 | 76cd916a26 | |
邱博亞 | 24c8845f28 | |
邱博亞 | 5d7769270a | |
邱博亞 | 6dddde451d | |
邱博亞 | cde9364f76 | |
邱博亞 | 6ad48313ed | |
邱博亞 | 864358bd69 | |
BoHung Chiu | c3eb6f7ac8 | |
邱博亞 | f8e8653c5c | |
BoHung Chiu | 336c940457 | |
邱博亞 | 0660a12bff | |
邱博亞 | ab6b79eb29 | |
BoHung Chiu | 16edd24809 | |
BoHung Chiu | 27b4b2aab7 | |
BoHung Chiu | 22ab0909ad | |
BoHung Chiu | 7f14f7db5a | |
BoHung Chiu | e86b431bbb | |
BoHung Chiu | 14881759b7 | |
BoHung Chiu | 56dad2a1b4 | |
BoHung Chiu | f8835c49d0 | |
BoHung Chiu | a6e9c31222 | |
BoHung Chiu | 48c4948946 | |
BoHung Chiu | 82cec4139c | |
邱博亞 | 429ef0f11c | |
BoHung Chiu | 53eced22cc | |
BoHung Chiu | 8892dbb9f8 | |
BoHung Chiu | 02556434b3 | |
BoHung Chiu | 878fc0079d | |
BoHung Chiu | b3876c00d0 | |
BoHung Chiu | 6e63cf4777 | |
BoHung Chiu | 5ed7a08a1a | |
BoHung Chiu | ae43768659 | |
BoHung Chiu | dba2944273 | |
BoHung Chiu | 92b3b91138 | |
BoHung Chiu | d1b61401cb | |
BoHung Chiu | 90dabd7560 | |
BoHung Chiu | 28ef7b0ae0 | |
邱博亞 | e93d34d597 | |
BoHung Chiu | 70388806c6 | |
BoHung Chiu | 388ada1ae3 | |
BoHung Chiu | 33da76f7ae | |
BoHung Chiu | 4b55d3ef39 | |
BoHung Chiu | 2de6ba54ae | |
BoHung Chiu | 12eea8b58e | |
BoHung Chiu | e98009f659 | |
BoHung Chiu | c0261a90d8 | |
BoHung Chiu | 74881746ab | |
BoHung Chiu | a6caffd67f | |
BoHung Chiu | 1dca65f863 | |
BoHung Chiu | 3691a14c64 | |
BoHung Chiu | 958bade200 | |
BoHung Chiu | b4aa1d125b | |
BoHung Chiu | c4ef2557a3 | |
BoHung Chiu | 9709a8e708 | |
BoHung Chiu | 5fa2811cbe | |
BoHung Chiu | d78aab6408 | |
BoHung Chiu | c902128062 | |
BoHung Chiu | 97d7d0e90f | |
BoHung Chiu | eaa1009dda | |
BoHung Chiu | d8adf49ee0 | |
BoHung Chiu | 456f2b9ece | |
BoHung Chiu | 5c2b124e28 | |
BoHung Chiu | 4942cc9573 | |
BoHung Chiu | 912956b65a | |
BoHung Chiu | 2a2121a7c8 | |
BoHung Chiu | b97a590b5c | |
BoHung Chiu | b88915c6e7 | |
BoHung Chiu | ceb60e3afc | |
BoHung Chiu | a5313537ec | |
BoHung Chiu | cae7247750 | |
BoHung Chiu | b0d7599edd | |
BoHung Chiu | e199880f13 | |
BoHung Chiu | 3366262e62 | |
BoHung Chiu | 9c85d50c5b | |
BoHung Chiu | 24f93f7630 | |
chiu | c9f424b30d | |
BoHung Chiu | 69e269cf59 | |
BoHung Chiu | 875c3dc580 | |
BoHung Chiu | ce63816765 | |
chiu | 9e670ae11f | |
BoHung Chiu | 1cfe929348 | |
BoHung Chiu | 5d14e25578 | |
BoHung Chiu | 262eaa36b9 | |
BoHung Chiu | 9c8c1bd0c4 | |
BoHung Chiu | 1e18ac077a | |
BoHung Chiu | 6f3333a857 | |
BoHung Chiu | 9afb891362 | |
chiu | afa62d1d67 | |
chiu | a654081664 | |
chiu | eb73011ca4 | |
chiu | 7e3141d4f0 | |
chiu | a8952495f4 | |
chiu | b83b4e5633 | |
chiu | 386cb0c5e0 | |
chiu | d159171993 | |
chiu | 02f46d90e2 | |
chiu | b8c0ff2bd5 | |
chiu | 8342a17aca | |
chiu | a17980e7a7 | |
chiu | 1b88e86364 | |
chiu | c73a3ce9a8 | |
chiu | 7c46fbd6ac | |
chiu | b7efc22d1d | |
chiu | 86cf5f9a13 | |
chiu | 73241e7b18 | |
chiu | c43dd3c625 | |
chiu | 79bf7d9694 | |
chiu | 23c6753646 | |
chiu | 6c3cf31b03 | |
chiu | 304dffbe9f | |
chiu | ec3e4463ca | |
chiu | bb3d9ffeb9 | |
chiu | 212574e17a | |
chiu | 9ae24ce5f9 | |
chiu | 1a985bad64 | |
wmcheng | 0bd0a61986 | |
wmcheng | b55b5d60e3 | |
wmcheng | 367a95d7bc |
|
@ -0,0 +1,17 @@
|
|||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
property_hire (0.0.1)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
property_hire!
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.3
|
Binary file not shown.
After Width: | Height: | Size: 182 B |
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,497 @@
|
|||
// Retrieve the initial data
|
||||
function temporary() {
|
||||
attributesArray.length = 0;
|
||||
$('.attributes').each(function() {
|
||||
var attributesData = {},
|
||||
$selectType = $('.dataType').data().type;
|
||||
|
||||
// Capture "attributes-body" within the input[type = "text"] val
|
||||
$(this).find('.attributes-body').find('input[type="text"]').each(function(i) {
|
||||
var $type = $(this).data().type;
|
||||
attributesData[$type] = $(this).val();
|
||||
});
|
||||
|
||||
// Capture "attributes-body" within the input[type = "radio"] checked
|
||||
$(this).find('.attributes-body').find('input[type="radio"]').each(function(i) {
|
||||
var $type = $(this).data().type;
|
||||
attributesData[$type] = $(this).prop("checked");
|
||||
});
|
||||
|
||||
// Capture "attributes-body" within the dataType selected
|
||||
$(this).find('.attributes-body').find('.dataType').children("option:selected").each(function () {
|
||||
attributesData[$selectType] = {};
|
||||
attributesData[$selectType].index = $(this).index();
|
||||
attributesData[$selectType].name = $(this).attr('ref');
|
||||
if($(this).attr('ref') == 'typeB' || $(this).attr('ref') == 'typeE' || $(this).attr('ref') == 'typeF') {
|
||||
attributesData[$selectType].option = [];
|
||||
}
|
||||
});
|
||||
|
||||
// Capture "field-type" within the input[type = "text"] val
|
||||
$(this).find('.field-type').find('input[type="text"]').each(function(i) {
|
||||
var $type = $(this).data().type;
|
||||
if(!$type.match('option_lang')) {
|
||||
attributesData[$selectType][$type] = $(this).val();
|
||||
}
|
||||
});
|
||||
|
||||
$(this).find('.field-type .add-target').find('.input-append').each(function() {
|
||||
var append = []
|
||||
$(this).children('input[type="text"]').each(function() {
|
||||
var val = $(this).val();
|
||||
append.push(val);
|
||||
});
|
||||
attributesData[$selectType].option.push(append);
|
||||
})
|
||||
|
||||
// Capture "field-type" within the input[type = "checkbox"] checked
|
||||
$(this).find('.field-type').find('input[type="checkbox"]').each(function() {
|
||||
var $type = $(this).data().type;
|
||||
attributesData[$selectType][$type] = $(this).prop("checked");
|
||||
});
|
||||
|
||||
// Capture "field-type" within the input[type = "radio"] checked
|
||||
$(this).find('.field-type').find('input[type="radio"]').each(function() {
|
||||
var $type = $(this).data().type;
|
||||
attributesData[$selectType][$type] = $(this).prop("checked");
|
||||
});
|
||||
|
||||
// Capture "field-type" within the dataType selected
|
||||
$(this).find('.field-type').find('select').children("option:selected").each(function () {
|
||||
attributesData[$selectType].dateFormat = $(this).index();
|
||||
});
|
||||
|
||||
attributesArray.push(attributesData);
|
||||
});
|
||||
};
|
||||
|
||||
// Determine the Append input length
|
||||
function inputAppendLength() {
|
||||
$('.add-target').each(function(i) {
|
||||
if($(this).children('.input-append:not(:hidden)').length == 1 || $(this).children('.input-append').length == 1) {
|
||||
$(this).children('.input-append').each(function() {
|
||||
if($(this).children('div').hasClass('tab-content')) {
|
||||
var btnLength = $(this).children('.btn').length;
|
||||
$(this).find('.btn').eq(btnLength-2).addClass('last');
|
||||
$(this).find('.remove-input').addClass('hide');
|
||||
} else {
|
||||
var mediumLength = $(this).children('.input-medium').length;
|
||||
$(this).children('.input-medium').eq(mediumLength-1).addClass('last');
|
||||
$(this).children('.remove-input').addClass('hide');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$(this).children('.input-append').each(function() {
|
||||
if($(this).children('div').hasClass('tab-content')) {
|
||||
$(this).find('.btn').removeClass('last');
|
||||
$(this).find('.remove-input').removeClass('hide');
|
||||
} else {
|
||||
$(this).children('.input-medium').removeClass('last');
|
||||
$(this).children('.remove-input').removeClass('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Role Attribute Template Data
|
||||
function setData(l, type, ol) {
|
||||
var fields = $('#info').length ? "info[p_hire_fields]" : $('#sub_property').length ? "sub_property[p_hire_fields]" : "property[p_hire_fields]",
|
||||
data = {
|
||||
_add_more: ["add_more_" +l, fields+"["+l+"]["+type+"][add_more]"],
|
||||
_calendar: ["calendar_" +l, fields+"["+l+"]["+type+"][calendar]"],
|
||||
_cross_lang: ["cross_lang_" +l, fields+"["+l+"]["+type+"][cross_lang]"],
|
||||
_disabled: ["disabled_" +l, fields+"["+l+"][disabled]"],
|
||||
_format: ["format_" +l, fields+"["+l+"]["+type+"][format]"],
|
||||
_initial: ["initial_" +l, fields+"["+l+"]["+type+"][initial]"],
|
||||
_is_range: ["is_range_" +l, fields+"["+l+"]["+type+"][is_range]"],
|
||||
_key: ["key_" +l, fields+"["+l+"][key]"],
|
||||
_markup: fields+"["+l+"][markup]",
|
||||
_option_list: ["option_list_"+l+"_"+ol, fields+"["+l+"]["+type+"][option_list]["+ol+"]", "option_list_"+ol],
|
||||
_placeholder: ["placeholder_" +l, fields+"["+l+"]["+type+"][placeholder]"],
|
||||
_title_translations: ["title_translations_" +l, fields+"["+l+"][title_translations]"],
|
||||
_to_delete: ["to_delete_" +l, fields+"["+l+"][to_delete]"],
|
||||
_to_require: ["to_require_" +l, fields+"["+l+"][to_require]"],
|
||||
_display_in_reason_for_hire: ["display_in_reason_for_hire_" +l, fields+"["+l+"][display_in_reason_for_hire]"],
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
// Get Default Address Form
|
||||
function getAddressForm(trigger, element, decide) {
|
||||
if(decide) {
|
||||
addressVal.length = addressArray.length = 0;
|
||||
var addressAllVal = [];
|
||||
var inputNameArray = [];
|
||||
trigger.closest('.input-append').find('.tab-pane').each(function() {
|
||||
var adderssText = $(this).children('input[type="text"]').val(),
|
||||
addersshidden = '',
|
||||
addressData = {},
|
||||
inputName = [];
|
||||
$(this).children('input:not(:first)').each(function(j) {
|
||||
var name = $(this).attr('name'),
|
||||
val = $(this).val();
|
||||
addersshidden += val;
|
||||
addressData[name] = val;
|
||||
inputName.push(name);
|
||||
});
|
||||
addressArray.push(addressData);
|
||||
addressAllVal.push(adderssText);
|
||||
inputNameArray.push(inputName);
|
||||
if(adderssText != addersshidden) {
|
||||
addressVal.push(false);
|
||||
} else {
|
||||
addressVal.push(true);
|
||||
}
|
||||
});
|
||||
element.find('.tab-pane').each(function(i) {
|
||||
$(this).find('textarea, input[type="text"]').each(function(j) {
|
||||
$(this).attr('name',inputNameArray[i][j]);
|
||||
});
|
||||
if(addressVal[i]) {
|
||||
$(this).find('textarea, input[type="text"]').each(function(j) {
|
||||
$(this).val(addressArray[i][$(this).attr('name')]);
|
||||
});
|
||||
} else {
|
||||
$(this).find('textarea').val(addressAllVal[i]);
|
||||
$(this).find('input[type="text"]').each(function(j) {
|
||||
$(this).val('');
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
element.off('show');
|
||||
};
|
||||
|
||||
// Return Address Form
|
||||
function returnAddressForm(element, decide) {
|
||||
if(decide) {
|
||||
addressArray.length = 0;
|
||||
element.find('.tab-pane').each(function(i) {
|
||||
var addressData = {};
|
||||
$(this).find('textarea, input[type="text"]').each(function(j) {
|
||||
var name = $(this).attr('name'),
|
||||
val = $(this).val();
|
||||
addressData[name] = val;
|
||||
});
|
||||
addressArray.push(addressData);
|
||||
});
|
||||
$.map(addressInputId, function(n, i) {
|
||||
var v = '';
|
||||
$('#'+n).find('input[type="hidden"]').each(function() {
|
||||
$(this).val(addressArray[i][$(this).attr('name')]);
|
||||
v += addressArray[i][$(this).attr('name')]
|
||||
});
|
||||
$('#'+n).find('input[type="text"]').each(function() {
|
||||
$(this).val(v);
|
||||
});
|
||||
});
|
||||
};
|
||||
returnDecide = false;
|
||||
};
|
||||
|
||||
$(function() {
|
||||
appendIndex = null;
|
||||
if($('#user-forms').length) {
|
||||
addressVal = [];
|
||||
addressArray = [];
|
||||
addressInputId = [];
|
||||
propertyType = null;
|
||||
returnDecide = false;
|
||||
$('.attributes').each(function() {
|
||||
if($(this).find('.toggle-check').attr('value') == "true") {
|
||||
$(this).addClass('disabled').children('.attributes-body').hide();
|
||||
}
|
||||
});
|
||||
$('.returnDecide').on(clickEvent, function() {
|
||||
returnDecide = true;
|
||||
})
|
||||
$('#address-field').on('hidden', function () {
|
||||
$('.btn[data-toggle="modal"]').removeClass('active').blur();
|
||||
$(this).find('.nav-tabs > li').removeClass('active').eq(0).addClass('active');
|
||||
$(this).find('.tab-content > .tab-pane').removeClass('active in').eq(0).addClass('active in');
|
||||
$(this).on('show', getAddressForm(null, $(this), false));
|
||||
returnAddressForm($(this), returnDecide)
|
||||
});
|
||||
$('.control-group').delegate('.btn[data-toggle="modal"]', 'click', function() {
|
||||
var $trigger = $(this);
|
||||
addressInputId.length = 0;
|
||||
$(this).closest('.input-append').find('.tab-pane').each(function() {
|
||||
addressInputId.push($(this).attr('id'));
|
||||
});
|
||||
$('#address-field').on('show', getAddressForm($trigger, $('#address-field'), true));
|
||||
});
|
||||
$('#user-forms').delegate('.togglebox, .delete, .trigger, .remove-input', clickEvent, function(event) {
|
||||
if($(this).hasClass('togglebox')) {
|
||||
var property_staus = [];
|
||||
if($(this).hasClass('disable')) {
|
||||
$(this).find('.toggle-check')
|
||||
.attr('value', 'false')
|
||||
.closest('.attributes')
|
||||
.removeClass('disabled')
|
||||
.children('.attributes-body')
|
||||
.fadeIn(300);
|
||||
} else {
|
||||
$(this).find('.toggle-check')
|
||||
.attr('value', 'true')
|
||||
.closest('.attributes')
|
||||
.addClass('disabled')
|
||||
.children('.attributes-body')
|
||||
.fadeOut(300)
|
||||
.find('.check')
|
||||
.attr("checked",false)
|
||||
.attr("value",property_staus);
|
||||
}
|
||||
$(this).toggleClass('disable');
|
||||
};
|
||||
if($(this).hasClass('remove-input')) {
|
||||
$(this).closest('.input-append').fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
inputAppendLength();
|
||||
});
|
||||
};
|
||||
if($(this).hasClass('trigger')) {
|
||||
appendIndex = $(this).closest('.controls').find('.input-append').length;
|
||||
nameNumber = $(this).closest('.controls').find('.input-append:eq(0)').find('input').eq(0).attr('name');
|
||||
nameNumber = nameNumber.match(/[^[\D\]]+(?=])/g)[0];
|
||||
propertyType = $(this).data('properties')
|
||||
if($(this).hasClass('textInput')) {
|
||||
$("#template-text").tmpl().appendTo($(this).closest('.controls').find('.add-target'));
|
||||
} else if ($(this).hasClass('textLengInput')) {
|
||||
$("#template-text-language").tmpl().appendTo($(this).closest('.controls').find('.add-target'));
|
||||
} else if ($(this).hasClass('address')) {
|
||||
$("#template-address").tmpl().appendTo($(this).closest('.controls').find('.add-target'));
|
||||
}
|
||||
inputAppendLength();
|
||||
};
|
||||
event.preventDefault();
|
||||
});
|
||||
inputAppendLength();
|
||||
} else {
|
||||
attributesArray = [];
|
||||
attributesHeaderLength = null;
|
||||
templateType = null;
|
||||
attributeIndex = null;
|
||||
if($('.add-target').length) {
|
||||
inputAppendLength();
|
||||
}
|
||||
if(!$('.attributes').length) {
|
||||
$('#attributes-area').addClass('clickHere');
|
||||
} else {
|
||||
temporary();
|
||||
};
|
||||
|
||||
$('.add-attributes').on(clickEvent, function() {
|
||||
if($('#attributes-area').hasClass('clickHere')) {
|
||||
$('#attributes-area').removeClass('clickHere');
|
||||
};
|
||||
attributesHeaderLength = $('.attributes:not(:hidden)').length+1;
|
||||
attributesLength = $('#attributes-area .attributes').length;
|
||||
if(templateType == null){
|
||||
templateType = "typeA";
|
||||
}
|
||||
$("#template-attributes").tmpl(setData(attributesLength, templateType, appendIndex)).appendTo( "#attributes-area" );
|
||||
$('.toggle-check').togglebox();
|
||||
});
|
||||
|
||||
|
||||
|
||||
$('.attributes.default').each(function(i) {
|
||||
$(this).children('.field-type').not('.default').hide();
|
||||
$(this).find('input[type="text"]').on('keyup', function() {
|
||||
$(this).trigger("checking");
|
||||
});
|
||||
$(this).find('input[type="radio"], input[type="checkbox"], select').change(function() {
|
||||
$(this).trigger("checking");
|
||||
});
|
||||
$(this).delegate('input[type="text"], input[type="radio"], input[type="checkbox"], select', 'checking', function(e) {
|
||||
var e = e.target.type,
|
||||
$data = $(this).data().type;
|
||||
switch(e) {
|
||||
case 'text':
|
||||
var val = $(this).val();
|
||||
if(!$(this).closest('.field-type').length) {
|
||||
$data = attributesArray[i][$data];
|
||||
} else if(!$(this).closest('.add-target').length) {
|
||||
$data = attributesArray[i].select[$data];
|
||||
} else {
|
||||
appendIndex = $(this).parent('.input-append').index()
|
||||
optionIndex = $(this).index()
|
||||
$data = attributesArray[i].select.option[appendIndex][optionIndex];
|
||||
}
|
||||
if(val != $data) {
|
||||
$(this).closest('.attributes').find('.reply').removeClass('hide');
|
||||
}
|
||||
break;
|
||||
case 'radio':
|
||||
var checked = $(this).prop("checked");
|
||||
$data = attributesArray[i][$data];
|
||||
if(checked != $data) {
|
||||
$(this).closest('.attributes').find('.reply').removeClass('hide');
|
||||
}
|
||||
break;
|
||||
case 'checkbox':
|
||||
var checked = $(this).prop("checked");
|
||||
$data = attributesArray[i].select[$data];
|
||||
if(checked != $data) {
|
||||
$(this).closest('.attributes').find('.reply').removeClass('hide');
|
||||
}
|
||||
break;
|
||||
case 'select-one':
|
||||
var ref,
|
||||
$data = attributesArray[i].select.name;
|
||||
$(this).children("option:selected").each(function() {
|
||||
ref = $(this).attr('ref');
|
||||
});
|
||||
if(ref != $data) {
|
||||
$(this).closest('.attributes').find('.reply').removeClass('hide');
|
||||
}
|
||||
break;
|
||||
};
|
||||
});
|
||||
$(this).delegate('.reply', clickEvent, function() {
|
||||
var $bodyText = $(this).parent('.attributes-header').siblings('.attributes-body').find('input[type="text"]'),
|
||||
$bodyRadio = $(this).parent('.attributes-header').siblings('.attributes-body').find('input[type="radio"]'),
|
||||
$bodySelected = $(this).parent('.attributes-header').siblings('.attributes-body').find('.dataType').children("option"),
|
||||
$fieldTypeO = $(this).parent('.attributes-header').siblings('.field-type.default'),
|
||||
$fieldTypeN = $(this).parent('.attributes-header').siblings('.field-type').not('.default');
|
||||
$bodyText.each(function() {
|
||||
var $type = $(this).data().type;
|
||||
$(this).val(attributesArray[i][$type]);
|
||||
});
|
||||
$bodyRadio.each(function() {
|
||||
var $type = $(this).data().type;
|
||||
$(this).prop("checked", attributesArray[i][$type])
|
||||
});
|
||||
$fieldTypeO.find('input[type="text"]').each(function() {
|
||||
var $type = $(this).data().type;
|
||||
if(!$type.match('option_lang')) {
|
||||
$(this).val(attributesArray[i].select[$type]);
|
||||
}
|
||||
});
|
||||
$fieldTypeO.find('.add-target').find('.input-append').each(function(k) {
|
||||
$(this).children('input[type="text"]').each(function(j) {
|
||||
$(this).val(attributesArray[i].select.option[k][j]);
|
||||
// var val = $(this).val();
|
||||
// append.push(val);
|
||||
});
|
||||
})
|
||||
$fieldTypeO.find('input[type="checkbox"], input[type="radio"]').each(function() {
|
||||
var $type = $(this).data().type;
|
||||
$(this).prop("checked", attributesArray[i].select[$type]);
|
||||
});
|
||||
$fieldTypeO.find('select').children("option").eq(attributesArray[i].select.dateFormat).prop('selected',true);
|
||||
$bodySelected.eq(attributesArray[i].select.index).prop('selected',true);
|
||||
$fieldTypeO.show();
|
||||
$fieldTypeN.empty().hide();
|
||||
$(this).addClass('hide')
|
||||
return false
|
||||
})
|
||||
});
|
||||
$('#attributes-area').delegate('.togglebox, .delete, .trigger, .remove-input', clickEvent, function(event) {
|
||||
if($(this).hasClass('togglebox')) {
|
||||
if($(this).hasClass('disable')) {
|
||||
$(this).find('.toggle-check')
|
||||
.attr('value', 'false')
|
||||
.closest('.attributes')
|
||||
.removeClass('disabled')
|
||||
.find('input, select')
|
||||
.removeAttr('disabled')
|
||||
.end('.attributes')
|
||||
.find('.btn-group .btn')
|
||||
.removeClass('disabled')
|
||||
.end().find('.attribute_field_disabled').attr('value', 'false');
|
||||
if($(this).closest('.attributes').find('.dataType').children("option:selected").attr('ref')) {
|
||||
$(this).closest('.attributes').find('.field-type').addClass('in').find('.control-group').delay(150).fadeIn(300);
|
||||
}
|
||||
} else {
|
||||
$(this).find('.toggle-check')
|
||||
.attr('value', 'true')
|
||||
.closest('.attributes')
|
||||
.addClass('disabled')
|
||||
.find('.attributes-body input, .attributes-body select')
|
||||
.attr({'disabled': 'disabled'})
|
||||
.end('.attributes')
|
||||
.find('.btn-group .btn')
|
||||
.addClass('disabled')
|
||||
.end().find('.attribute_field_disabled').attr('value', 'true')
|
||||
.end().find('.field-type .control-group').fadeOut(300, function() {
|
||||
$(this).parent('.field-type').removeClass('in');
|
||||
});
|
||||
}
|
||||
$(this).toggleClass('disable');
|
||||
};
|
||||
if($(this).hasClass('delete')) {
|
||||
$(this).closest('.attributes').fadeOut(300, function() {
|
||||
$('.attributes:not(:hidden)').each(function(i) {
|
||||
$(this).find('.attributes-header h4 span').text(i+1);
|
||||
});
|
||||
attributesHeaderLength = $('.attributes:not(:hidden)').length+1;
|
||||
if(!$('.attributes:not(:hidden)').length) {
|
||||
$('#attributes-area').addClass('clickHere');
|
||||
};
|
||||
}).find('.attribute_field_to_delete').attr('value', 'true');;
|
||||
};
|
||||
if($(this).hasClass('trigger')) {
|
||||
// appendIndex = $(this).closest('.controls').find('.input-append').length;
|
||||
appendIndex = $(this).closest('.controls').find('.input-append:last-child').children('input:first-child').attr('name');
|
||||
// appendIndex = appendIndex.split("][");
|
||||
// appendIndex = parseInt(appendIndex[appendIndex.length-2])+1;
|
||||
appendIndex = parseInt(appendIndex.match(/[^[\D\]]+(?=])/g)[1])+1;
|
||||
attributeIndex = $(this).closest('.attributes').index();
|
||||
templateType = $(this).closest('.attributes').find('.dataType').children("option:selected").attr('ref');
|
||||
$("#template-input-append").tmpl(setData(attributeIndex, templateType, appendIndex)).appendTo($(this).closest('.controls').find('.add-target'));
|
||||
inputAppendLength();
|
||||
};
|
||||
if($(this).hasClass('remove-input')) {
|
||||
$(this).parent('.input-append').fadeOut(300, function() {
|
||||
$(this).remove()
|
||||
inputAppendLength();
|
||||
});
|
||||
|
||||
}
|
||||
event.preventDefault();
|
||||
});
|
||||
$('#attributes-area').delegate('.dataType', 'change', function() {
|
||||
$(this).children("option:selected").each(function () {
|
||||
var target = $(this).closest('.attributes').find('.field-type').not('.default');
|
||||
attributeIndex = $(this).closest('.attributes').index();
|
||||
appendIndex = 0
|
||||
// $(this).closest('.attributes').find('.add-target').find('.input-append').length;
|
||||
if($(this).closest('.attributes').hasClass('default')){
|
||||
var i = $(this).closest('.attributes').index()
|
||||
if($(this).attr('ref') == attributesArray[i].select.name) {
|
||||
$(this).closest('.attributes').find('.field-type.default').show()
|
||||
target.empty().hide();
|
||||
} else {
|
||||
$(this).closest('.attributes').find('.field-type.default').hide()
|
||||
if($(this).attr('ref')) {
|
||||
templateType = $(this).attr('ref');
|
||||
target.removeAttr('class').addClass('field-type fade in ' + templateType).empty();
|
||||
$("#template-type").tmpl(setData(attributeIndex, templateType, appendIndex)).appendTo(target);
|
||||
if(templateType == 'typeB' || templateType == 'typeE' || templateType == 'typeF') {
|
||||
inputAppendLength();
|
||||
}
|
||||
} else {
|
||||
target.removeAttr('class').addClass('field-type fade')
|
||||
target.empty();
|
||||
};
|
||||
target.show();
|
||||
}
|
||||
} else {
|
||||
if($(this).attr('ref')) {
|
||||
templateType = $(this).attr('ref');
|
||||
target.removeAttr('class').addClass('field-type fade in ' + templateType).empty();
|
||||
$("#template-type").tmpl(setData(attributeIndex, templateType, appendIndex)).appendTo(target);
|
||||
if(templateType == 'typeB' || templateType == 'typeE' || templateType == 'typeF') {
|
||||
inputAppendLength();
|
||||
}
|
||||
} else {
|
||||
target.removeAttr('class').addClass('field-type fade')
|
||||
target.empty();
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
|
@ -1,8 +1,115 @@
|
|||
var Calendar = function(dom,property_id){
|
||||
window.auto_close_popup = false;
|
||||
$.fn.fullCalendar = function(args){
|
||||
var self = this[0]
|
||||
if(!self.calendar_args)
|
||||
self.calendar_args = args;
|
||||
else
|
||||
args = Object.assign(self.calendar_args, args);
|
||||
var calendar = new FullCalendar.Calendar(self,args);
|
||||
calendar.render();
|
||||
$(window).on("load",function(){
|
||||
calendar.render();
|
||||
})
|
||||
this.calendar = calendar;
|
||||
self.calendar = calendar;
|
||||
$.fullCalendar = calendar;
|
||||
return calendar;
|
||||
};
|
||||
function correct_date(date){
|
||||
var new_date = new Date();
|
||||
new_date.setTime(date.getTime() + date.getTimezoneOffset() * 60 * 1000);
|
||||
return new_date;
|
||||
}
|
||||
FullCalendar.Calendar.prototype.get_all_events = function(){
|
||||
this.currentData.all_events = [];
|
||||
var all_events = this.currentData.all_events;
|
||||
if(this.currentData.eventStore && this.currentData.eventStore.instances){
|
||||
var instances = this.currentData.eventStore.instances;
|
||||
Object.keys(instances).forEach(function(k){
|
||||
var instance = instances[k];
|
||||
var range = Object.assign({},instance.range);
|
||||
range.start = correct_date(range.start);
|
||||
range.end = correct_date(range.end);
|
||||
all_events.push(range);
|
||||
})
|
||||
}
|
||||
return this.currentData.all_events;
|
||||
}
|
||||
FullCalendar.Calendar.prototype.isAnOverlapEvent = function(eventStartDay, eventEndDay){
|
||||
eventStartDay = eventStartDay || eventEndDay;
|
||||
eventEndDay = eventEndDay || eventStartDay;
|
||||
if((typeof(eventStartDay)).toLowerCase() == "string")
|
||||
eventStartDay = new Date(eventStartDay);
|
||||
if((typeof(eventEndDay)).toLowerCase() == "string")
|
||||
eventEndDay = new Date(eventEndDay);
|
||||
var events = this.get_all_events();
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
var eventA = events[i];
|
||||
// start-time in between any of the events
|
||||
if (eventStartDay >= eventA.start && eventStartDay <= eventA.end) {
|
||||
return true;
|
||||
}
|
||||
//end-time in between any of the events
|
||||
if (eventEndDay >= eventA.start && eventEndDay <= eventA.end) {
|
||||
return true;
|
||||
}
|
||||
//any of the events in between/on the start-time and end-time
|
||||
if (eventStartDay <= eventA.start && eventEndDay >= eventA.end) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
window.is_chinese = ( I18n && I18n.locale.indexOf('zh') != -1 );
|
||||
window.datetime_format = is_chinese ? 'y M d h:m b' : 'd M, y h:m b';
|
||||
window.date_format = is_chinese ? 'y M d' : 'd M, y';
|
||||
window.time_format = "h:m b";
|
||||
window.date_time_str_format = 'y/MM/d H:m';
|
||||
window.std_date_format = 'y-MM-d';
|
||||
window.short_day = (is_chinese ? "d (w)" : "w d");
|
||||
window.short_date = (is_chinese ? "M d (w)" : "w d, M");
|
||||
window.short_date_time = (is_chinese ? "M d (w) h:m b" : "w d, M h:m b");
|
||||
window.getDateString = function(date, format,is_chinese) {
|
||||
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
var week_days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
|
||||
if(is_chinese){
|
||||
months = [];
|
||||
for(var i=0;i<12;i++){
|
||||
months.push((i+1)+"月");
|
||||
}
|
||||
week_days = ["週日","週一","週二","週三","週四","週五","週六"]
|
||||
}
|
||||
var getPaddedComp = function(comp) {
|
||||
return ((parseInt(comp) < 10) ? ('0' + comp) : comp)
|
||||
},
|
||||
formattedDate = format,
|
||||
o = {
|
||||
"y+": date.getFullYear() + (is_chinese ? "年" : ""), // year
|
||||
"MM+": getPaddedComp(date.getMonth() + 1), //raw month
|
||||
"M+": months[date.getMonth()], //month
|
||||
"d+": (is_chinese ? (date.getDate() + "日") : getPaddedComp(date.getDate())), //day
|
||||
"w+": week_days[date.getDay()], //weekday
|
||||
"h+": getPaddedComp((date.getHours() > 12) ? date.getHours() % 12 : date.getHours()), //hour
|
||||
"H+": getPaddedComp(date.getHours()), //hour
|
||||
"m+": getPaddedComp(date.getMinutes()), //minute
|
||||
"s+": getPaddedComp(date.getSeconds()), //second
|
||||
"S+": getPaddedComp(date.getMilliseconds()), //millisecond,
|
||||
"b+": (date.getHours() >= 12) ? 'PM' : 'AM'
|
||||
};
|
||||
|
||||
c = this;
|
||||
for (var k in o) {
|
||||
if (new RegExp("(" + k + ")").test(format)) {
|
||||
formattedDate = formattedDate.replace(RegExp.$1, o[k]);
|
||||
}
|
||||
}
|
||||
return formattedDate;
|
||||
};
|
||||
var Calendar = function(dom, property_id, valid_range, currentView, display_hire_event, locale = "en"){
|
||||
var c = this;
|
||||
display_hire_event = (display_hire_event == undefined ? true : display_hire_event);
|
||||
this.locale = locale.replace("_","-");
|
||||
this.title = $("#current_title");
|
||||
this.calendar = $(dom);
|
||||
this.calendar_dom = $(dom);
|
||||
this.nextBtn = $("#next_month_btn");
|
||||
this.prevBtn = $("#prev_month_btn");
|
||||
this.todayBtn = $("#today_btn");
|
||||
|
@ -11,7 +118,7 @@ var Calendar = function(dom,property_id){
|
|||
this.dialog = new EventDialog(c);
|
||||
this.loading = $('#calendar-loading');
|
||||
this.agenda_space = $("#calendar_agenda");
|
||||
this.currentView = "month";
|
||||
this.currentView = currentView || "dayGridMonth";
|
||||
this.property_id = property_id;
|
||||
this.navigation = $("#navigation");
|
||||
this.rangeSelection = $("#range_selection");
|
||||
|
@ -22,43 +129,105 @@ var Calendar = function(dom,property_id){
|
|||
var d = date.getDate();
|
||||
var m = date.getMonth();
|
||||
var y = date.getFullYear();
|
||||
var dview = (c.currentView == "agenda" ? "month" : c.currentView);
|
||||
c.calendar.fullCalendar({
|
||||
var dview = (c.currentView == "agenda" ? "dayGridMonth" : c.currentView);
|
||||
c.calendar_dom.css("overflow","visible");
|
||||
c.calendar_dom.fullCalendar({
|
||||
themeSystem: 'bootstrap',
|
||||
editable: false,
|
||||
selectable: false,
|
||||
events: "/xhr/property_hires/get_bookings?property_id="+c.property_id,
|
||||
header: false,
|
||||
default: dview,
|
||||
height: $("body").height() - 141,
|
||||
selectable: true,
|
||||
width: "100%",
|
||||
validRange: valid_range,
|
||||
locale: c.locale,
|
||||
events: function(args, success_callback, fail_callback) {
|
||||
var start = args.start;
|
||||
var end = args.end;
|
||||
$.ajax({
|
||||
url: "/xhr/property_hires/get_bookings?property_id="+c.property_id,
|
||||
dataType: 'json',
|
||||
type: 'GET',
|
||||
data: {
|
||||
start: Math.round(start.getTime() / 1000),
|
||||
end: Math.round(end.getTime() / 1000),
|
||||
_: Date.now(),
|
||||
display_hire_event: display_hire_event
|
||||
},
|
||||
success: function(json) {
|
||||
// json = json.map(function(obj){
|
||||
// obj.start = new Date(obj.start).toJSON();
|
||||
// obj.end = new Date(obj.end).toJSON();
|
||||
// return obj;
|
||||
// })
|
||||
success_callback(json);
|
||||
}
|
||||
});
|
||||
},
|
||||
// events: 'https://fullcalendar.io/demo-events.json',
|
||||
headerToolbar: false,
|
||||
fixedWeekCount: false,
|
||||
initialView: dview,
|
||||
loading: function(bool) {
|
||||
if (bool) c.loading.css("left",($(window).width()/2 - 60) + "px").show();
|
||||
if (bool) c.loading.show();
|
||||
else c.loading.hide();
|
||||
if(this.currentData)
|
||||
$('#current_title').html(this.currentData.viewTitle);
|
||||
},
|
||||
windowResize : function(view){
|
||||
view.setHeight($("body").height() - 141);
|
||||
c.calendar.fullCalendar("refetchEvents");
|
||||
c.calendar_dom.calendar.refetchEvents();
|
||||
},
|
||||
viewDisplay: function(view) {
|
||||
c.title.html(view.title);
|
||||
},
|
||||
eventClick: function(calEvent, e, view) {
|
||||
eventTimeFormat: { hour12: true, hour: '2-digit', minute: '2-digit', omitZeroMinute: true, meridiem: 'narrow' },
|
||||
eventClick: function(eventClickInfo) {
|
||||
var calEvent = {"event": eventClickInfo.event},
|
||||
originalEvent = eventClickInfo.jsEvent,
|
||||
view = eventClickInfo.view,
|
||||
el = $(eventClickInfo.el);
|
||||
if(el.hasClass("reserve_btn")){
|
||||
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;
|
||||
window.pick_hire_date(date_str,allow_times);
|
||||
}else{
|
||||
c.dialog.dismiss();
|
||||
c.dialog.inflate(calEvent);
|
||||
c.dialog.show({"x":e.originalEvent.clientX,"y":e.originalEvent.clientY});
|
||||
c.dialog.show({"x": originalEvent.clientX,"y": originalEvent.clientY});
|
||||
}
|
||||
},
|
||||
dateClick: function(ev) {
|
||||
var calendar = this;
|
||||
var calendar_dom = $(this.el);
|
||||
if(c.calendar_dom.hasClass("active_picker")){
|
||||
var date = ev.date,
|
||||
date_str = getDateString(date,date_time_str_format),
|
||||
day_element = ev.dayEl,
|
||||
jsEvent = ev.jsEvent;
|
||||
var time_str = date_str.split(" ")[1];
|
||||
var date_str = date_str.split(" ")[0];
|
||||
calendar_dom.trigger("init_time",[time_str]);
|
||||
calendar_dom.trigger("select_time",[date_str]);
|
||||
}
|
||||
},
|
||||
views: {
|
||||
dayGridMonth: {
|
||||
dayMaxEvents: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
c.nextBtn.click(function(){
|
||||
c.dialog.dismiss();
|
||||
c.calendar.fullCalendar('next');
|
||||
c.calendar_dom.calendar.next();
|
||||
c.title.text(c.calendar_dom.calendar.currentData.viewTitle);
|
||||
});
|
||||
c.prevBtn.click(function(){
|
||||
c.dialog.dismiss();
|
||||
c.calendar.fullCalendar('prev');
|
||||
c.calendar_dom.calendar.prev();
|
||||
c.title.text(c.calendar_dom.calendar.currentData.viewTitle);
|
||||
});
|
||||
c.todayBtn.click(function(){
|
||||
c.dialog.dismiss();
|
||||
c.calendar.fullCalendar('today');
|
||||
c.calendar_dom.calendar.today();
|
||||
c.title.text(c.calendar_dom.calendar.currentData.viewTitle);
|
||||
});
|
||||
c.modeBtns.click(function(){
|
||||
c.dialog.dismiss();
|
||||
|
@ -69,7 +238,7 @@ var Calendar = function(dom,property_id){
|
|||
if(c.currentView == "agenda")
|
||||
agendaView.refresh();
|
||||
else
|
||||
c.calendar.fullCalendar("refetchEvents");
|
||||
c.calendar_dom.calendar.refetchEvents();
|
||||
});
|
||||
|
||||
var toggleViews = function(view){
|
||||
|
@ -77,7 +246,7 @@ var Calendar = function(dom,property_id){
|
|||
c.modeBtns.each(function(){
|
||||
if ($(this).data("mode") == view)
|
||||
$(this).addClass("active");
|
||||
})
|
||||
});
|
||||
if(view != "agenda"){
|
||||
if(c.currentView == "agenda"){
|
||||
// $("#sec1").addClass("span3").removeClass("span7");
|
||||
|
@ -85,7 +254,7 @@ var Calendar = function(dom,property_id){
|
|||
// $("#sec3").addClass("span4").removeClass("span5");
|
||||
agendaView.hide();
|
||||
}
|
||||
c.calendar.fullCalendar('changeView',view);
|
||||
c.calendar_dom.calendar.changeView(view);
|
||||
}else{
|
||||
// $("#sec1").addClass("span7").removeClass("span3");
|
||||
$("#sec2").hide();
|
||||
|
@ -94,84 +263,156 @@ var Calendar = function(dom,property_id){
|
|||
}
|
||||
c.currentView = view;
|
||||
if(loadeventsonviewchange){
|
||||
c.calendar.fullCalendar("refetchEvents");
|
||||
c.calendar_dom.calendar.refetchEvents();
|
||||
loadeventsonviewchange = false;
|
||||
}
|
||||
if(c.calendar_dom.calendar.currentData){
|
||||
var viewTitle = c.calendar_dom.calendar.currentData.viewTitle;
|
||||
if(view == "timeGridDay" && $('.fc-col-header-cell-cushion ').text() != "")
|
||||
viewTitle = $('.fc-col-header-cell-cushion ').text() + ', ' + viewTitle;
|
||||
$('#current_title').html(viewTitle);
|
||||
}
|
||||
c.title.text(c.calendar_dom.calendar.currentData.viewTitle);
|
||||
// c.calendar_dom.calendar.rerenderEvents(); //Rerender to fix layout
|
||||
};
|
||||
if(c.currentView == "agenda"){toggleViews("agenda");loadeventsonviewchange = true;}
|
||||
};
|
||||
|
||||
this.destroy = function () {
|
||||
c.calendar_dom.fullCalendar("destroy");
|
||||
}
|
||||
|
||||
this.renderEvent = function(eventStick){
|
||||
if(eventStick.recurring == true)
|
||||
c.calendar.fullCalendar("refetchEvents");
|
||||
if(eventStick.recurring === true)
|
||||
c.calendar_dom.calendar.refetchEvents();
|
||||
else
|
||||
c.calendar.fullCalendar("renderEvent",eventStick);
|
||||
}
|
||||
c.calendar_dom.calendar.addEvent(eventStick);
|
||||
};
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
c.initialize();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var EventDialog = function(calendar,event){
|
||||
_t = this;
|
||||
var event_quick_view = null;
|
||||
var template = "";
|
||||
var _this_event = null;
|
||||
var month_names = ["Jan","Feb","March","April","May","June","July","Aug","Sep","Oct","Nov","Dec"];
|
||||
this.inflate = function(_event){
|
||||
if(!_event) throw new UserException("EventStick can't be null!");
|
||||
_event.allDay = _event.event.allDay;
|
||||
_event._start = _event.event.start;
|
||||
_event._end = (_event.event.end ? _event.event.end : _event.event.start);
|
||||
// var start_date = getDateString(_event._start,date_format);
|
||||
// var end_date = getDateString(_event._end,date_format);
|
||||
if(_event._end - _event._start > 86400 * 1000){
|
||||
_event.allDay = true;
|
||||
}
|
||||
_event.title = _event.event.title;
|
||||
var extendedProps = _event.event.extendedProps;
|
||||
Object.keys(extendedProps).forEach(function(k){
|
||||
_event[k] = extendedProps[k];
|
||||
})
|
||||
if(!_event.hiring_person_name)
|
||||
_event.hiring_person_name = "";
|
||||
_this_event = _event;
|
||||
var start_time = "",
|
||||
end_time = "",
|
||||
time_string = null;
|
||||
|
||||
if(_event.allDay) {
|
||||
start_time = $.fullCalendar.formatDate(_event._start,"MMM dd, yyyy");
|
||||
start_time = getDateString(_event._start,datetime_format, is_chinese);
|
||||
if(_event._end)
|
||||
end_time = $.fullCalendar.formatDate(_event._end,"MMM dd, yyyy");
|
||||
time_string = (_event._start === _event._end || !_event._end ? "<p class='start-date'><i class='icons-calendar' /> " + start_time + "</p>" : "<i class='icons-calendar' /> " + start_time + " <i class='icons-arrow-right-5' /> " + end_time + "");
|
||||
end_time = getDateString(_event._end,datetime_format, is_chinese);
|
||||
time_string = (_event._start === _event._end || !_event._end ? "<p class='start-date'><i class='icons-calendar' /></i>" + start_time + "</p>" : "<i class='icons-calendar' /></i>" + start_time + "<br><i class='icons-arrow-right-5' /></i>" + end_time + "");
|
||||
} else {
|
||||
var sh = _event._start.getHours() > 12 ? _event._start.getHours() - 12 : _event._start.getHours(),
|
||||
eh = _event._end.getHours() > 12 ? _event._end.getHours() - 12 : _event._end.getHours(),
|
||||
sm = _event._start.getMinutes() < 10 ? '0' + _event._start.getMinutes() : _event._start.getMinutes(),
|
||||
em = _event._end.getMinutes() < 10 ? '0' + _event._end.getMinutes() : _event._end.getMinutes(),
|
||||
stime = _event._start.getHours() > 12 ? sh + ':' + sm + " PM" : sh + ':' + sm + " AM",
|
||||
etime = _event._end.getHours() > 12 ? eh + ':' + em + " PM" : eh + ':' + em + " AM",
|
||||
same = (_event._start.getDate() == _event._end.getDate() && _event._start.getMonth() == _event._end.getMonth() && _event._start.getFullYear() == _event._end.getFullYear());
|
||||
start_time = month_names[_event._start.getMonth()] + " " + _event._start.getDate() + ", " + _event._start.getFullYear();
|
||||
end_time = month_names[_event._end.getMonth()] + " " + _event._end.getDate() + ", " + _event._end.getFullYear();
|
||||
|
||||
time_string = (same ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
|
||||
start_time = getDateString(_event._start,date_format, is_chinese);
|
||||
end_time = getDateString(_event._end,date_format, is_chinese);
|
||||
var stime = getDateString(_event._start,time_format, is_chinese),
|
||||
etime = getDateString(_event._end,time_format, is_chinese),
|
||||
same = (start_time == end_time);
|
||||
if( same ){
|
||||
time_string = "<p class='date'><i class='icons-calendar' /></i> " +
|
||||
start_time +
|
||||
"</p><p class='time'><i class='icons-clock' /></i> " + stime +
|
||||
" <i class='icons-arrow-right-5' /></i> " + etime ;
|
||||
}else{
|
||||
time_string = "<i class='icons-calendar' /></i><span class='start-date'>" + start_time + " " + stime +
|
||||
"</span><br><i class='icons-arrow-right-5' /></i><span class='end-date'>" +
|
||||
end_time + " " + etime + "</span>"
|
||||
}
|
||||
// time_string = (same ? "<p class='date'><i class='icons-calendar' /> " + start_time + "</p><p class='time'><i class='icons-clock' /> " + stime + " <i class='icons-arrow-right-5' /> " + etime : "<p class='start-date'><i class='icons-arrow-right-2' /> " + start_time + "<span class='pull-right'>" + stime + "</span></p><p class='end-date'><i class='icons-arrow-left-2' /> " + end_time + "<span class='pull-right'>" + etime + "</p>");
|
||||
}
|
||||
event_quick_view = $('<div class="calendar-modal" style="display:none;"></div>');
|
||||
template = '<div class="modal-content">' +
|
||||
'<div class="modal-header">' +
|
||||
'<div class="property_title">' + _event.property_title + '</div>' +
|
||||
'<button type="button" class="close event-close-btn" data-dismiss="modal" aria-hidden="true">×</button>' +
|
||||
'<h3>' + _event.title + '</h3>' +
|
||||
'</div>' +
|
||||
'<div class="modal-body">' +
|
||||
'<div class="event_summary">' + time_string + '<br>' + _event.hiring_person_name + '</div>'
|
||||
_event.note +
|
||||
'<div class="event_summary">' + time_string + '</br>' + _event.hiring_person_name + '</div>' + _event.note +
|
||||
(_event.error_message ? ("<br><span style=\"color: #FC4040;\">" + _event.error_message + "</span>") : "") +
|
||||
'</div>' +
|
||||
'<div class="modal-footer" />' +
|
||||
'<div class="modal-footer">' +
|
||||
(_event.view_button ? '<a href="' + _event.view_path + '" class="btn view-btn">'+ _event.view_path_name +'</a>' : "") +
|
||||
'</div>'
|
||||
'</div>';
|
||||
}
|
||||
|
||||
|
||||
this.show = function(pos){
|
||||
event_quick_view.css({display: 'inline-block',width: '',height: '', position: "fixed", "z-index": "10000"});
|
||||
var offset;
|
||||
var padding = 20;
|
||||
if(pos){
|
||||
offset = {"left":pos.x,"top":pos.y};
|
||||
var pos = getPosition(pos);
|
||||
event_quick_view.css({"left":pos.x+"px","top":pos.y+"px"});
|
||||
event_quick_view.offset(offset);
|
||||
}else{
|
||||
offset = {"left": padding, "top": padding};
|
||||
}
|
||||
event_quick_view.html(template).appendTo("body").show();
|
||||
event_quick_view.find(".event-close-btn").one("click",function(){_t.dismiss();});
|
||||
event_quick_view.find("a.delete").one("click",function(){calendar.deleteEvent(_this_event.delete_url,_this_event._id);return false;});
|
||||
event_quick_view.find("a.edit").one("click",function(){calendar.editEvent(_this_event.edit_url,_this_event.allDay);return false;});
|
||||
var window_width = $(window).width(),
|
||||
window_height = $(window).height();
|
||||
var dialog_width = event_quick_view.width(),
|
||||
dialog_height = event_quick_view.height();
|
||||
var new_offset = Object.assign({},offset);
|
||||
var need_redisplay = false;
|
||||
var new_width = null, new_height = null;
|
||||
var padding_top = padding + 40;
|
||||
if(offset.left + dialog_width > window_width){
|
||||
new_offset.left = window_width - dialog_width - padding;
|
||||
need_redisplay = true;
|
||||
}
|
||||
if(new_offset.left < padding){
|
||||
new_width = dialog_width - (padding - new_offset.left);
|
||||
new_offset.left = padding;
|
||||
need_redisplay = true;
|
||||
}
|
||||
if(offset.top + dialog_height > window_height){
|
||||
new_offset.top = window_height - dialog_height - padding;
|
||||
need_redisplay = true;
|
||||
}
|
||||
if(new_offset.top < padding_top){
|
||||
new_height = dialog_height - (padding_top - new_offset.top);
|
||||
new_offset.top = padding_top;
|
||||
need_redisplay = true;
|
||||
}
|
||||
if(need_redisplay){
|
||||
event_quick_view.offset(new_offset);
|
||||
event_quick_view.width(new_width);
|
||||
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();
|
||||
|
@ -239,6 +480,7 @@ var AgendaView = function(calendar){
|
|||
'<th>Date</th>' +
|
||||
'<th>Time</th>' +
|
||||
'<th>Events</th>' +
|
||||
'<th>Borrower</th>' +
|
||||
'</tr>' +
|
||||
'</thead>' +
|
||||
'<tbody>' +
|
||||
|
@ -251,11 +493,9 @@ var AgendaView = function(calendar){
|
|||
|
||||
var head_template = '<div>' +
|
||||
'<label>From</label>' +
|
||||
'<select name="start_month" class="form-control input-sm" />' +
|
||||
'<select name="start_year" class="form-control input-sm" />' +
|
||||
'<input class="input-large" id="agenda_start" placeholder="YYYY/MM" type="text" value="'+start_year+'/'+('0'+(start_month+1)).substr(-2,2)+'" title="YYYY/MM" autocomplete="off">'+
|
||||
'<label>To</label>' +
|
||||
'<select name="end_month" class="form-control input-sm" />' +
|
||||
'<select name="end_year" class="form-control input-sm" />' +
|
||||
'<input class="input-large" id="agenda_end" placeholder="YYYY/MM" type="text" value="'+end_year+'/'+('0'+(end_month+1)).substr(-2,2)+'" title="YYYY/MM" autocomplete="off">'+
|
||||
'<button id="show_events" class="btn btn-sm bt-filter btn-primary">Show Events</button>' +
|
||||
'</div>';
|
||||
|
||||
|
@ -265,6 +505,7 @@ var AgendaView = function(calendar){
|
|||
'<td>' +
|
||||
'<div class="event" />' +
|
||||
'</td>' +
|
||||
'<td class="Borrower">'+
|
||||
'</tr>';
|
||||
// var month_template = '<div class="span4"><h4></h4><div class="tiny_calendar"><table class="table"><tbody><tr><th class="week_title">Sun</th><th class="week_title">Mon</th><th class="week_title">Tue</th><th class="week_title">Wed</th><th class="week_title">Thu</th><th class="week_title">Fri</th><th class="week_title">Sat</th></tr></tbody></table></div></div>';
|
||||
|
||||
|
@ -283,7 +524,7 @@ var AgendaView = function(calendar){
|
|||
|
||||
this.inflate = function(forceInflation){
|
||||
loading(true);
|
||||
_calendar.calendar.hide();
|
||||
_calendar.calendar_dom.hide();
|
||||
_calendar.navigation.hide();
|
||||
|
||||
if(!forceInflation){
|
||||
|
@ -300,10 +541,12 @@ var AgendaView = function(calendar){
|
|||
_calendar.rangeSelection.append(renderHead().html()).show();
|
||||
_calendar.rangeSelection.find("button#show_events").click(function(){
|
||||
show_event_clicked = true;
|
||||
start_month = parseInt($("select[name=start_month]").val());
|
||||
end_month = parseInt($("select[name=end_month]").val());
|
||||
start_year = parseInt($("select[name=start_year]").val());
|
||||
end_year = parseInt($("select[name=end_year]").val());
|
||||
var starts = $("#agenda_start").val().split("/"),
|
||||
ends = $("#agenda_end").val().split("/");
|
||||
start_month = parseInt(starts[1]) - 1;
|
||||
end_month = parseInt(ends[1]) - 1;
|
||||
start_year = parseInt(starts[0]);
|
||||
end_year = parseInt(ends[0]);
|
||||
av.inflate(true);
|
||||
})
|
||||
}
|
||||
|
@ -337,7 +580,7 @@ var AgendaView = function(calendar){
|
|||
_calendar.rangeSelection.hide();
|
||||
agenda_space.hide();
|
||||
_calendar.navigation.show();
|
||||
_calendar.calendar.show();
|
||||
_calendar.calendar_dom.show();
|
||||
}
|
||||
|
||||
this.show = function(){
|
||||
|
@ -348,7 +591,7 @@ var AgendaView = function(calendar){
|
|||
return x.clone();
|
||||
}
|
||||
var eventsManager = function(){
|
||||
var url = "/xhr/calendars/agenda",
|
||||
var url = "/xhr/property_hires/get_bookings?property_id="+_calendar.property_id,
|
||||
sd = new Date(start_year,start_month,1),
|
||||
ed = new Date(end_year,end_month+1,0),
|
||||
usd = Math.round(sd/1000),
|
||||
|
@ -356,9 +599,39 @@ var AgendaView = function(calendar){
|
|||
$.ajax({
|
||||
type : "get",
|
||||
url : url,
|
||||
data : {"agenda_start":sd.toLocaleString(),"agenda_end":ed.toLocaleString(),"page_id" : _calendar.page_id,"unix_start":usd,"unix_end":ued},
|
||||
dataType : "json",
|
||||
data : {"agenda_start":sd.toLocaleString(),"agenda_end":ed.toLocaleString(),"page_id" : _calendar.page_id,"start":usd,"end":ued},
|
||||
success : function(data){
|
||||
$.each(data.events,function(i,e){
|
||||
$("#agenda_start,#agenda_end").datepicker({
|
||||
dateFormat: "yy/mm",
|
||||
onChangeMonthYear: function( year, month, inst ){
|
||||
$(this).val($.datepicker.formatDate('yy/mm', new Date(year, month-1, 1)));
|
||||
},
|
||||
gotoCurrent: true
|
||||
});
|
||||
$("#agenda_start,#agenda_end").on("focus",function(){
|
||||
var input = this;
|
||||
var inst = $(this).data("datepicker");
|
||||
var year_month = $(input).val().split("/");
|
||||
if(year_month.length == 2){
|
||||
inst.selectedYear = parseInt(year_month[0]);
|
||||
inst.selectedMonth = parseInt(year_month[1]) - 1;
|
||||
inst.drawYear = inst.selectedYear;
|
||||
inst.drawMonth = inst.selectedMonth;
|
||||
inst.currentYear = inst.selectedYear;
|
||||
inst.currentMonth = inst.selectedMonth;
|
||||
}
|
||||
$.datepicker._updateDatepicker(inst);
|
||||
})
|
||||
$("#agenda_start,#agenda_end").focus(function () {
|
||||
$(".ui-datepicker-calendar").hide();
|
||||
$("#ui-datepicker-div").position({
|
||||
my: "center top",
|
||||
at: "center bottom",
|
||||
of: $(this)
|
||||
});
|
||||
});
|
||||
$.each(data,function(i,e){
|
||||
var ed = eventDom(e),
|
||||
s = new Date(e.start),
|
||||
e = new Date(e.end),
|
||||
|
@ -415,14 +688,16 @@ var AgendaView = function(calendar){
|
|||
var e_t = $(event_template),
|
||||
s = new Date(event.start),
|
||||
e = new Date(event.end),
|
||||
dateFormat = "";
|
||||
dateFormat = "",
|
||||
hiring_person_name = event.hiring_person_name;
|
||||
if(s.getDate() == e.getDate() && s.getMonth() == s.getMonth() && e.getFullYear() == e.getFullYear())
|
||||
dateFormat = $.fullCalendar.formatDate(s, "ddd dd");
|
||||
dateFormat = getDateString(s, short_day,is_chinese);
|
||||
else
|
||||
dateFormat = $.fullCalendar.formatDates(s, e, "ddd dd, MMM - {ddd dd, MMM}");
|
||||
dateFormat = getDateString(s,short_date,is_chinese) + ' - ' + getDateString(e,short_date,is_chinese);
|
||||
e_t.find("td:first").text(dateFormat);
|
||||
e_t.find("td.event_time").text((event.allDay ? "All Day" : $.fullCalendar.formatDate(s, "hh:mm")));
|
||||
e_t.find("div.event").text(event.title).css("color",event.color);
|
||||
e_t.find("td.event_time").text((event.diff_day ? (getDateString(s, short_date_time,is_chinese)+"~"+getDateString(e, short_date_time, is_chinese)) : (getDateString(s, time_format)+"~"+getDateString(e, time_format))));
|
||||
e_t.find("div.event").html(event.title).css("color",event.color);
|
||||
e_t.find("td.Borrower").text(hiring_person_name);
|
||||
return e_t;
|
||||
}
|
||||
|
||||
|
@ -565,33 +840,3 @@ var AgendaView = function(calendar){
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,140 @@
|
|||
.card {
|
||||
position: relative;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
background-clip: border-box;
|
||||
border: 1px solid rgba(0,0,0,.125);
|
||||
border-radius: .25rem;
|
||||
}
|
||||
|
||||
.card hr {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: .75rem 1.25rem;
|
||||
margin-bottom: 0;
|
||||
background-color: rgba(0,0,0,.03);
|
||||
border-bottom: 1px solid rgba(0,0,0,.125);
|
||||
}
|
||||
|
||||
.card-header:first-child {
|
||||
border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
align-items: normal;
|
||||
-webkit-box-flex: 1;
|
||||
-ms-flex: 1 1 auto;
|
||||
flex: 1 1 auto;
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
margin-bottom: .75rem;
|
||||
}
|
||||
|
||||
.card-header + .list-group .list-group-item:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.card-text:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: .75rem 1.25rem;
|
||||
background-color: rgba(0,0,0,.03);
|
||||
border-top: 1px solid rgba(0,0,0,.125);
|
||||
}
|
||||
|
||||
.card-footer:last-child {
|
||||
border-radius: 0 0 calc(.25rem - 1px) calc(.25rem - 1px);
|
||||
}
|
||||
|
||||
.card-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card {
|
||||
margin-bottom: 0.9375em;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 576px) {
|
||||
flex-flow: row wrap;
|
||||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card {
|
||||
flex: 1 0 0%;
|
||||
margin-bottom: 0;
|
||||
|
||||
+ .card {
|
||||
margin-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-right-radius: 0;
|
||||
|
||||
.card-img-top,
|
||||
.card-header {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.card-img-bottom,
|
||||
.card-footer {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-left-radius: 0;
|
||||
|
||||
.card-img-top,
|
||||
.card-header {
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.card-img-bottom,
|
||||
.card-footer {
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:only-child {
|
||||
border-radius: .25rem;
|
||||
|
||||
.card-img-top,
|
||||
.card-header {
|
||||
border-top-radius: .25rem;
|
||||
}
|
||||
|
||||
.card-img-bottom,
|
||||
.card-footer {
|
||||
border-radius: .25rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-child):not(:last-child):not(:only-child) {
|
||||
border-radius: 0;
|
||||
|
||||
.card-img-top,
|
||||
.card-img-bottom,
|
||||
.card-header,
|
||||
.card-footer {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*reset*/
|
||||
h1, h2, h3, h4, h5, p{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
br{
|
||||
display: block;
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
ol, ul{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
li{
|
||||
list-style: none;
|
||||
}
|
||||
body > img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img{
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
outline: none;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
table, tr, td{
|
||||
padding: 0;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
/*reset end *//* CSS Document */
|
||||
|
||||
#property_order_table{
|
||||
border-collapse: unset !important;
|
||||
position: relative;
|
||||
width: 593px;
|
||||
margin: 40px auto;
|
||||
}
|
||||
|
||||
#property_order_table th{
|
||||
background-color: #454545;
|
||||
color: #fff;
|
||||
}
|
||||
.position-text{
|
||||
position: relative;
|
||||
width: 85px;
|
||||
}
|
||||
|
||||
#property_order_table .editable-input{
|
||||
position: relative;
|
||||
width: 25px;
|
||||
margin-bottom: 0;
|
||||
padding: 0px 0px 0px 5px;
|
||||
}
|
||||
|
||||
.position-text-div{
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.order-edit-notification{
|
||||
background-color: #ffffd5;
|
||||
z-index: 10;
|
||||
display: none;
|
||||
height: 25px;
|
||||
left: 40%;
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
margin-top: 5px;
|
||||
top: 85px;
|
||||
width: 400px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
|
@ -1,3 +1,18 @@
|
|||
#hire_form label.col-sm-4.control-label{
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
#calendar.active_picker .fc-scrollgrid-sync-inner,#calendar.active_picker .fc-timegrid-slot{
|
||||
cursor: pointer;
|
||||
}
|
||||
#calendar.active_picker{
|
||||
.fc-scrollgrid-sync-inner:hover, .fc-timegrid-slot:hover{
|
||||
background: var(--fc-highlight-color, rgba(188, 232, 241, 0.3));
|
||||
}
|
||||
}
|
||||
a.reserve_btn{
|
||||
cursor: pointer;
|
||||
}
|
||||
/* orbit calendar */
|
||||
#orbit_calendar {
|
||||
transition: all 0.3s ease;
|
||||
|
@ -96,7 +111,9 @@
|
|||
& > * {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
& > select {
|
||||
height: 3em;
|
||||
}
|
||||
@media screen and (max-width: 479px) {
|
||||
margin-right: 0;
|
||||
|
||||
|
@ -253,6 +270,9 @@
|
|||
.event_list td {
|
||||
padding: 0;
|
||||
}
|
||||
.event_list th {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.event_holder {
|
||||
|
@ -627,8 +647,9 @@
|
|||
}
|
||||
|
||||
#calendar-loading {
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 10;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
|
@ -636,11 +657,12 @@
|
|||
border-radius: 4px;
|
||||
border: 1px solid #dbdbdb;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
background-image: url("/assets/loading1.gif");
|
||||
background-image: url("/assets/property_hire/loading1.gif");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center 20px;
|
||||
background-size: 50%;
|
||||
box-shadow: 0 0 25px 0 rgba(0, 0, 0, 0.2);
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
&:after {
|
||||
content: "Loading...";
|
||||
|
@ -691,7 +713,7 @@
|
|||
|
||||
.calendar-modal {
|
||||
position: fixed;
|
||||
z-index: 1050;
|
||||
z-index: 10000;
|
||||
width: 300px;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
|
@ -739,3 +761,369 @@
|
|||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* fullcalendar custom css */
|
||||
.table-bordered th, .table-bordered td {
|
||||
border: 1px solid #dee2e6;
|
||||
}
|
||||
.fc .fc-event,
|
||||
.fc .fc-scrollgrid table tr {
|
||||
-moz-column-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.fc-media-print {
|
||||
display: block; /* undo flexbox. FF doesn't know how to flow */
|
||||
max-width: 100% /* width will be hardcoded too */
|
||||
}
|
||||
|
||||
.fc-media-print .fc-timegrid-slots,
|
||||
.fc-media-print .fc-timegrid-axis-chunk,
|
||||
.fc-media-print .fc-timeline-slots,
|
||||
.fc-media-print .fc-non-business,
|
||||
.fc-media-print .fc-bg-event {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fc-media-print .fc-toolbar button,
|
||||
.fc-media-print .fc-h-event,
|
||||
.fc-media-print .fc-v-event {
|
||||
color: #000 !important;
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.fc-media-print .fc-event,
|
||||
.fc-media-print .fc-event-main { /* often controls the text-color */
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.fc-media-print .fc-timegrid-event {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.fc .fc-timeline-body {
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
z-index: 1; /* scope slots, bg, etc */
|
||||
}
|
||||
/*
|
||||
vertical slots in both the header AND the body
|
||||
*/
|
||||
.fc .fc-timeline-slots {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
bottom: 0
|
||||
}
|
||||
.fc .fc-timeline-slots > table {
|
||||
height: 100%;
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* border for both header AND body cells */
|
||||
|
||||
}
|
||||
.fc .fc-timeline-slot-minor {
|
||||
border-style: dotted;
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* header cells (aka "label") */
|
||||
|
||||
}
|
||||
.fc .fc-timeline-slot-frame {
|
||||
display: flex;
|
||||
align-items: center; /* vertical align */
|
||||
justify-content: center; /* horizontal align */
|
||||
overflow: hidden; /* important so text doesn't bleed out and cause extra scroll */
|
||||
}
|
||||
.fc .fc-timeline-header-row-chrono { /* a row of times */
|
||||
}
|
||||
.fc .fc-timeline-header-row-chrono .fc-timeline-slot-frame {
|
||||
justify-content: flex-start; /* horizontal align left or right */
|
||||
}
|
||||
.fc .fc-timeline-slot-cushion {
|
||||
padding: 4px 5px; /* TODO: unify with fc-col-header? */
|
||||
white-space: normal;
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* NOTE: how does the top row of cells get horizontally centered? */
|
||||
/* for the non-chrono-row, the fc-sticky system looks for text-align center, */
|
||||
/* and it's a fluke that the default browser stylesheet already does this for <th> */
|
||||
/* TODO: have StickyScrolling look at natural left coord to detect centeredness. */
|
||||
|
||||
}
|
||||
/* only owns one side, so can do dotted */
|
||||
.fc-direction-ltr .fc-timeline-slot { border-right: 0 !important }
|
||||
.fc-direction-rtl .fc-timeline-slot { border-left: 0 !important }
|
||||
.fc .fc-timeline-now-indicator-container {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 0;
|
||||
}
|
||||
.fc .fc-timeline-now-indicator-arrow,
|
||||
.fc .fc-timeline-now-indicator-line {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
border-style: solid;
|
||||
border-color: red;
|
||||
border-color: var(--fc-now-indicator-color, red);
|
||||
}
|
||||
.fc .fc-timeline-now-indicator-arrow {
|
||||
margin: 0 -6px; /* 5, then one more to counteract scroller's negative margins */
|
||||
|
||||
/* triangle pointing down. TODO: mixin */
|
||||
border-width: 6px 5px 0 5px;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
.fc .fc-timeline-now-indicator-line {
|
||||
margin: 0 -1px; /* counteract scroller's negative margins */
|
||||
bottom: 0;
|
||||
border-width: 0 0 0 1px;
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* container */
|
||||
|
||||
}
|
||||
.fc .fc-timeline-events {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
width: 0; /* for event positioning. will end up on correct side based on dir */
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* harness */
|
||||
|
||||
}
|
||||
.fc .fc-timeline-event-harness,
|
||||
.fc .fc-timeline-more-link {
|
||||
position: absolute;
|
||||
top: 0; /* for when when top can't be computed yet */
|
||||
/* JS will set tht left/right */
|
||||
}
|
||||
/* z-index, scoped within fc-timeline-events */
|
||||
.fc-timeline-event { z-index: 1 }
|
||||
.fc-timeline-event.fc-event-mirror { z-index: 2 }
|
||||
.fc-timeline-event {
|
||||
position: relative; /* contains things. TODO: make part of fc-h-event and fc-v-event */
|
||||
display: flex; /* for v-aligning start/end arrows and making fc-event-main stretch all the way */
|
||||
align-items: center;
|
||||
border-radius: 0;
|
||||
padding: 2px 1px;
|
||||
margin-bottom: 1px;
|
||||
font-size: .85em;
|
||||
font-size: var(--fc-small-font-size, .85em)
|
||||
|
||||
/* time and title spacing */
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
}
|
||||
.fc-timeline-event .fc-event-main {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
min-width: 0; /* important for allowing to shrink all the way */
|
||||
}
|
||||
.fc-timeline-event .fc-event-time {
|
||||
font-weight: bold;
|
||||
}
|
||||
.fc-timeline-event .fc-event-time,
|
||||
.fc-timeline-event .fc-event-title {
|
||||
white-space: normal;
|
||||
padding: 0 2px;
|
||||
}
|
||||
/* move 1px away from slot line */
|
||||
.fc-direction-ltr .fc-timeline-event.fc-event-end,
|
||||
.fc-direction-ltr .fc-timeline-more-link {
|
||||
margin-right: 1px;
|
||||
}
|
||||
.fc-direction-rtl .fc-timeline-event.fc-event-end,
|
||||
.fc-direction-rtl .fc-timeline-more-link {
|
||||
margin-left: 1px;
|
||||
}
|
||||
/* make event beefier when overlap not allowed */
|
||||
.fc-timeline-overlap-disabled .fc-timeline-event {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
/* arrows indicating the event continues into past/future */
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
/* part of the flexbox flow */
|
||||
.fc-timeline-event:not(.fc-event-start):before,
|
||||
.fc-timeline-event:not(.fc-event-end):after {
|
||||
content: "";
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
opacity: .5;
|
||||
|
||||
/* triangle. TODO: mixin */
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0 1px;
|
||||
border: 5px solid #000; /* TODO: var */
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
/* pointing left */
|
||||
.fc-direction-ltr .fc-timeline-event:not(.fc-event-start):before,
|
||||
.fc-direction-rtl .fc-timeline-event:not(.fc-event-end):after {
|
||||
border-left: 0;
|
||||
}
|
||||
/* pointing right */
|
||||
.fc-direction-ltr .fc-timeline-event:not(.fc-event-end):after,
|
||||
.fc-direction-rtl .fc-timeline-event:not(.fc-event-start):before {
|
||||
border-right: 0;
|
||||
}
|
||||
/* +more events indicator */
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
.fc-timeline-more-link {
|
||||
font-size: .85em;
|
||||
font-size: var(--fc-small-font-size, .85em);
|
||||
color: inherit;
|
||||
color: var(--fc-more-link-text-color, inherit);
|
||||
background: #d0d0d0;
|
||||
background: var(--fc-more-link-bg-color, #d0d0d0);
|
||||
padding: 1px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.fc-timeline-more-link-inner { /* has fc-sticky */
|
||||
display: inline-block;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 2px;
|
||||
}
|
||||
.fc .fc-timeline-bg { /* a container for bg content */
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 0;
|
||||
left: 0; /* will take precedence when LTR */
|
||||
right: 0; /* will take precedence when RTL */ /* TODO: kill */
|
||||
}
|
||||
.fc .fc-timeline-bg .fc-non-business { z-index: 1 }
|
||||
.fc .fc-timeline-bg .fc-bg-event { z-index: 2 }
|
||||
.fc .fc-timeline-bg .fc-highlight { z-index: 3 }
|
||||
.fc .fc-timeline-bg-harness {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.fc .fc-resource-timeline-divider {
|
||||
width: 3px; /* important to have width to shrink this cell. no cross-browser problems */
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.fc {
|
||||
|
||||
|
||||
/* will match horizontal groups in the datagrid AND group lanes in the timeline area */
|
||||
|
||||
}
|
||||
|
||||
.fc .fc-resource-timeline .fc-resource-group:not([rowspan]) {
|
||||
background: rgba(208, 208, 208, 0.3);
|
||||
background: var(--fc-neutral-bg-color, rgba(208, 208, 208, 0.3));
|
||||
}
|
||||
|
||||
.fc .fc-timeline-lane-frame {
|
||||
position: relative; /* contains the fc-timeline-bg container, which liquidly expands */
|
||||
/* the height is explicitly set by row-height-sync */
|
||||
}
|
||||
|
||||
.fc .fc-timeline-overlap-enabled .fc-timeline-lane-frame .fc-timeline-events { /* has height set on it */
|
||||
box-sizing: content-box; /* padding no longer part of height */
|
||||
padding-bottom: 10px; /* give extra spacing underneath for selecting */
|
||||
}
|
||||
|
||||
/* hack to make bg expand to lane's full height in resource-timeline with expandRows (#6134) */
|
||||
.fc-timeline-body-expandrows td.fc-timeline-lane {
|
||||
position: relative;
|
||||
}
|
||||
.fc-timeline-body-expandrows .fc-timeline-lane-frame {
|
||||
position: static;
|
||||
}
|
||||
/* the "frame" */
|
||||
.fc-datagrid-cell-frame-liquid {
|
||||
height: 100%; /* needs liquid hack */
|
||||
}
|
||||
.fc-liquid-hack .fc-datagrid-cell-frame-liquid {
|
||||
height: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* the "frame" in a HEADER */
|
||||
/* needs to position the column resizer */
|
||||
/* needs to vertically center content */
|
||||
|
||||
}
|
||||
.fc .fc-datagrid-header .fc-datagrid-cell-frame {
|
||||
position: relative; /* for resizer */
|
||||
display: flex;
|
||||
justify-content: flex-start; /* horizontal align (natural left/right) */
|
||||
align-items: center; /* vertical align */
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* the column resizer (only in HEADER) */
|
||||
|
||||
}
|
||||
.fc .fc-datagrid-cell-resizer {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 5px;
|
||||
cursor: col-resize;
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* the cushion */
|
||||
|
||||
}
|
||||
.fc .fc-datagrid-cell-cushion {
|
||||
padding: 8px;
|
||||
white-space: normal;
|
||||
overflow: hidden; /* problem for col resizer :( */
|
||||
}
|
||||
.fc {
|
||||
|
||||
/* expander icons */
|
||||
|
||||
}
|
||||
.fc .fc-datagrid-expander {
|
||||
cursor: pointer;
|
||||
opacity: 0.65
|
||||
|
||||
}
|
||||
.fc .fc-datagrid-expander .fc-icon { /* the expander and spacers before the expander */
|
||||
display: inline-block;
|
||||
width: 1em; /* ensure constant width, esp for empty icons */
|
||||
}
|
||||
.fc .fc-datagrid-expander-placeholder {
|
||||
cursor: auto;
|
||||
}
|
||||
.fc .fc-resource-timeline-flat .fc-datagrid-expander-placeholder {
|
||||
display: none;
|
||||
}
|
||||
.fc-direction-ltr .fc-datagrid-cell-resizer { right: -3px }
|
||||
.fc-direction-rtl .fc-datagrid-cell-resizer { left: -3px }
|
||||
.fc-direction-ltr .fc-datagrid-expander { margin-right: 3px }
|
||||
.fc-direction-rtl .fc-datagrid-expander { margin-left: 3px }
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,44 +1,87 @@
|
|||
class Admin::PropertyHiresController < OrbitAdminController
|
||||
|
||||
include Admin::PropertyHiresHelper
|
||||
def index
|
||||
@tags = @module_app.tags
|
||||
@categories = @module_app.categories.enabled
|
||||
@filter_fields = filter_fields(@categories, @tags)
|
||||
@table_fields = ["property_hire.title", :category, "property_hire.location", "property_hire.available_for_hire"]
|
||||
|
||||
@properties = Property.where(:title.ne => "")
|
||||
.order_by(sort)
|
||||
@properties = Property.order_by(sort)
|
||||
.with_categories(filters("category"))
|
||||
.with_tags(filters("tag"))
|
||||
|
||||
@properties = search_data(@properties,[:title]).page(params[:page]).per(10)
|
||||
if request.xhr?
|
||||
render :partial => "index"
|
||||
end
|
||||
end
|
||||
def fields_display_order
|
||||
uid = params[:id].split("-").last
|
||||
@property = Property.find_by(:uid=>uid)
|
||||
end
|
||||
def update_fields_display_order
|
||||
uid = params[:id].split("-").last
|
||||
@property = Property.find_by(:uid=>uid)
|
||||
prop = params.require(:property).permit!
|
||||
@property.update_attributes(prop)
|
||||
redirect_to params[:referer_url]
|
||||
end
|
||||
def order
|
||||
@properties = Property.all.sort_order
|
||||
end
|
||||
def updateorder
|
||||
ids_with_order = params[:order]
|
||||
ids_with_order.each_with_index do |id,idx|
|
||||
property = Property.find(id) rescue nil
|
||||
if !property.nil?
|
||||
property.order_position = idx
|
||||
property.save
|
||||
end
|
||||
end
|
||||
render :json => {"success" => true}.to_json
|
||||
end
|
||||
|
||||
def my_bookings
|
||||
@table_fields = ["property_hire.hiring_person_name", "property_hire.reason_for_hire", "property_hire.hiring_person_number", "property_hire.period", "property_hire.passed", :actions]
|
||||
@table_fields = ["property_hire.title","property_hire.hiring_person_name", "property_hire.reason_for_hire", "property_hire.hiring_person_number", "property_hire.period", "property_hire.passed", :actions]
|
||||
@bookings = PHire.where(:hiring_person_id => current_user.member_profile.id.to_s).desc(:created_at).page(params[:page]).per(10)
|
||||
end
|
||||
|
||||
def new
|
||||
@property = Property.new
|
||||
def copy
|
||||
@property = Property.where(:uid => params[:id].split("-").last).first.clone_new #rescue nil
|
||||
create_set (false)
|
||||
@locations = PropertyLocation.all.desc(:created_at).collect{|loc| [loc.title, loc.id.to_s]}
|
||||
@locations << ["Other", "other_location"]
|
||||
end
|
||||
|
||||
def new
|
||||
@property = Property.new
|
||||
create_set (false)
|
||||
@locations = PropertyLocation.all.desc(:created_at).collect{|loc| [loc.title, loc.id.to_s]}
|
||||
@locations << ["Other", "other_location"]
|
||||
end
|
||||
def edit_hire
|
||||
@phire = PHire.find(params[:id])
|
||||
end
|
||||
def update_hire
|
||||
@phire = PHire.find(params[:id])
|
||||
@phire.update_attributes(phire_params)
|
||||
redirect_to admin_property_hire_path(:id=>@phire.property)
|
||||
end
|
||||
def edit
|
||||
@property = Property.where(:uid => params[:id].split("-").last).first rescue nil
|
||||
create_set (true)
|
||||
@locations = PropertyLocation.all.desc(:created_at).collect{|loc| [loc.title, loc.id.to_s]}
|
||||
@locations << ["Other", "other_location"]
|
||||
end
|
||||
|
||||
def show
|
||||
@table_fields = ["property_hire.hiring_person_name", "property_hire.reason_for_hire", "property_hire.hiring_person_number", "property_hire.period", "property_hire.passed", :actions]
|
||||
@table_fields = ["property_hire.hiring_person_name", "property_hire.reason_for_hire", "property_hire.hiring_person_number", "property_hire.period", "property_hire.passed", "property_hire.actions"]
|
||||
@property = Property.where(:uid => params[:id].split("-").last).first rescue nil
|
||||
@bookings = @property.p_hires.desc(:created_at).page(params[:page]).per(10)
|
||||
end
|
||||
|
||||
def destroy
|
||||
property = Property.find(params[:id]) rescue nil
|
||||
email = property.get_owner_emails
|
||||
Admin::PropertyHiresHelper::HireMethod.send_mail('delete',email,property.id,nil,nil,current_user.id)
|
||||
property.destroy if !property.nil?
|
||||
if params[:page]
|
||||
redirect_to admin_property_hires_path(:page => params[:page])
|
||||
|
@ -50,17 +93,43 @@ class Admin::PropertyHiresController < OrbitAdminController
|
|||
def update
|
||||
property = Property.where(:uid => params[:id].split("-").last).first rescue nil
|
||||
redirect_to admin_property_hires_path and return if property.nil?
|
||||
property.update_attributes(property_params)
|
||||
if params[:page]
|
||||
redirect_to admin_property_hires_path(:page => params[:page])
|
||||
else
|
||||
redirect_to admin_property_hires_path
|
||||
@property_params = property_params
|
||||
if @property_params[:p_hire_fields]
|
||||
@property_params[:p_hire_fields].each do |a|
|
||||
@field_name = 'property'
|
||||
field_status = a.last[:id].present?
|
||||
@attribute_field = PHireField.add_p_hire_field(property, a.last, a.last[:id], field_status)
|
||||
@attribute = property
|
||||
end
|
||||
if property.need_change_tmp_reason
|
||||
Thread.new do
|
||||
p_hire_field_ids = property.p_hire_fields.where(:display_in_reason_for_hire=>true).pluck(:id)
|
||||
property.p_hires.each do |p_hire|
|
||||
p_hire.tmp_reason_for_hire = p_hire.p_hire_field_values.where(:p_hire_field_id.in=>p_hire_field_ids).map{|v| v.get_value_by_locale(I18n.locale.to_s)}.join(" ")
|
||||
p_hire.save
|
||||
end
|
||||
property.update(:need_change_tmp_reason => false)
|
||||
end
|
||||
end
|
||||
flash.now[:notice] = "Updated Fields"
|
||||
property.p_hire_fields.each{|t| t.destroy if t["to_delete"] == true}
|
||||
else
|
||||
if @property_params["special_unavailable_dates"].nil?
|
||||
@property_params["special_unavailable_dates"] = []
|
||||
end
|
||||
property.update_attributes(@property_params)
|
||||
email = property.get_owner_emails
|
||||
Admin::PropertyHiresHelper::HireMethod.send_mail('edit',email,property.id,nil,nil,current_user.id)
|
||||
end
|
||||
redirect_to params[:referer_url]
|
||||
end
|
||||
|
||||
def create
|
||||
property = Property.new(property_params)
|
||||
if property.save
|
||||
tmp_property_params = property_params
|
||||
if tmp_property_params["copy_id"] && tmp_property_params["clone_p_hires"].blank?
|
||||
tmp_property_params["except_clone_relations"] = ["p_hires","p_hire_field_values"]
|
||||
end
|
||||
if Property.create(tmp_property_params)
|
||||
redirect_to admin_property_hires_path
|
||||
end
|
||||
end
|
||||
|
@ -70,14 +139,29 @@ class Admin::PropertyHiresController < OrbitAdminController
|
|||
end
|
||||
|
||||
def settings
|
||||
if PropertyHireSetting.count == 0
|
||||
@settings = PropertyHireSetting.create
|
||||
else
|
||||
@settings = PropertyHireSetting.first
|
||||
end
|
||||
if request.request_method == "PATCH"
|
||||
@settings.update_attributes(settings_params)
|
||||
@settings.update_attributes(settings_params.except("property_day_settings"))
|
||||
@settings.save
|
||||
if settings_params["property_day_settings"]
|
||||
property_day_settings = settings_params["property_day_settings"].values
|
||||
property_day_settings.each do |setting|
|
||||
setting["property_id"] = "default_settings"
|
||||
s = nil
|
||||
if setting["id"].present?
|
||||
s = PropertyDaySetting.where(:id=>setting["id"]).first
|
||||
end
|
||||
if s
|
||||
if setting["_destroy"] == "1"
|
||||
s.destroy
|
||||
else
|
||||
s.update_attributes(setting.except("id","_destroy"))
|
||||
end
|
||||
else
|
||||
s = PropertyDaySetting.create(setting.except("id","_destroy"))
|
||||
end
|
||||
end
|
||||
end
|
||||
@saved = true
|
||||
else
|
||||
@saved = false
|
||||
|
@ -104,6 +188,8 @@ class Admin::PropertyHiresController < OrbitAdminController
|
|||
phire.passed = false
|
||||
end
|
||||
phire.save
|
||||
email = [phire.hiring_person_email].select{|e| e.present?}
|
||||
Admin::PropertyHiresHelper::HireMethod.send_mail('p_hire',email,phire.property.id,nil,phire.id,(current_user.id rescue nil))
|
||||
if params[:ref] == "index"
|
||||
if params[:page]
|
||||
redirect_to admin_property_hire_path(phire.property, :page => params[:page])
|
||||
|
@ -162,6 +248,30 @@ class Admin::PropertyHiresController < OrbitAdminController
|
|||
end
|
||||
end
|
||||
end
|
||||
def custom_fields
|
||||
@field_name = 'property'
|
||||
uid = params[:id].split("-").last
|
||||
@attribute = Property.find_by(:uid=>uid)
|
||||
@attribute_type = 'property'
|
||||
@class = 'properties'
|
||||
end
|
||||
|
||||
def checkforthread
|
||||
running = !File.exists?("public/uploads/reservation_export/#{params[:property_id]}/#{params[:property_title]}.xlsx")
|
||||
render :json => {"status" => running}.to_json
|
||||
end
|
||||
|
||||
def export_reservation_data
|
||||
property = Property.find(params[:id])
|
||||
title = property.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')
|
||||
f = "public/uploads/reservation_export/#{property.id}/#{title}.xlsx"
|
||||
File.delete(f) if File.exists?(f)
|
||||
url = request.host_with_port
|
||||
Thread.new do
|
||||
system("rake property_hire_tasks:prepare_download[#{property.id},#{url}] >> #{Rails.root}/log/rake.log &")
|
||||
end
|
||||
render :json => {"success" => true, "title" => title}.to_json
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
@ -172,11 +282,62 @@ class Admin::PropertyHiresController < OrbitAdminController
|
|||
def location_params
|
||||
params.require(:property_location).permit!
|
||||
end
|
||||
|
||||
def phire_params
|
||||
p_hire_params = params.require(:p_hire).permit!
|
||||
property = (@phire ? @phire.property : Property.find(params[:p_hire][:property_id]) rescue nil)
|
||||
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 += "<br>".html_safe
|
||||
end
|
||||
p_hire_params["note_for_hire"] = note_texts
|
||||
p_hire_params.delete("notes_selector")
|
||||
end
|
||||
return p_hire_params
|
||||
end
|
||||
def property_params
|
||||
prop = params.require(:property).permit!
|
||||
if prop[:weekdays].nil?
|
||||
prop[:weekdays] = []
|
||||
end
|
||||
if prop[:owners].nil?
|
||||
prop[:owners] = []
|
||||
end
|
||||
prop.delete(:property_location) if prop[:property_location] == "other"
|
||||
prop
|
||||
notes_selector = prop["notes_selector"]
|
||||
notes_selector = {} if notes_selector.nil?
|
||||
prop["notes_selector"] = (0 ... notes_selector.keys.count).to_a.map{|k| k.to_s}.zip(notes_selector.values).to_h
|
||||
return prop
|
||||
end
|
||||
def create_set (save_flag)
|
||||
@email_set = []
|
||||
['p_hire','edit','delete'].each do |field_name|
|
||||
email_set = @property.hire_email_sets.select{|v| v.field_name==field_name}
|
||||
if email_set.length==0
|
||||
title = Hash.new
|
||||
content = Hash.new
|
||||
I18n.available_locales.each do |locale|
|
||||
I18n.with_locale(locale) do
|
||||
title[locale] = t("property_hire.email_#{field_name}_success")
|
||||
content[locale] = t("property_hire.email_#{field_name}_content")
|
||||
end
|
||||
end
|
||||
if save_flag
|
||||
email_set = @property.hire_email_sets.create(field_name:field_name,title:title,content:content)
|
||||
else
|
||||
email_set = @property.hire_email_sets.new(field_name:field_name,title:title,content:content)
|
||||
end
|
||||
else
|
||||
email_set = email_set[0]
|
||||
end
|
||||
@email_set << email_set
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,36 +1,93 @@
|
|||
class PropertyHiresController < ApplicationController
|
||||
include Admin::PropertyHiresHelper
|
||||
FrontendMethods = ["hire", "view_calendar", "hire_success"]
|
||||
def index
|
||||
properties = Property.filter_by_categories.filter_by_tags.desc(:created_at)
|
||||
data = properties.collect do |property|
|
||||
actions = []
|
||||
if property.can_be_hired
|
||||
actions << {
|
||||
"text" => t("property_hire.hire"),
|
||||
"btn-class" => "btn-primary",
|
||||
"link" => OrbitHelper.url_to_show(property.to_param) + "?method=hire"
|
||||
}
|
||||
actions << {
|
||||
"text" => t("property_hire.view_calendar"),
|
||||
"btn-class" => "btn-info",
|
||||
"link" => OrbitHelper.url_to_show(property.to_param) + "?method=view_calendar"
|
||||
}
|
||||
end
|
||||
{
|
||||
"title" => property.title,
|
||||
"image" => property.image.url,
|
||||
"image-thumb" => property.image.thumb.url,
|
||||
"url_to_show" => OrbitHelper.url_to_show(property.to_param),
|
||||
"location" => property.get_location_name,
|
||||
"actions" => actions
|
||||
}
|
||||
end
|
||||
properties = Property.can_display.filter_by_categories.sort_order
|
||||
url = "/#{I18n.locale}#{OrbitHelper.page.get_url}"
|
||||
data = index_data(properties, url)
|
||||
filterprops = data.dup
|
||||
filterprops.insert(0,{
|
||||
"title" => t("property_hire.all_properties"),
|
||||
"id" => "all&page_id=" + OrbitHelper.page.id.to_s
|
||||
})
|
||||
headers = [
|
||||
{
|
||||
"column" => t("property_hire.title")
|
||||
},
|
||||
{
|
||||
"column" => t("property_hire.image")
|
||||
"column" => ""
|
||||
},
|
||||
{
|
||||
"column" => t("property_hire.location")
|
||||
},
|
||||
{
|
||||
"column" => t("property_hire.actions")
|
||||
}
|
||||
]
|
||||
{
|
||||
"properties" => data,
|
||||
"filterprops" => filterprops,
|
||||
"headers" => headers,
|
||||
"extras" => {
|
||||
"first_property_id" => filterprops.first["id"],
|
||||
"today" => t("property_hire.today"),
|
||||
"day" => t("property_hire.day"),
|
||||
"week" => t("property_hire.week"),
|
||||
"month" => t("property_hire.month"),
|
||||
"language" => OrbitHelper.get_site_locale
|
||||
},
|
||||
"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)
|
||||
is_user_manager = check_if_user_is_manager?
|
||||
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")
|
||||
|
@ -42,7 +99,7 @@ class PropertyHiresController < ApplicationController
|
|||
{
|
||||
"properties" => data,
|
||||
"headers" => headers,
|
||||
"total_pages" => properties.total_pages
|
||||
"total_pages" => (properties.total_pages rescue 1)
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -85,7 +142,7 @@ class PropertyHiresController < ApplicationController
|
|||
"value" => property.purchase_date.strftime("%Y-%m-%d")
|
||||
}
|
||||
end
|
||||
if property.owners.empty?
|
||||
if property.owners.blank?
|
||||
owners = property.other_owner
|
||||
else
|
||||
owners = property.owner_profiles.collect{|mp| mp.name}.join(",")
|
||||
|
@ -121,16 +178,19 @@ class PropertyHiresController < ApplicationController
|
|||
}
|
||||
end
|
||||
actions = []
|
||||
if property.can_be_hired
|
||||
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" => OrbitHelper.url_to_show(property.to_param) + "?method=hire"
|
||||
"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" => OrbitHelper.url_to_show(property.to_param) + "?method=view_calendar"
|
||||
"link" => url_to_show + "?method=view_calendar"
|
||||
}
|
||||
end
|
||||
{
|
||||
|
@ -148,6 +208,9 @@ class PropertyHiresController < ApplicationController
|
|||
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?
|
||||
{
|
||||
|
@ -156,22 +219,97 @@ class PropertyHiresController < ApplicationController
|
|||
"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
|
||||
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])
|
||||
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
|
||||
redirect_to params[:url]
|
||||
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 "/" + I18n.locale.to_s + params[:url]
|
||||
redirect_to index_page
|
||||
else
|
||||
redirect_to "/" + I18n.locale.to_s + params[:url] + "/#{property.to_param}?method=hire"
|
||||
redirect_to hire_page
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -179,49 +317,354 @@ class PropertyHiresController < ApplicationController
|
|||
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 = PHire.new
|
||||
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
|
||||
is_user_manager = check_if_user_is_manager?
|
||||
{
|
||||
"hire" => hire,
|
||||
"property" => property,
|
||||
"page" => page.url,
|
||||
"current_user" => OrbitHelper.current_user
|
||||
"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,
|
||||
"language" => OrbitHelper.get_site_locale
|
||||
}
|
||||
end
|
||||
|
||||
def check_availability
|
||||
data = check_for_availability params[:stime], params[:etime], params[:property_id], params[:interval], params[:recurring_end_date]
|
||||
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 = []
|
||||
if params[:property_id] == "all"
|
||||
categories = Page.find(params["page_id"]).categories rescue []
|
||||
properties = Property.where(:category_id.in => categories)
|
||||
properties.each do |property|
|
||||
allevents += get_each_booking(property)
|
||||
end
|
||||
else
|
||||
property = Property.find(params[:property_id]) rescue nil
|
||||
if !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])
|
||||
re = PHire.recurring_event(sdt,edt,params[:property_id])
|
||||
allevents = events.inject(re, :<<)
|
||||
end
|
||||
allevents = get_each_booking(property)
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
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
|
||||
if DateTime.now >= (@property.start_date || DateTime.now - 1.day) && DateTime.now <= (@property.end_date || DateTime.now + 1.month)
|
||||
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 DateTime.now >= (@property.start_date || DateTime.now - 1.day) && DateTime.now <= (@property.end_date || DateTime.now + 1.month)
|
||||
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
|
||||
@is_user_manager = check_if_user_is_manager?
|
||||
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
|
||||
params.require(:p_hire).permit!
|
||||
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 += "<br>".html_safe
|
||||
end
|
||||
p_hire_params["note_for_hire"] = note_texts
|
||||
p_hire_params.delete("notes_selector")
|
||||
end
|
||||
return p_hire_params
|
||||
end
|
||||
|
||||
def get_each_booking(property)
|
||||
events =[]
|
||||
allevents = []
|
||||
@property = property
|
||||
|
||||
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,property.id.to_s,property.set_availability)
|
||||
re = PHire.recurring_event(sdt,edt,property.id.to_s,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)}
|
||||
is_user_manager = check_if_user_is_manager?
|
||||
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.to_date rescue nil
|
||||
@check_end_date = property.end_date.to_date rescue nil
|
||||
if check_setting
|
||||
if (@check_start_date > edt rescue false) || (@check_end_date < sdt rescue false)
|
||||
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
|
||||
return allevents
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,561 @@
|
|||
module Admin::PHireFieldHelper
|
||||
|
||||
include ActionView::Helpers::FormTagHelper
|
||||
include ActionView::Helpers::FormOptionsHelper
|
||||
include ActionView::Helpers::DateHelper
|
||||
include ActionView::Helpers::TagHelper
|
||||
include ActionView::Helpers::RenderingHelper
|
||||
include ActionView::Context
|
||||
include OrbitBasis::RenderAnywhere
|
||||
|
||||
include OrbitFormHelper
|
||||
|
||||
def block_helper(member,index,disable = false,attribute_type=nil,p_hire=nil, to_require=true, col=2, value=nil)
|
||||
unless self.disabled
|
||||
return "" if self.title.blank?
|
||||
@col = col
|
||||
@index = index
|
||||
@require = to_require
|
||||
@markup_options = markup_options.merge(:disabled=>disable, :required => to_require)
|
||||
@member = member
|
||||
@attribute_value = @member.get_value_from_field_id(id,p_hire)
|
||||
@attribute_type = attribute_type
|
||||
@new_attribute = @attribute_value.nil? || @attribute_value.new_record?
|
||||
@attribute_value = @attribute_value || p_hire.p_hire_field_values.build(p_hire_field_id: id)
|
||||
@prefiled_value = value || @attribute_value.value rescue nil
|
||||
return instance_eval("render_#{markup}") rescue ""
|
||||
end
|
||||
end
|
||||
|
||||
def lang_tab(str,lang)
|
||||
content_tag(:div,str,:class=>"tab-pane fade",:id=>(get_field_name_base+"tab_#{lang}"))
|
||||
end
|
||||
def render_hint_text
|
||||
place_holder= self.get_placeholder rescue ''
|
||||
return "" if place_holder.blank?
|
||||
control_group_wrapper do |key,value|
|
||||
if !@prefiled_value.nil?
|
||||
value = can_muti_lang_input? ? @prefiled_value[key] : @prefiled_value
|
||||
else
|
||||
value = nil
|
||||
end
|
||||
key = can_muti_lang_input? ? "#{key}" : I18n.locale
|
||||
name1 = ""
|
||||
text_area_tag(name1, place_holder,@markup_options.merge(:class=>'input-medium form-control',:readonly=>"",:rows=>"4"))
|
||||
end
|
||||
end
|
||||
def render_address
|
||||
control_group_wrapper do |key,value|
|
||||
value = (can_muti_lang_input? ? @prefiled_value[key] : @prefiled_value) rescue nil
|
||||
key_field = can_muti_lang_input? ? "[#{key}]" : ""
|
||||
place_holder= @panel_setting["placeholder"][key] rescue ''
|
||||
# result = text_area_tag(get_field_name_base + key_field, value,@markup_options.merge({:placeholder=>place_holder,:for=>key}))
|
||||
result = text_field_tag(get_field_name_base + key_field, value,@markup_options.merge({:placeholder=>place_holder,:for=>key}))
|
||||
|
||||
add_ext= @attribute_value.address_key[key] rescue {}
|
||||
|
||||
result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][county]",add_ext["county"],:class=>"county_#{key}", :id=>nil)
|
||||
result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][street_address]",add_ext["street_address"],:class=>"street_address_#{key}", :id=>nil)
|
||||
result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][city]",add_ext["city"],:class=>"city_#{key}", :id=>nil)
|
||||
result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][zip]",add_ext["zip"],:class=>"zip_#{key}", :id=>nil)
|
||||
result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][country]",add_ext["country"],:class=>"country_#{key}", :id=>nil)
|
||||
result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][indicator]",add_ext["indicator"],:class=>"indicator_#{key}", :id=>nil)
|
||||
end
|
||||
end
|
||||
|
||||
def render_checkbox
|
||||
@prefiled_value ||=[]
|
||||
control_group_wrapper do
|
||||
a = self.typeE[:option_list].collect do |key,value|
|
||||
label_tag("#{get_basic_field_name_org}_#{self.id}_#{key}",check_box_tag(get_field_name_base+"[#{key}]", true , (@prefiled_value.include?(key) ? true : false), { :id=>"#{get_basic_field_name_org}_#{self.id}_#{key}"})+value[I18n.locale.to_s],@markup_options.merge(:class=>"checkbox inline"))
|
||||
end.join.html_safe rescue ""
|
||||
end
|
||||
end
|
||||
|
||||
def render_date
|
||||
d = DateTime.now()
|
||||
|
||||
if date_is_range?
|
||||
# fill_from = @attribute_value.get_date(:from) rescue nil
|
||||
# fill_to = @attribute_value.get_date(:to) rescue nil
|
||||
control_group_wrapper do
|
||||
|
||||
case self.typeC['format']
|
||||
when 'format1'
|
||||
fill_from = (@prefiled_value && @prefiled_value["from"] ) ? @prefiled_value["from"] : d.strftime("%Y/%m/%d %H:%M")
|
||||
fill_to = (@prefiled_value && @prefiled_value["to"] ) ? @prefiled_value["to"] : d.strftime("%Y/%m/%d %H:%M")
|
||||
buf = datetime_picker(get_field_name_base+'[from]', fill_from, 'yyyy/MM/dd hh:mm', true)
|
||||
buf << ' ~ '
|
||||
buf << datetime_picker(get_field_name_base+'[to]', fill_to, 'yyyy/MM/dd hh:mm', true)
|
||||
when 'format2'
|
||||
fill_from = (@prefiled_value && @prefiled_value["from"] ) ? @prefiled_value["from"] : d.strftime("%Y/%m/%d")
|
||||
fill_to = (@prefiled_value && @prefiled_value["to"] ) ? @prefiled_value["to"] : d.strftime("%Y/%m/%d")
|
||||
buf = datetime_picker(get_field_name_base+'[from]', fill_from, 'yyyy/MM/dd')
|
||||
buf << ' ~ '
|
||||
buf << datetime_picker(get_field_name_base+'[to]', fill_to, 'yyyy/MM/dd')
|
||||
when 'format3'
|
||||
fill_from = (@prefiled_value && @prefiled_value["from"] ) ? @prefiled_value["from"] : d.strftime("%Y/%m")
|
||||
fill_to = (@prefiled_value && @prefiled_value["to"] ) ? @prefiled_value["to"] : d.strftime("%Y/%m/")
|
||||
buf = datetime_picker(get_field_name_base+'[from]', fill_from, 'yyyy/MM')
|
||||
buf << ' ~ '
|
||||
buf << datetime_picker(get_field_name_base+'[to]', fill_to, 'yyyy/MM')
|
||||
when 'format4'
|
||||
fill_from = (@prefiled_value && @prefiled_value["from"] ) ? @prefiled_value["from"] : d.strftime("%Y")
|
||||
fill_to = (@prefiled_value && @prefiled_value["to"] ) ? @prefiled_value["to"] : d.strftime("%Y")
|
||||
buf = datetime_picker(get_field_name_base+'[from]', fill_from, 'yyyy')
|
||||
buf << ' ~ '
|
||||
buf << datetime_picker(get_field_name_base+'[to]', fill_to, 'yyyy')
|
||||
end
|
||||
|
||||
# buf = date_select(get_field_name_base+'[from]',nil,@markup_options.merge(:default=>fill_from),:class=>"input-small")
|
||||
# buf << ' ~ '
|
||||
# buf << date_select(get_field_name_base+'[to]',nil,@markup_options.merge(:default=>fill_to),:class=>"input-small")
|
||||
buf
|
||||
end
|
||||
else
|
||||
# @prefiled_value = @attribute_value.get_date
|
||||
# @prefiled_value = @attribute_value.get_date
|
||||
|
||||
case self.typeC['format']
|
||||
when 'format1'
|
||||
tmp = datetime_picker(get_field_name_base, (@prefiled_value ? @prefiled_value : d.strftime("%Y/%m/%d %H:%M")), 'yyyy/MM/dd hh:mm', true)
|
||||
when 'format2'
|
||||
tmp = datetime_picker(get_field_name_base, (@prefiled_value ? @prefiled_value : d.strftime("%Y/%m/%d")), 'yyyy/MM/dd')
|
||||
when 'format3'
|
||||
tmp = datetime_picker(get_field_name_base, (@prefiled_value ? @prefiled_value : d.strftime("%Y/%m")), 'yyyy/MM')
|
||||
when 'format4'
|
||||
tmp = datetime_picker(get_field_name_base, (@prefiled_value ? @prefiled_value : d.strftime("%Y")), 'yyyy')
|
||||
end
|
||||
|
||||
control_group_wrapper{tmp}
|
||||
# control_group_wrapper{date_select(get_field_name_base,nil,@markup_options.merge(:default=>@prefiled_value),:class=>"input-small")}
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def property_datetime_picker(object_name, value, format, time=false)
|
||||
content_tag :div, :class => "input-append datetimepick", "data-date-format"=>format, "data-picktime"=>"#{time}" do
|
||||
concat text_field_tag(object_name, value, :placeholder=>format)
|
||||
concat (content_tag :span, :class => 'add-on clearDate' do
|
||||
content_tag :i, nil, :class => 'icons-cross-3'
|
||||
end)
|
||||
concat (content_tag :span, :class => 'add-on iconbtn' do
|
||||
content_tag :i, nil, 'data-time-icon' => 'icons-clock', 'data-date-icon' => 'icons-calendar', :class=>"icons-calendar"
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
def render_date_durnation #Need re-write low priority
|
||||
|
||||
end
|
||||
|
||||
def render_radio_button
|
||||
@prefiled_value ||=[]
|
||||
control_group_wrapper do
|
||||
self.typeE[:option_list].collect do |key,value|
|
||||
label_tag("#{get_basic_field_name_org}_#{self.id}_#{key}",radio_button_tag(get_field_name_base, key , (@prefiled_value.include?(key) ? true : false), {:required=>@require,:id=>"#{get_basic_field_name_org}_#{self.id}_#{key}"})+value[I18n.locale.to_s],@markup_options.merge(:class=>"radio inline"))
|
||||
end.join.html_safe
|
||||
end
|
||||
end
|
||||
def render_property_preferred_session
|
||||
@prefiled_value ||=[]
|
||||
@prefiled_value = Array(@prefiled_value)
|
||||
control_group_wrapper do
|
||||
@member.summary_chioices.map.with_index do |value,key|
|
||||
key = key.to_s
|
||||
label_tag("#{get_basic_field_name_org}_#{self.id}_#{key}",radio_button_tag(get_field_name_base, key , ((@prefiled_value.include?(key) || @prefiled_value.include?(key.to_i)) ? true : false), {:required=>@require,:id=>"#{get_basic_field_name_org}_#{self.id}_#{key}"})+value,@markup_options.merge(:class=>"radio inline"))
|
||||
end.join.html_safe
|
||||
end if @member.enable_summary_choice
|
||||
end
|
||||
def render_select
|
||||
prompt = @panel_setting["initial"][I18n.locale.to_s] rescue nil
|
||||
@markup_options.merge!(:prompt => prompt) unless prompt.nil?
|
||||
control_group_wrapper{select_tag( get_field_name_base,options_for_select(self.typeB["option_list"].collect{|p| [p[1][I18n.locale.to_s],p[0]]},@prefiled_value),@markup_options)} rescue ""
|
||||
end
|
||||
|
||||
def render_text_area
|
||||
control_group_wrapper do |key,value|
|
||||
if !@prefiled_value.nil?
|
||||
value = can_muti_lang_input? ? @prefiled_value[key] : @prefiled_value
|
||||
else
|
||||
value = nil
|
||||
end
|
||||
key = can_muti_lang_input? ? "#{key}" : I18n.locale
|
||||
place_holder= typeD["placeholder"][key] rescue ''
|
||||
name1 = can_muti_lang_input? ? (get_field_name_base + "[#{key}]") : get_field_name_base
|
||||
text_area_tag(name1, value,@markup_options.merge(:placeholder=>place_holder,:class=>'ckeditor input-medium form-control'))
|
||||
end
|
||||
end
|
||||
|
||||
def render_text_field
|
||||
a = control_group_wrapper do |key,value|
|
||||
add_more_blank = can_add_more ? "[]" : ""
|
||||
key_field = can_muti_lang_input? ? "#{key}" : I18n.locale
|
||||
place_holder= typeA["placeholder"][key_field] rescue ''
|
||||
name1 = can_muti_lang_input? ? ([get_field_name_base,add_more_blank,"[#{key_field}]"].join) : ([get_field_name_base,add_more_blank].join)
|
||||
text_field_tag(name1, value,@markup_options.merge(:placeholder=>place_holder,:class=>'input-medium form-control'))
|
||||
end
|
||||
end
|
||||
|
||||
def date_is_range?
|
||||
is_range = "false"
|
||||
data = get_data
|
||||
if !data.nil?
|
||||
is_range = data['is_range'] if data.has_key? "is_range"
|
||||
end
|
||||
is_range == "true"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def valid_locales
|
||||
site = Site.first
|
||||
[I18n.locale]+(site.valid_locales-[I18n.locale])
|
||||
end
|
||||
|
||||
def lang_panel_tabbable_wrapper(add_more_params,&block)
|
||||
add_more_counter = ''
|
||||
|
||||
if self.markup=='text_area' #or self.markup=='address'
|
||||
tmp1 = valid_locales.collect do |key|
|
||||
if !@prefiled_value.nil?
|
||||
value = @prefiled_value[key] || @prefiled_value[key.to_s] rescue nil
|
||||
else
|
||||
value = nil
|
||||
end
|
||||
# div_class_ary = ["tab-pane" ,"fade","#{get_pairing_tab_class({})}_#{key}"]
|
||||
div_class_ary = ["tab-pane" ,"fade"]
|
||||
if @show_set_field && @markup=='text_area'
|
||||
div_id = "ckeditor_#{get_pairing_tab_class({})}_#{key}"
|
||||
else
|
||||
div_id = "#{get_pairing_tab_class({})}_#{key}"
|
||||
end
|
||||
if can_add_more
|
||||
add_more_value = add_more_params[0][:value]
|
||||
add_more_counter = add_more_params[0][:counter]
|
||||
value = add_more_value[key] rescue nil
|
||||
div_class_ary << "add_more_item_#{add_more_counter}"
|
||||
end
|
||||
|
||||
div_class = div_class_ary.join(" ")
|
||||
div_class << (key == I18n.locale ? " active in" : '')
|
||||
content_tag(:div,yield(key,value), :id=>div_id,:class=>div_class)
|
||||
end# of VALID_LOCALES.collect for tabed input
|
||||
tmp2 = content_tag(:div,:class => 'btn-group', :data=>{:toggle=>"buttons-radio"}) do
|
||||
buff2 = valid_locales.each.collect do |key|
|
||||
# link_entry = self.add_more ? "#{add_more_tab(:tab_btn,loop_counter,key)}" : "#tab"+id.to_s+"_#{key}"
|
||||
if @show_set_field && @markup=='text_area'
|
||||
link_entry_ary = ["#ckeditor_#{get_pairing_tab_class({})}","_#{key}"]
|
||||
else
|
||||
link_entry_ary = ["##{get_pairing_tab_class({})}","_#{key}"]
|
||||
end
|
||||
link_entry_ary << ".add_more_item_#{add_more_counter}" if can_add_more
|
||||
link_entry = link_entry_ary.join
|
||||
link_to(I18n.t(key),link_entry,:data=>{:toggle=>"tab"},:class=>"btn #{(key == I18n.locale ? "active" : nil)}",:for=>key)
|
||||
end # of VALID_LOCALES.collect for tabs
|
||||
|
||||
buff2 << link_to((content_tag :i,'',:class=>'icon-edit'),"##{get_pairing_tab_class({})}_m_window", :role=>"button",:class=>'btn',:data=>{:toggle=>"modal"}) if self.markup == 'address'
|
||||
buff2 << link_to((content_tag :i,'',:class=>'icon-trash'),"#",:class=>"btn remove-input") if self.add_more
|
||||
buff2.join.html_safe
|
||||
end # of content ul
|
||||
tmp = content_tag :div,:class=> "tab-content textarea-lang" do
|
||||
tmp2 << tmp1.join('').html_safe
|
||||
end
|
||||
else
|
||||
|
||||
# tmp = content_tag :div,:class=> (add_more || self.markup=='address') ? "input-append" : "tab-content" do
|
||||
tmp1 =
|
||||
content_tag :div,:class=> "tab-content" do
|
||||
|
||||
buff = valid_locales.collect do |key|
|
||||
value = @prefiled_value[key] || @prefiled_value[key.to_s] rescue nil
|
||||
# div_class_ary = ["tab-pane" ,"fade","#{get_pairing_tab_class({})}_#{key}"]
|
||||
div_class_ary = ["tab-pane" ,"fade"]
|
||||
|
||||
div_id = "#{get_pairing_tab_class({})}_#{key}"
|
||||
|
||||
|
||||
if can_add_more
|
||||
add_more_value = add_more_params[0][:value]
|
||||
add_more_counter = add_more_params[0][:counter]
|
||||
value = add_more_value[key] rescue nil
|
||||
div_class_ary << "add_more_item_#{add_more_counter}"
|
||||
end
|
||||
|
||||
div_class = div_class_ary.join(" ")
|
||||
div_class << (key == I18n.locale ? " active in" : '')
|
||||
content_tag(:div,yield(key,value), :id=>div_id,:class=>div_class)
|
||||
end# of VALID_LOCALES.collect for tabed input
|
||||
|
||||
buff.join('').html_safe
|
||||
|
||||
end
|
||||
|
||||
tmp2 = content_tag(:div,:class => 'btn-group', :data=>{:toggle=>"buttons-radio"}) do
|
||||
buff2 = valid_locales.each.collect do |key|
|
||||
# link_entry = self.add_more ? "#{add_more_tab(:tab_btn,loop_counter,key)}" : "#tab"+id.to_s+"_#{key}"
|
||||
link_entry_ary = ["##{get_pairing_tab_class({})}","_#{key}"]
|
||||
link_entry_ary << ".add_more_item_#{add_more_counter}" if can_add_more
|
||||
link_entry = link_entry_ary.join
|
||||
link_to(I18n.t(key),link_entry,:data=>{:toggle=>"tab"},:class=>"btn #{(key == I18n.locale ? "active" : nil)}",:for=>key)
|
||||
end # of VALID_LOCALES.collect for tabs
|
||||
|
||||
buff2 << link_to((content_tag :i,'',:class=>'icon-edit'),"#address-field", :role=>"button",:class=>'btn',:data=>{:toggle=>"modal"}) if self.markup == 'address'
|
||||
buff2 << link_to((content_tag :i,'',:class=>'icon-trash'),"#",:class=>"btn remove-input") if self.add_more
|
||||
buff2.join.html_safe
|
||||
end # of content ul
|
||||
|
||||
|
||||
|
||||
tmp = content_tag :div,:class=> "input-append" do
|
||||
tmp1 << tmp2
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def controls_wrapper(*add_more_params,&block)
|
||||
result = Array.new
|
||||
add_more_counter = ""
|
||||
|
||||
if can_add_more
|
||||
add_more_counter = add_more_params[0][:counter]
|
||||
add_more_value = add_more_params[0][:value]
|
||||
end
|
||||
|
||||
|
||||
|
||||
if can_muti_lang_input?
|
||||
result << lang_panel_tabbable_wrapper(add_more_params,&block)
|
||||
result << gen_modal_dialog if self.markup == "address"
|
||||
# result << add_more_unt if can_add_more
|
||||
else #cross lang field
|
||||
case can_add_more
|
||||
when true
|
||||
value = add_more_params[0][:value]
|
||||
result << content_tag(:div,:class=>"input-append"){yield(nil,value) + link_to((content_tag :i,'',:class=>'icon-trash'),"#",:class=>"btn remove-input") }
|
||||
# result << add_more_unt
|
||||
else
|
||||
value = @prefiled_value
|
||||
result << yield(nil,value)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
if self.markup == "address"
|
||||
result
|
||||
else
|
||||
result[0]
|
||||
end
|
||||
|
||||
end # of def controls_wrapper(&block)
|
||||
|
||||
def control_group_wrapper(&block)
|
||||
div_class = can_muti_lang_input? ? "col-sm-#{12-@col} controls" : "col-sm-#{12-@col} controls"
|
||||
# div_class = can_muti_lang_input? ? "control-group language-swich" : "control-group"
|
||||
result = ""
|
||||
|
||||
case self.markup
|
||||
|
||||
when "text_field"
|
||||
|
||||
if can_add_more
|
||||
|
||||
multipleInputs =
|
||||
content_tag(:div,:class=>"add-target") do
|
||||
@attribute_value.add_more_counter.times.collect do |t|
|
||||
controls_wrapper(:value=>(@prefiled_value[t] rescue nil),:counter=>t,&block)
|
||||
end.join('').html_safe # of add_more fields
|
||||
end
|
||||
|
||||
|
||||
temp = content_tag(:div, multipleInputs + add_more_unt, :class=>'add-input')
|
||||
|
||||
result = form_label + content_tag(:div,temp,:class=>div_class)
|
||||
|
||||
# result = label + multipleInputs + add_more_unt
|
||||
# result = label + 一堆的輸入框(要用 multipleInput editMore 包起來) + add_more btn + hidden_fields
|
||||
else
|
||||
result = form_label + content_tag(:div,controls_wrapper(&block),:class=>div_class)
|
||||
end
|
||||
|
||||
when "address"
|
||||
|
||||
# address = content_tag :div,:class=>"multipleInput editMore" do
|
||||
address = content_tag :div,:class=>"col-sm-#{12-@col}" do
|
||||
form_label + content_tag(:div, controls_wrapper(&block), :class=>'add-input')
|
||||
end # of div multipleInput editMore
|
||||
|
||||
result = address
|
||||
|
||||
else
|
||||
result = form_label + content_tag(:div,controls_wrapper(&block),:class=>div_class)
|
||||
end
|
||||
result = result + end_block
|
||||
result.html_safe
|
||||
|
||||
end
|
||||
|
||||
|
||||
def add_more_unt
|
||||
temp_field_name = get_basic_field_name_base + '[temp]'
|
||||
add_more = content_tag :p,:class=> 'add-btn' do
|
||||
content = link_to (content_tag :i,I18n.t(:add),:class=>"icon-plus"),"#","data-roles"=>"role_a",:class=>"trigger #{can_muti_lang_input? ? 'textLengInput' : 'textInput' } btn btn-small btn-primary"
|
||||
content << hidden_field_tag("#{temp_field_name}[count]",@attribute_value.add_more_counter ,:class=>"list_count", :id=>nil)
|
||||
content << hidden_field_tag("#{temp_field_name}[count]",get_basic_field_name_base,:class=>"field_name", :id=>nil)
|
||||
content
|
||||
end # of div
|
||||
# add_more = content_tag :div,:class=> 'controls' do
|
||||
# content_tag :span,:class=> 'help-block' do
|
||||
# content = link_to (content_tag :i,I18n.t(:add),:class=>"icon-plus-sign"),"#",:class=>'addinput'
|
||||
# content << hidden_field_tag("#{temp_field_name}[count]",@attribute_value.add_more_counter ,:class=>"list_count")
|
||||
# content << hidden_field_tag("#{temp_field_name}[count]",get_basic_field_name_base,:class=>"field_name")
|
||||
# content
|
||||
# end # of span
|
||||
# end # of div
|
||||
end
|
||||
|
||||
def end_block
|
||||
if @new_attribute
|
||||
hidden_field_tag(get_basic_field_name_base+"[#{get_basic_field_name}_id]",id,:for=>"field_#{@index}", :id=>nil)
|
||||
else
|
||||
hidden_field_tag(get_basic_field_name_base+"[id]",@attribute_value.id,:for=>"field_#{@index}", :id=>nil)
|
||||
end
|
||||
end
|
||||
|
||||
def add_more_tab(mode,counter,key)
|
||||
case mode
|
||||
when :input_field
|
||||
get_pairing_tab_class(:suffix=>['','tab'+counter.to_s,key].join('-'))
|
||||
when :tab_btn
|
||||
".#{get_pairing_tab_class(:suffix=>['','tab'+counter.to_s,key].join('-'))}"
|
||||
end
|
||||
end
|
||||
|
||||
def get_pairing_tab_class(opts)
|
||||
prefix = opts[:prefix]
|
||||
suffix = opts[:suffix]
|
||||
str = get_basic_field_name_base.gsub("[","_").gsub("]",'')
|
||||
str = prefix.nil? ? str : prefix+ str
|
||||
suffix.nil? ? str : str + suffix
|
||||
end
|
||||
|
||||
def get_basic_field_name_org
|
||||
"p_hire[p_hire_field_values_attributes]"
|
||||
end
|
||||
|
||||
def get_basic_field_name
|
||||
"p_hire_field"
|
||||
end
|
||||
|
||||
def get_basic_field_name_base
|
||||
"#{get_basic_field_name_org}[#{@index}]"
|
||||
end
|
||||
|
||||
def get_field_name_base
|
||||
get_basic_field_name_base + "[value]"
|
||||
end
|
||||
|
||||
def form_label
|
||||
if self.markup == "text_area"
|
||||
plc = typeD["placeholder"][I18n.locale].to_s.blank? ? nil : "(#{typeD["placeholder"][I18n.locale]})"
|
||||
label_tag(key, '' , :class=>"col-sm-#{@col} control-label muted") do
|
||||
concat (!@require.blank? ? '*'+title : title)
|
||||
if plc
|
||||
concat tag(:br)
|
||||
concat plc
|
||||
end
|
||||
end
|
||||
else
|
||||
label_tag(key,(!@require.blank? ? '*'+title : title),:class=>"col-sm-#{@col} control-label muted")
|
||||
end
|
||||
end
|
||||
|
||||
def can_muti_lang_input?
|
||||
if self.markup == "address"
|
||||
return true
|
||||
else
|
||||
$property_list[:markups][markup]["muti_lang_input_supprt"] and !(get_data["cross_lang"] == "true")
|
||||
end
|
||||
end
|
||||
|
||||
def can_add_more
|
||||
if self.markup == "address"
|
||||
return false
|
||||
else
|
||||
add_more
|
||||
end
|
||||
end
|
||||
|
||||
def gen_modal_dialog
|
||||
render_anywhere("shared/attribute_field/address_modal_dialog",{
|
||||
:field_name=>title,
|
||||
:html_id=>"address-field",
|
||||
:btn_class => "#{get_pairing_tab_class({})}",
|
||||
:field_name_basic => get_basic_field_name_base
|
||||
}
|
||||
)
|
||||
end
|
||||
def show_set_field(field_sets,key_field,key_index,field,markup='text_field')
|
||||
@show_set_field = true
|
||||
def self.can_muti_lang_input?
|
||||
true
|
||||
end
|
||||
def self.can_add_more
|
||||
false
|
||||
end
|
||||
@markup = markup
|
||||
def self.markup
|
||||
@markup
|
||||
end
|
||||
def self.add_more
|
||||
false
|
||||
end
|
||||
@new_attribute = false
|
||||
@key_index = key_index
|
||||
def self.key
|
||||
@key_index
|
||||
end
|
||||
def self.form_label
|
||||
''
|
||||
end
|
||||
def self.end_block
|
||||
unless @attribute_value.new_record?
|
||||
hidden_field_tag("property[#{@key_field}][#{@key_index}]"+"[id]",
|
||||
@attribute_value.id,:for=>"field_#{@key_index}", :id=>nil)
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
@key_field = key_field
|
||||
@field = field
|
||||
def self.get_basic_field_name_base
|
||||
"property[#{@key_field}][#{@key_index}][#{@field}]"
|
||||
end
|
||||
def self.get_field_name_base
|
||||
"property[#{@key_field}][#{@key_index}][#{@field}]"
|
||||
end
|
||||
@attribute_value = field_sets
|
||||
@prefiled_value = field_sets[field]
|
||||
a = control_group_wrapper do |key,value|
|
||||
add_more_blank = ""
|
||||
if markup=='text_field'
|
||||
if key_field == 'property_email_sets'
|
||||
inside = text_field_tag([get_field_name_base,"[#{key}]"].join,value,:class=>'input-medium form-control')
|
||||
else
|
||||
inside = text_field_tag([get_field_name_base,"[#{key}]"].join,value)
|
||||
end
|
||||
else
|
||||
inside = cktext_area("property[#{@key_field}][#{@key_index}][#{@field}]","#{key}",value:value)
|
||||
end
|
||||
inside
|
||||
end
|
||||
@key_field = nil
|
||||
@key_index = nil
|
||||
@field = nil
|
||||
@show_set_field = nil
|
||||
return a.html_safe
|
||||
end
|
||||
end
|
|
@ -0,0 +1,113 @@
|
|||
module Admin::PHireFieldValuesHelper
|
||||
def show_property_type_panel(attribute_field,type)
|
||||
markup = attribute_field.markup
|
||||
$property_list[:markups][markup]["panel"] == type ? type : [type,'hide'].join(" ")
|
||||
end
|
||||
def show_west_calender(from_to=nil)
|
||||
case from_to
|
||||
when :to
|
||||
date = get_date(:to)
|
||||
when :from
|
||||
date = get_date(:from)
|
||||
when nil
|
||||
date = get_date
|
||||
end
|
||||
|
||||
# case self.member_profile_field["typeC"]["format"]
|
||||
# when 'format1' # Y/M/D h:m
|
||||
# date.strftime("%Y/%m/%d %H:%M")
|
||||
# when 'format2' # Y/M/D
|
||||
# date.strftime("%Y/%m/%d")
|
||||
# when 'format3' # Y/M
|
||||
# date.strftime("%Y/%m")
|
||||
# when 'format4' # Y
|
||||
# date.strftime("%Y")
|
||||
# end # of case west cal format
|
||||
end
|
||||
|
||||
def show_minguo_calendar(from_to=nil)
|
||||
get_minguo
|
||||
|
||||
case from_to
|
||||
when :to
|
||||
date = get_date(:to)
|
||||
when :from
|
||||
date = get_date(:from)
|
||||
when nil
|
||||
date = get_date
|
||||
end
|
||||
|
||||
@date = date.split('/')
|
||||
date_year = @date[0].to_i
|
||||
|
||||
year_str = ""
|
||||
unless date_year == 1912
|
||||
m_year = (date_year - 1912).abs.to_s + I18n.t("date.minguo_calendar.year")
|
||||
year_str = minguo_format_year(m_year)
|
||||
end
|
||||
get_minguo_year(from_to) + minguo_m_y_d_time(from_to)
|
||||
end
|
||||
|
||||
def get_minguo_year(from_to=nil)
|
||||
case from_to
|
||||
when :to
|
||||
date = get_date(:to)
|
||||
when :from
|
||||
date = get_date(:from)
|
||||
when nil
|
||||
date = get_date
|
||||
end
|
||||
|
||||
@date = date.split('/')
|
||||
date_year = @date[0].to_i
|
||||
|
||||
m_year = (date_year - 1911).abs
|
||||
year_end = I18n.t("date.minguo_calendar.year")
|
||||
case
|
||||
when date_year <1912
|
||||
I18n.t("date.minguo_calendar.before") + (m_year+1).to_s + year_end
|
||||
when date_year ==1912
|
||||
I18n.t("date.minguo_calendar.first_year")
|
||||
when date_year >1912
|
||||
I18n.t("date.minguo_calendar.after")+ (m_year).to_s + year_end
|
||||
end # of case tw_calendar year
|
||||
end
|
||||
|
||||
def minguo_m_y_d_time(from_to=nil)
|
||||
case from_to
|
||||
when :to
|
||||
date = get_date(:to)
|
||||
when :from
|
||||
date = get_date(:from)
|
||||
when nil
|
||||
date = get_date
|
||||
end
|
||||
@date = date.split('/')
|
||||
|
||||
case self.p_hire_field["typeC"]["format"]
|
||||
when 'format1' # Y/M/D h:m
|
||||
"/#{@date[1]}/#{@date[2]}"
|
||||
when 'format2' # Y/M/D
|
||||
"/#{@date[1]}/#{@date[2]}"
|
||||
when 'format3' # Y/M
|
||||
|
||||
"/#{@date[1]}#{I18n.t("date.minguo_calendar.month")}"\
|
||||
when 'format4' # Y
|
||||
''
|
||||
end # of case
|
||||
end
|
||||
|
||||
def get_date_by_format(from_to = nil)
|
||||
case I18n.locale
|
||||
when :zh_tw
|
||||
case
|
||||
when self.p_hire_field["typeC"]["calendar"] == "west_calendar"
|
||||
show_west_calender(from_to)
|
||||
when self.p_hire_field["typeC"]["calendar"] == "tw_calendar"
|
||||
show_minguo_calendar(from_to)
|
||||
end #case self.p_hire_field["typeC"]["calendar"]
|
||||
when :en
|
||||
show_west_calender(from_to)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +1,182 @@
|
|||
module Admin::PropertyHiresHelper
|
||||
|
||||
def check_for_availability(stime, etime, pid, interval=nil, recurring_end_date=nil)
|
||||
data = File.open(File.join(File.dirname(__FILE__), '../../../config', 'list.yml')).read
|
||||
$property_list = YAML::load(ERB.new(data).result(binding)).symbolize_keys
|
||||
include OrbitBackendHelper
|
||||
def check_for_availability(stime, etime, pid, interval=nil, recurring_end_date=nil, time_setting_id=nil)
|
||||
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, interval, recurring_end_date)
|
||||
data = {"success" => true}
|
||||
else
|
||||
data = {"success" => false, "msg" => "Property is already hired during this time."}
|
||||
values_not_ok = {"success" => false, "msg" => I18n.t("property_hire.values_are_not_ok",:default=>"Values are not ok.")}
|
||||
return values_not_ok if property.nil? || stime.blank? || etime.blank?
|
||||
timezone = (params[:timezone] rescue nil)
|
||||
timezone = timezone ? timezone : Time.zone.to_s
|
||||
stime = DateTime.parse(stime + timezone) rescue nil
|
||||
etime = DateTime.parse(etime + timezone) rescue nil
|
||||
return values_not_ok if stime.nil? || etime.nil?
|
||||
if !recurring_end_date.blank?
|
||||
recurring_end_date = DateTime.parse(recurring_end_date + timezone) rescue nil
|
||||
begin
|
||||
interval_time = 1.send(interval)
|
||||
tmp_date = recurring_end_date - interval_time
|
||||
if tmp_date < etime
|
||||
I18n.with_locale(params[:locale]) do
|
||||
interval_str= I18n.t("property_hire.1_#{interval}","1 #{interval}")
|
||||
default_msg = "Recurring end date must exceed hire end time than #{interval_str}!"
|
||||
msg = I18n.t("property_hire.recurring_end_date_must_exceed_time",{:time=>interval_str,:default=>default_msg})
|
||||
return {"success" => false, "msg" => msg}
|
||||
end
|
||||
end
|
||||
rescue
|
||||
end
|
||||
else
|
||||
data = {"success" => false, "msg" => "Property is unavailable during this time."}
|
||||
recurring_end_date = nil
|
||||
end
|
||||
data = {}
|
||||
if stime > etime
|
||||
I18n.with_locale(params[:locale]) do
|
||||
return {"success" => false, "msg" => I18n.t("property_hire.starting_time_cannot_be_greater_than_ending_time")}
|
||||
end
|
||||
end
|
||||
mp = OrbitHelper.current_user.member_profile rescue nil
|
||||
available_flag = property.is_available_for_hire?(stime, etime, interval, recurring_end_date, time_setting_id, mp)
|
||||
if available_flag == 1
|
||||
if property.not_yet_hired?(stime, etime, interval, recurring_end_date,params[:phire_id], time_setting_id)
|
||||
data = {"success" => true}
|
||||
else
|
||||
I18n.with_locale(params[:locale]) do
|
||||
data = {"success" => false, "msg" => I18n.t("property_hire.property_is_already_hired_during_this_time")}
|
||||
end
|
||||
end
|
||||
else
|
||||
I18n.with_locale(params[:locale]) do
|
||||
msg = I18n.t("property_hire.property_is_unavailable_during_this_time")
|
||||
if available_flag == 2 ## need hire after
|
||||
if recurring_end_date.present?
|
||||
stime = [stime,recurring_end_date].max
|
||||
end
|
||||
can_hire_date = stime - (property.can_hire_before_months).month
|
||||
msg += ("<br>" + I18n.t("property_hire.please_hire_after_date",{:date=>"{#{can_hire_date.new_offset(0).to_json.gsub('"','')}}"}))
|
||||
elsif available_flag == 3 ## need hire before
|
||||
default_msg = "This property must be reserved #{property.need_hire_before} #{property.need_hire_before_unit}s in advance."
|
||||
msg += I18n.t("property_hire.unavailable_hint3",{:month=>property.need_hire_before,:unit=>I18n.t("property_hire._#{property.need_hire_before_unit}",:default=>property.need_hire_before_unit),:default=>default_msg})
|
||||
elsif available_flag == 0
|
||||
msg += ("<br>" + property.render_unavailable_message)
|
||||
end
|
||||
data = {"success" => false, "msg" => msg}
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
def render_custom_text_field(f,field_name,type)
|
||||
text = "<div>
|
||||
<div class=\"input-append\">
|
||||
<div class=\"tab-content\">"
|
||||
@site_in_use_locales.each_with_index do |locale,i|
|
||||
text += "<div class=\"tab-pane fade #{'active in' if i == 0}\" id=\"property_#{field_name}_#{type}_#{locale}\">
|
||||
#{f.text_field_tag("#{f.object_name}[#{field_name}][#{type}][#{locale}]", f.object.custom_text(field_name,type,locale))}
|
||||
</div>"
|
||||
end
|
||||
text += "<div class=\"btn-group\" data-toggle=\"buttons-radio\">"
|
||||
@site_in_use_locales.each_with_index do |locale,i|
|
||||
text += "<a class=\"btn #{'active' if i == 0}\" data-toggle=\"tab\" href=\"#property_#{field_name}_#{type}_#{locale}\" aria-expanded=\"true\">#{t(locale)}</a>"
|
||||
end
|
||||
text += "</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>"
|
||||
text.html_safe
|
||||
end
|
||||
def check_if_user_is_manager?
|
||||
ma = ModuleApp.find_by_key("property_hire")
|
||||
if OrbitHelper.current_user.nil?
|
||||
is_user_manager = false
|
||||
else
|
||||
is_user_manager = (OrbitHelper.current_user.is_admin? || OrbitHelper.current_user.is_manager?(ma) || OrbitHelper.current_user.is_sub_manager?(ma))
|
||||
end
|
||||
return is_user_manager
|
||||
end
|
||||
module HireMethod
|
||||
extend ActionView::Helpers::UrlHelper
|
||||
extend ActionView::Helpers::TagHelper
|
||||
extend ActionView::Context
|
||||
extend ActionView::Helpers::FormTagHelper
|
||||
def self.set_input_name(input_name)
|
||||
@input_name = input_name
|
||||
end
|
||||
def self.get_input_name
|
||||
@input_name
|
||||
end
|
||||
def self.create_lang_panel(field)
|
||||
tmp2 = content_tag(:div,:class => 'btn-group', :data=>{:toggle=>"buttons-radio"}) do
|
||||
I18n.available_locales.collect do |key|
|
||||
link_entry_ary = ["##{field}","_#{key}"]
|
||||
link_entry = link_entry_ary.join
|
||||
link_to(I18n.t(key),link_entry,:data=>{:toggle=>"tab"},:class=>"btn #{(key == I18n.locale ? "active" : nil)}",:for=>key)
|
||||
end.join.html_safe
|
||||
end
|
||||
end
|
||||
def self.multiple_lang_tag(index1,type_of_tag,field,value=nil,custom_options={},combine_element='',exteral_options={},panel_in_first=false)
|
||||
content_tag(:div,{:class => "tab-panel"}.merge(exteral_options)) do
|
||||
all_field = (get_input_name + "[#{index1}][#{field}][parant]").gsub(/\[/,'_').gsub(/\]/,'')
|
||||
tmp = I18n.available_locales.collect do |locale|
|
||||
active_flag = ((locale == I18n.locale) ? ' active' : '')
|
||||
content_tag(:div,:class => "tab-content#{active_flag}",:id=>"#{all_field}_#{locale}") do
|
||||
value_locale = ((value[locale] || value[locale.to_s]) rescue nil)
|
||||
self.__send__("#{type_of_tag}_tag","#{get_input_name}[#{index1}][#{field}][#{locale}]",value_locale,custom_options)
|
||||
end
|
||||
end.join
|
||||
if panel_in_first
|
||||
tmp = create_lang_panel(all_field).html_safe + tmp.html_safe + combine_element
|
||||
else
|
||||
tmp = tmp.html_safe + create_lang_panel(all_field).html_safe + combine_element
|
||||
end
|
||||
tmp
|
||||
end
|
||||
end
|
||||
def self.show_set_field(id,field_sets,key_field,key_index,field,markup='text_field',with_id=true)
|
||||
end_block = with_id ? hidden_field_tag("property[#{key_field}][#{key_index}]"+"[id]",id) : ''
|
||||
custom_options = markup == 'text_area' ? {:class => 'ckeditor'} : {}
|
||||
a = multiple_lang_tag(key_field,markup,"#{key_index}][#{field}",field_sets,custom_options,end_block,{},markup=='text_area')
|
||||
a.html_safe
|
||||
end
|
||||
def self.send_mail(field_name,email,property_id,send_date=nil,hire_id=nil,user_id=nil)
|
||||
return if email.blank?
|
||||
property = Property.where(id: property_id).first
|
||||
if !property.nil?
|
||||
email_set = property.hire_email_sets.select{|v| v.field_name == field_name}
|
||||
title = property.title_translations.collect{|k,v| v}.select{|v| v.present?}.uniq.join('/')
|
||||
note = property.note_translations.collect{|k,v| v}.select{|v| v.present?}.uniq.join('/')
|
||||
content = "title:#{title}<br>note:#{note}"
|
||||
mail_subject = I18n.t("property_hire.email_#{field_name}_success")
|
||||
email_set_content = nil
|
||||
enable = false
|
||||
if email_set.length==0
|
||||
enable = true
|
||||
elsif !(email_set[0].disabled)
|
||||
enable = true
|
||||
mail_subject = email_set[0].title[I18n.locale]
|
||||
email_set_content = email_set[0].content.to_yaml
|
||||
end
|
||||
if field_name == "p_hire" && (property.set_availability rescue false)
|
||||
hire = PHire.find(hire_id) rescue nil
|
||||
if hire
|
||||
mail_subject += " (#{I18n.t("property_hire.hire_time")}: #{hire.date.to_s.gsub("-","/")} #{hire.time})"
|
||||
end
|
||||
end
|
||||
if enable
|
||||
mail = Email.create(mail_to: Array(email),
|
||||
module_app_key:"property_hire",
|
||||
template:"email/#{field_name}_email.html.erb",
|
||||
mail_sentdate: send_date || Time.current,
|
||||
mail_subject: mail_subject,
|
||||
template_data:{'property_id'=>property_id,'email_set_content'=>email_set_content,'content'=>content,'locale'=>I18n.locale.to_s,'hire_id'=>hire_id,'user_id'=>user_id})
|
||||
else
|
||||
return false
|
||||
end
|
||||
begin
|
||||
mail.deliver
|
||||
rescue => e
|
||||
puts ["email can't deliver",e]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
class HireEmailSet
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
field :field_name, type: String
|
||||
field :title
|
||||
field :content
|
||||
field :disabled, type: Boolean, default: false
|
||||
belongs_to :property
|
||||
end
|
|
@ -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
|
||||
|
@ -11,25 +11,78 @@ class PHire
|
|||
field :hiring_person_id
|
||||
field :hiring_person_name
|
||||
field :reason_for_hire
|
||||
field :tmp_reason_for_hire, type: String, default: "" # store reason text from custom fields
|
||||
field :note_for_hire
|
||||
field :property_day_setting_id
|
||||
field :passed, type: Boolean, default: false
|
||||
field :recurring, type: Boolean, :default => false
|
||||
field :recurring_end_date, type: DateTime
|
||||
field :recurring_interval
|
||||
|
||||
field :organization
|
||||
field :person_in_charge
|
||||
field :tel_of_person_in_charge
|
||||
field :department
|
||||
field :contact_person
|
||||
field :tel_of_contact_person
|
||||
field :mobile_phone_of_contact_person
|
||||
field :contact_person_Email
|
||||
field :contact_person_department
|
||||
belongs_to :property
|
||||
|
||||
has_many :p_hire_field_values, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :p_hire_field_values, allow_destroy: true
|
||||
def property_day_setting
|
||||
PropertyDaySetting.find(self.property_day_setting_id) rescue nil
|
||||
end
|
||||
def time
|
||||
property_day_setting.title rescue nil
|
||||
end
|
||||
def as_json(options = {})
|
||||
startt = self.start_time
|
||||
endt = self.end_time
|
||||
recurring = false
|
||||
datet = self.date
|
||||
classNames = []
|
||||
viewButton = false
|
||||
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
|
||||
if !OrbitHelper.current_user.nil?
|
||||
if OrbitHelper.current_user.member_profile.id.to_s == self.hiring_person_id
|
||||
classNames = ["mybooking"]
|
||||
viewButton = true
|
||||
end
|
||||
end
|
||||
title = startt.strftime("%H:%M") + " ~ " + endt.strftime("%H:%M") + " " + self.hiring_person_name
|
||||
{
|
||||
:id => self.id.to_s,
|
||||
:title => self.reason_for_hire,
|
||||
# :title => (self.reason_for_hire.to_s + " "+ self.tmp_reason_for_hire.to_s).html_safe,
|
||||
:property_title => self.property.title,
|
||||
:title => title,
|
||||
:hiring_person_id => self.hiring_person_id,
|
||||
:hiring_person_name => self.hiring_person_name,
|
||||
:note => self.note_for_hire || "",
|
||||
:start => self.start_time.rfc822,
|
||||
:end => self.end_time.rfc822,
|
||||
:start => startt.to_json.gsub('"',''),
|
||||
:end => endt.to_json.gsub('"',''),
|
||||
:allDay => false,
|
||||
:color => "#FC4040"
|
||||
:diff_day => (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,
|
||||
:date=>datet,
|
||||
:recurring=>recurring,
|
||||
:classNames => classNames,
|
||||
:view_button => viewButton,
|
||||
:view_path => "/#{OrbitHelper.get_site_locale}/admin/property_hires/#{self.id.to_s}/show_booking_details",
|
||||
:view_path_name => I18n.t("property_hire.view")
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -38,48 +91,98 @@ class PHire
|
|||
end
|
||||
|
||||
def hirer_name
|
||||
return self.hiring_person_name.nil? ? self.hiring_person_profile.name : self.hiring_person_name
|
||||
return self.hiring_person_name.nil? ? (self.hiring_person_profile.name rescue "") : self.hiring_person_name
|
||||
end
|
||||
|
||||
def hiring_person_profile
|
||||
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_only=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_only
|
||||
events = events.where(:date.ne=>nil)
|
||||
end
|
||||
|
||||
def self.recurring_event(start_date,end_date,property_id)
|
||||
@recurring_events = self.where(:property_id => property_id, :recurring => true, :recurring_end_date.gte => start_date)
|
||||
events
|
||||
end
|
||||
def self.convert_datetime(time)
|
||||
if time.class == Time
|
||||
return time.to_datetime
|
||||
elsif time.class == DateTime
|
||||
return time
|
||||
elsif time.class == String
|
||||
return DateTime.parse(time)
|
||||
else
|
||||
return Time.at(time).to_datetime #time is seconds
|
||||
end
|
||||
end
|
||||
def self.recurring_event(start_date,end_date,property_id,date_only=false)
|
||||
start_date = convert_datetime(start_date)
|
||||
end_date = convert_datetime(end_date)
|
||||
@property = Property.find(property_id) rescue nil
|
||||
@recurring = []
|
||||
if @property != nil
|
||||
unavailable = @property.set_unavailibility && !@property.weekdays.empty? && !@property.start_date.nil? && !@property.end_date.nil?
|
||||
unavailable_start_date = @property.start_date
|
||||
unavailable_end_date = @property.end_date
|
||||
unavailable_start_time = @property.start_time.to_s
|
||||
unavailable_end_time = @property.end_time.to_s
|
||||
unavailable_start_date = DateTime.parse(unavailable_start_date.strftime("%Y-%m-%d " + unavailable_start_time.to_s + Time.zone.to_s)) rescue nil
|
||||
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_only
|
||||
@recurring_events = @recurring_events.where(:date.ne=>nil)
|
||||
end
|
||||
start_date_utc_mjd = start_date.to_datetime.new_offset(0).mjd
|
||||
@recurring_events.each do |re|
|
||||
case re.recurring_interval
|
||||
when "week"
|
||||
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
|
||||
new_end_date = [recurring_end_date,end_date].min
|
||||
@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
|
||||
if @start_date < start_date
|
||||
add_interval = nil
|
||||
period_str = nil
|
||||
if re.recurring_interval == "week"
|
||||
period_str = 'week'
|
||||
add_interval = (start_date_utc_mjd - @start_date.new_offset(0).mjd)
|
||||
days = 7
|
||||
if add_interval < 0
|
||||
add_interval = 0
|
||||
else
|
||||
add_interval = add_interval / days
|
||||
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"}
|
||||
else
|
||||
period_str = 'month'
|
||||
add_interval = ((start_date.year * 12 + start_date.month) - (@start_date.year * 12 + @start_date.month))
|
||||
add_interval = 0 if add_interval < 0
|
||||
end
|
||||
add_interval = add_interval.send(period_str)
|
||||
@start_date += add_interval
|
||||
@end_date += add_interval
|
||||
end
|
||||
while @start_date <= new_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))
|
||||
if !((startt..endt) & (@start_date..@end_date)).blank?
|
||||
@start_date += interval
|
||||
@end_date += interval
|
||||
datet += interval if datet
|
||||
next
|
||||
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"}
|
||||
if @start_date >= start_date
|
||||
@recurring << re.as_json({:startt=>@start_date,:endt=>@end_date,:datet=>datet})
|
||||
end
|
||||
@start_date += interval
|
||||
@end_date += interval
|
||||
datet += interval if datet
|
||||
end
|
||||
end
|
||||
# end
|
||||
end
|
||||
end
|
||||
@recurring
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
class PHireField
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
include Mongoid::Attributes::Dynamic
|
||||
include ::AttributeFieldsHelper
|
||||
include ::Admin::PHireFieldHelper
|
||||
field :display_in_reason_for_hire, type: Boolean, default: false
|
||||
field :key, type: String
|
||||
field :af_count
|
||||
field :title, type: String, localize: true
|
||||
field :markup, default: "text_field"
|
||||
field :option_list, type: Hash,default: {}
|
||||
field :markup_options, type: Hash
|
||||
field :built_in, type: Boolean, default: false
|
||||
field :disabled, type: Boolean, default: false
|
||||
field :to_delete, type: Boolean, default: false
|
||||
|
||||
field :to_require,type: Boolean, default: true
|
||||
|
||||
field :typeA, type: Hash, default: {cross_lang: false}
|
||||
field :typeB, type: Hash, default: {}
|
||||
field :typeC, type: Hash, default: {calendar: "west_calendar", format: "format3"}
|
||||
field :typeD, type: Hash, default: {cross_lang: false}
|
||||
field :typeE, type: Hash, default: {}
|
||||
field :typeF, type: Hash, default: {}
|
||||
belongs_to :property
|
||||
has_many :p_hire_field_values, autosave: true, dependent: :destroy
|
||||
accepts_nested_attributes_for :p_hire_field_values, :allow_destroy => true
|
||||
before_save :check_option_list
|
||||
before_destroy do
|
||||
@property = self.property
|
||||
if @property && @property.custom_field_names
|
||||
@property.custom_field_names.delete("p_hire_fields.#{self.id}")
|
||||
@property.save
|
||||
end
|
||||
end
|
||||
after_save do
|
||||
unless self.disabled
|
||||
@property = self.property
|
||||
if @property && @property.custom_field_names
|
||||
if self.new_record? || !(@property.custom_field_names.include?("p_hire_fields.#{self.id}"))
|
||||
@property.custom_field_names << "p_hire_fields.#{self.id}"
|
||||
@property.save
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.display_in_reason_for_hire_changed? && self.property
|
||||
self.property.update(:need_change_tmp_reason=>true)
|
||||
end
|
||||
end
|
||||
def markup_value
|
||||
get_data["option_list"]
|
||||
end
|
||||
|
||||
def add_more
|
||||
(get_data["add_more"] == "true" ? true : false) rescue false
|
||||
end
|
||||
|
||||
def locale
|
||||
get_data["cross_lang"] == "true" ? false : true
|
||||
end
|
||||
|
||||
def self_defined_markup_options?
|
||||
(self.property.method(self[:key].pluralize.to_sym) && self.property.method(self[:key].pluralize+"_for_"+markup)) rescue false
|
||||
end
|
||||
|
||||
def option_list
|
||||
if self_defined_markup_options?
|
||||
#Class need to have corresponding field and value agent
|
||||
# Ex: For "status" the class must have field called "statuses" for the relation and "statuses_for_select" for the select function
|
||||
method = self.property.method(self[:key].pluralize+"_for_"+markup)
|
||||
return (method.call rescue {})
|
||||
elsif self[:option_list].nil? || (self[:option_list].empty?)
|
||||
return {}
|
||||
else
|
||||
return self[:option_list]
|
||||
end
|
||||
end
|
||||
|
||||
def markup_options=(var)
|
||||
self[:markup_options] = (eval(var) rescue {})
|
||||
end
|
||||
|
||||
def markup_options
|
||||
if self[:markup_options].nil?
|
||||
return {}
|
||||
else
|
||||
Hash[self[:markup_options].map{|key,val|[key.to_sym,val]}] rescue {}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def panel
|
||||
panel = $property_list[:markups][self[:markup]]["panel"]
|
||||
end
|
||||
|
||||
def get_data
|
||||
self[panel]
|
||||
end
|
||||
def get_placeholder(locale=I18n.locale)
|
||||
placeholder = self.get_data["placeholder"] rescue nil
|
||||
if placeholder
|
||||
if placeholder.respond_to?(:keys)
|
||||
placeholder[locale.to_s]
|
||||
else
|
||||
placeholder
|
||||
end
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
def typeA=(var)
|
||||
check_add_more_convert(var)
|
||||
check_cross_lang_convert(var,"typeA")
|
||||
self["typeA"] = var
|
||||
end
|
||||
|
||||
def typeD=(var)
|
||||
check_cross_lang_convert(var,"typeD")
|
||||
self["typeD"] = var
|
||||
end
|
||||
|
||||
def is_built_in?
|
||||
self.built_in
|
||||
end
|
||||
|
||||
def is_disabled?
|
||||
self.disabled
|
||||
end
|
||||
|
||||
def self.add_p_hire_field(property,property_param, p_hire_field_id=nil,field_status)
|
||||
@field_name = 'property'
|
||||
if field_status.eql?(true)
|
||||
@p_hire_field_counter = property.p_hire_fields_enabled.count rescue nil
|
||||
@p_hire_field = self.find(p_hire_field_id) rescue nil
|
||||
old_key = @p_hire_field.key
|
||||
@p_hire_field.update(property_param)
|
||||
@p_hire_field.save
|
||||
attribute_values = @p_hire_field.p_hire_field_values
|
||||
if attribute_values.count > 0
|
||||
attribute_values.each do |av|
|
||||
av.key = property_param["key"]
|
||||
av.save
|
||||
end
|
||||
end
|
||||
@p_hire_field[:af_count] = @p_hire_field_counter
|
||||
else
|
||||
@p_hire_field_counter = property.p_hire_fields_enabled.count rescue nil
|
||||
@p_hire_field = property.p_hire_fields.build(property_param) rescue nil
|
||||
@p_hire_field.save
|
||||
@p_hire_field[:af_count] = @p_hire_field_counter
|
||||
end
|
||||
return @p_hire_field
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def check_cross_lang_convert(var,field)
|
||||
if self[field]["cross_lang"] != var["cross_lang"]
|
||||
case var["cross_lang"]
|
||||
when "true" #from no-add_more to add_more
|
||||
cross_lang_convert(:to_cross_lang)
|
||||
else #from add_more to no-add_more
|
||||
cross_lang_convert(:to_no_cross_lang)
|
||||
end # of case
|
||||
end # of if
|
||||
end
|
||||
|
||||
def check_add_more_convert(var)
|
||||
if self["typeA"]["add_more"] != var["add_more"]
|
||||
case var["add_more"]
|
||||
when "true" #from no-add_more to add_more
|
||||
add_more_convert(:to_add_more)
|
||||
else #from add_more to no-add_more
|
||||
add_more_convert(:to_no_add_more)
|
||||
end # of case
|
||||
end # of if
|
||||
end
|
||||
|
||||
def cross_lang_convert(opt)
|
||||
|
||||
end
|
||||
|
||||
def check_option_list
|
||||
self[:option_list] = self[panel]["option_list"] rescue nil
|
||||
end
|
||||
|
||||
def add_more_convert(opt)
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,237 @@
|
|||
class PHireFieldValue
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
include Mongoid::Attributes::Dynamic
|
||||
include ::AttributeValuesHelper
|
||||
include ::Admin::PHireFieldValuesHelper
|
||||
|
||||
field :key, type: String
|
||||
|
||||
belongs_to :p_hire_field
|
||||
belongs_to :p_hire
|
||||
|
||||
before_save :check_key
|
||||
before_save :data_proc
|
||||
|
||||
def add_more_counter
|
||||
index_max = self["val"].count rescue 0
|
||||
index_max == 0 ? 1 : index_max
|
||||
end
|
||||
|
||||
def value(index = nil)
|
||||
site = Site.first
|
||||
result = case self.p_hire_field.markup
|
||||
when 'text_field','text_area'
|
||||
if self.p_hire_field.add_more and (self.p_hire_field.markup == "text_field")
|
||||
index.nil? ? self["val"] : self["val"][index]
|
||||
else
|
||||
self.p_hire_field.get_data["cross_lang"] =="true" ? self["val"] : Hash[site.valid_locales.collect{|lang| [lang,self[lang.to_sym]]}]
|
||||
end
|
||||
when 'select','radio_button','address'
|
||||
self["val"]
|
||||
when 'date'
|
||||
if !self["val"].blank? and !self["val"]['(1i)'].blank?
|
||||
"#{self["val"]['(1i)']}/#{self["val"]['(2i)']}/#{self["val"]['(3i)']}"
|
||||
else
|
||||
self["val"]
|
||||
end
|
||||
when 'checkbox'
|
||||
self["val"]
|
||||
end #end of case self.p_hire_field.markup
|
||||
end
|
||||
|
||||
def value=(value)
|
||||
#save everything to temp_data waiting for futher process
|
||||
self[:temp_data] = value
|
||||
end
|
||||
|
||||
def get_field_value
|
||||
p_hire_field = self.p_hire_field
|
||||
if (p_hire_field.markup.eql?("text_field") || p_hire_field.markup.eql?("text_area"))
|
||||
if self.value.class == String
|
||||
field_value = self.value
|
||||
else
|
||||
field_value = self.value[I18n.locale]
|
||||
end
|
||||
elsif (p_hire_field.markup.eql?("select") || p_hire_field.markup.eql?("radio_button"))
|
||||
field_value = p_hire_field.markup_value["#{self.value}"][I18n.locale] rescue nil
|
||||
elsif p_hire_field.markup.eql?("address")
|
||||
field_value = rf[:address_key][I18n.locale].map{|k,v| v}.delete_if(&:blank?).join(', ')
|
||||
elsif p_hire_field.markup.eql?("date")
|
||||
case p_hire_field.typeC['format']
|
||||
when 'format1'
|
||||
field_value = self.value.to_date.strftime("%Y/%m/%d")
|
||||
when 'format2'
|
||||
field_value = self.value.to_date.strftime("%Y/%m/%d")
|
||||
when 'format3'
|
||||
field_value = self.value.to_date.strftime("%Y/%m")
|
||||
when 'format4'
|
||||
field_value = self.value.to_date.strftime("%Y")
|
||||
end
|
||||
elsif p_hire_field.markup.eql?("checkbox")
|
||||
field_value = self.value.map {|v| p_hire_field.markup_value["#{v}"][I18n.locale]}.join(', ') rescue nil
|
||||
end
|
||||
|
||||
field_value = (field_value =~ /\A#{URI::regexp(['http', 'https'])}\z/) ? "<a href='#{field_value}' target='blank'>#{field_value}</a>" : field_value
|
||||
field_value = (field_value =~ /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i) ? "<a href='mailto:#{field_value}'>#{field_value}</a>" : field_value
|
||||
if p_hire_field.markup.eql?("hint_text")
|
||||
field_value = p_hire_field.get_placeholder rescue ""
|
||||
{
|
||||
"key" => p_hire_field.key,
|
||||
"title" => p_hire_field.title,
|
||||
"value" => field_value,
|
||||
"val" => field_value,
|
||||
"hint" => true
|
||||
}
|
||||
elsif !field_value.blank?
|
||||
{
|
||||
"key" => p_hire_field.key,
|
||||
"title" => p_hire_field.title,
|
||||
"value" => field_value,
|
||||
"val" => field_value = self.value
|
||||
}
|
||||
else
|
||||
{
|
||||
"key" => p_hire_field.key,
|
||||
"title" => p_hire_field.title,
|
||||
"value" => "",
|
||||
"val" => field_value = self.value
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def get_value_by_locale(locale,add_more_index=nil)
|
||||
p_hire_field = self.p_hire_field
|
||||
case p_hire_field.markup
|
||||
when "text_field"
|
||||
case p_hire_field.add_more
|
||||
when true
|
||||
if p_hire_field.locale
|
||||
add_more_index.nil? ? self.value.collect{|t| t[locale.to_s]}.join(",") : self.value(add_more_index)[locale]
|
||||
else
|
||||
add_more_index.nil? ? self.value.join(",") : self.value(add_more_index)
|
||||
end
|
||||
|
||||
when false
|
||||
p_hire_field.locale ? self[locale.to_s] : self.value
|
||||
end
|
||||
|
||||
when "select"
|
||||
markup_values = p_hire_field.self_defined_markup_options? ? p_hire_field.markup_value : self.p_hire_field.markup_value
|
||||
markup_values[self.value][locale.to_s] rescue 'NoData'
|
||||
|
||||
when "text_area"
|
||||
p_hire_field.locale ? self[locale.to_s] : self.value
|
||||
|
||||
when "date"
|
||||
if p_hire_field.date_is_range?
|
||||
get_date_by_format(:from) + ' ~ ' + get_date_by_format(:to)
|
||||
# self.value["from"] + ' ~ ' + self.value["to"]
|
||||
else
|
||||
get_date_by_format
|
||||
# self.value
|
||||
end
|
||||
|
||||
when "address"
|
||||
self.value[locale.to_s]
|
||||
|
||||
when "radio_button"
|
||||
markup_values = p_hire_field.markup_value
|
||||
markup_values[self.value][locale.to_s]
|
||||
|
||||
when "checkbox"
|
||||
markup_values = p_hire_field.markup_value
|
||||
self.value.collect{|key| markup_values["#{key}"][I18n.locale]}.join(",")
|
||||
when "date_durnation"
|
||||
self.value
|
||||
|
||||
else
|
||||
p_hire_field.locale ? self[locale.to_s] : self.value
|
||||
end
|
||||
end
|
||||
|
||||
def get_date(item = nil)
|
||||
case item
|
||||
when :from
|
||||
# data = self[:val]["from"]
|
||||
data = self.value["from"]
|
||||
when :to
|
||||
# data = self[:val]["to"]
|
||||
data = self.value["to"]
|
||||
when nil
|
||||
# data = self[:val]
|
||||
data = self.value
|
||||
end
|
||||
|
||||
# Date.new(data["(1i)"].to_i,data["(2i)"].to_i,data["(3i)"].to_i) rescue nil
|
||||
end
|
||||
|
||||
def self.put_field_values(p_hire, field_value_param, field_value_id=nil,field_value_status)
|
||||
if field_value_status.eql?(true)
|
||||
@p_hire_field_value = p_hire.p_hire_field_values.find(field_value_id) rescue nil
|
||||
if @p_hire_field_value!=nil
|
||||
@p_hire_field_value.update(field_value_param) rescue nil
|
||||
@p_hire_field_value.save rescue nil
|
||||
end
|
||||
else
|
||||
@p_hire_field_value = p_hire.p_hire_field_values.build(field_value_param) rescue nil
|
||||
@p_hire_field_value.save
|
||||
end
|
||||
return @p_hire_field_value
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
def unset_all_lang_values
|
||||
VALID_LOCALES.each{|t| self.unset t}
|
||||
end
|
||||
|
||||
def data_proc
|
||||
p_hire_field = self.p_hire_field
|
||||
unless self[:temp_data].nil?
|
||||
case p_hire_field.markup
|
||||
when "address"
|
||||
self["val"] = self["temp_data"]
|
||||
when 'text_field','text_area'
|
||||
if p_hire_field.add_more
|
||||
self["val"] = self["temp_data"]
|
||||
else # if not add_more
|
||||
if p_hire_field.can_muti_lang_input?
|
||||
self[:temp_data].each do |key,val|
|
||||
self[key] = val
|
||||
end if(!p_hire_field.get_data[:cross_lang])
|
||||
else
|
||||
self["val"] = self[:temp_data]
|
||||
end
|
||||
end # of self.p_hire_field.add_more
|
||||
|
||||
when 'select','date','radio_button'
|
||||
self["val"] = self[:temp_data]
|
||||
when 'checkbox'
|
||||
self["val"] = self[:temp_data].keys
|
||||
end #end of case self.p_hire_field.markup
|
||||
end # of self[:temp_data].nil?
|
||||
self.unset('temp_data')
|
||||
self.unset('temp')
|
||||
end #of data_proc
|
||||
|
||||
def check_key
|
||||
if self.p_hire_field_id.present? && self.p_hire_field.nil?
|
||||
begin
|
||||
self.p_hire_field = PHireField.find(self.p_hire_field_id)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
self.key = self.p_hire_field.key rescue nil
|
||||
end
|
||||
|
||||
def method_missing(*field)
|
||||
if field.size < 1
|
||||
self[field[0]]
|
||||
else
|
||||
self[(field[0].to_s.delete "=")] = field[1]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,6 +5,15 @@ class Property
|
|||
include OrbitCategory::Categorizable
|
||||
include Slug
|
||||
|
||||
FIELDSNAME=["hiring_person_email","hiring_person_number","hiring_person_name","reason_for_hire","note_for_hire","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"]
|
||||
field :need_change_tmp_reason, type: Boolean, default: false
|
||||
field :need_hire_before, type: Integer, default: 0 #0代表沒有限制
|
||||
field :need_hire_before_unit, type: String, default: "day" #month, day, hour, minute
|
||||
field :custom_calendar_type, type: Integer, default: 0 #0=>預設, 1=> 顯示, 2=> 不顯示
|
||||
field :custom_carousel_image_width, type: String, default: ""
|
||||
field :display_img, :type => Boolean, :default => false
|
||||
field :image_display_class, type: String, default: "full-size-img" #3 choices: full-size-img , pull-left , pull-right
|
||||
field :order_position, type: Integer, default: -1
|
||||
field :title, as: :slug_title, :localize => true
|
||||
field :property_usage, :localize => true
|
||||
field :note, :localize => true
|
||||
|
@ -14,26 +23,74 @@ class Property
|
|||
field :owners, type: Array, :default => []
|
||||
field :other_owner
|
||||
field :owner_email
|
||||
field :owner_email_rule, type: Integer, default: 0 # 0 => owners, 1 => owner_email, 2 => owners + owner_email
|
||||
field :owner_phone
|
||||
field :price
|
||||
field :other_location
|
||||
field :p_hire_start_time, type: DateTime
|
||||
field :p_hire_end_time, type: DateTime
|
||||
field :p_open_start_time, type: DateTime
|
||||
field :p_open_end_time, type: DateTime
|
||||
field :p_display_start_time, type: DateTime
|
||||
field :p_display_end_time, type: DateTime
|
||||
field :recurring_enable, type: Boolean, :default => false
|
||||
|
||||
mount_uploader :image, ImageUploader
|
||||
|
||||
# unavailibility fields
|
||||
|
||||
field :can_hire_before_months, type: Integer, default: 0
|
||||
field :set_availability, type: Boolean, default: false
|
||||
field :set_unavailibility, type: Boolean, default: false
|
||||
field :start_time
|
||||
field :end_time
|
||||
field :weekdays, type: Array, default: []
|
||||
field :start_date, type: DateTime
|
||||
field :end_date, type: DateTime
|
||||
field :special_unavailable_dates, type: Array, default: []
|
||||
field :special_unavailable_dates_title, type: Array, default: []
|
||||
field :start_date, type: DateTime # unavailable start date
|
||||
field :end_date, type: DateTime # unavailable end date
|
||||
field :hours_restriction, type: Integer, default: 0
|
||||
field :hours_restriction_duration, type: String
|
||||
field :description, :localize => true
|
||||
field :unavailibility_note, :localize => true
|
||||
|
||||
field :hiring_person_email, type: Hash, default: {"enable"=>"1","required"=>"true"}
|
||||
field :hiring_person_number, type: Hash, default: {"enable"=>"1","required"=>"true"}
|
||||
field :hiring_person_name, type: Hash, default: {"enable"=>"1","required"=>"true"}
|
||||
field :reason_for_hire, type: Hash, default: {"enable"=>"1","required"=>"true"}
|
||||
field :note_for_hire, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :organization, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :person_in_charge, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :tel_of_person_in_charge, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :department, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :contact_person, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :tel_of_contact_person, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :mobile_phone_of_contact_person, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :contact_person_Email, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :contact_person_department, type: Hash, default: {"enable"=>"1","required"=>"false"}
|
||||
field :enable_notes_selector , type: Boolean, default: false
|
||||
field :notes_selector ,type: Hash, default: {}
|
||||
field :enable_fields_sort , type: Boolean, default: false
|
||||
field :custom_field_names, type: Array
|
||||
field :default_field_names, type: Array
|
||||
field :copy_id
|
||||
field :except_clone_relations, :type=>Array, :default => []
|
||||
belongs_to :property_location
|
||||
has_many :p_hires
|
||||
|
||||
has_many :hire_email_sets, :autosave => true, :dependent => :destroy, :inverse_of => :property
|
||||
accepts_nested_attributes_for :hire_email_sets, :allow_destroy => true
|
||||
has_many :p_hire_fields, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :p_hire_fields, :allow_destroy => true
|
||||
has_many :property_field_sets, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :property_field_sets, :allow_destroy => true
|
||||
has_many :property_day_settings, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :property_day_settings, :allow_destroy => true
|
||||
has_many :property_carousel_images, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :property_carousel_images, :allow_destroy => true
|
||||
has_many :property_files, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :property_files, :allow_destroy => true
|
||||
has_many :property_links, :autosave => true, :dependent => :destroy
|
||||
accepts_nested_attributes_for :property_links, :allow_destroy => true
|
||||
scope :sort_order, ->{order_by([:created_at,:desc],[:order_position,:asc])}
|
||||
scope :can_display, ->{any_of({:p_display_start_time.lt=>Time.now, :p_display_end_time.gt=>Time.now},{:p_display_start_time.lt=>Time.now, :p_display_end_time=>nil},{:p_display_start_time=>nil, :p_display_end_time=>nil})}
|
||||
WEEKDAYS = [
|
||||
"Sunday",
|
||||
"Monday",
|
||||
|
@ -43,7 +100,204 @@ class Property
|
|||
"Friday",
|
||||
"Saturday"
|
||||
]
|
||||
CAlENDARTYPE = ["default","display","not_display"]
|
||||
after_initialize do
|
||||
unless self.new_record?
|
||||
save_flag = false
|
||||
@no_validate = true
|
||||
if self.default_field_names.nil?
|
||||
self.default_field_names = self.get_all_fields(true)
|
||||
save_flag = true
|
||||
end
|
||||
if self.custom_field_names.nil?
|
||||
self.custom_field_names = self.get_all_fields(true)
|
||||
save_flag = true
|
||||
end
|
||||
if save_flag
|
||||
self.save
|
||||
end
|
||||
end
|
||||
end
|
||||
before_create do
|
||||
max_position = self.class.max(:order_position)
|
||||
max_position = -1 if max_position.nil?
|
||||
self.order_position = max_position + 1
|
||||
@no_validate = true
|
||||
if self.copy_id.present?
|
||||
self.clone_new(true)
|
||||
self.created_at = DateTime.now
|
||||
self.updated_at = DateTime.now
|
||||
else
|
||||
self.default_field_names = self.get_all_fields(true)
|
||||
self.custom_field_names = self.get_all_fields(true)
|
||||
end
|
||||
end
|
||||
before_save do
|
||||
unless @no_validate || self.new_record?
|
||||
self.custom_field_names = [] if self.custom_field_names.nil?
|
||||
self.default_field_names = self.get_all_fields(true)
|
||||
self.class::FIELDSNAME.each do |f|
|
||||
if((self.send(f)["enable"] == "1" rescue true) && !(self.custom_field_names.include?(f)))
|
||||
self.custom_field_names << f
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
after_save do
|
||||
self.change_day_setting_status
|
||||
end
|
||||
|
||||
def can_reserve
|
||||
start_time = self.p_hire_start_time || Time.now
|
||||
end_time = self.p_hire_end_time || (Time.now + 1.month)
|
||||
return Time.now >= start_time && end_time >= Time.now
|
||||
end
|
||||
|
||||
def p_hire_fields_enabled
|
||||
self.p_hire_fields.where(disabled: false)
|
||||
end
|
||||
def all_day_settings
|
||||
self.property_day_settings.asc(:key).group_by(&:day)
|
||||
end
|
||||
def change_day_setting_status
|
||||
if self.property_day_settings.count != 0
|
||||
if self.set_unavailibility && self.weekdays.count != 0
|
||||
self.property_day_settings.where(:day.nin=>self.weekdays).update_all(:enable=>true)
|
||||
tmp_start_time = self.start_time.blank? ? "00:00" : self.start_time
|
||||
tmp_end_time = self.end_time.blank? ? "24:00" : self.end_time
|
||||
self.property_day_settings.where(:day.in=>self.weekdays).each do |setting|
|
||||
if setting.end_time < tmp_start_time || setting.start_time > tmp_end_time
|
||||
setting.enable = true
|
||||
else
|
||||
setting.enable = false
|
||||
end
|
||||
setting.save
|
||||
end
|
||||
else
|
||||
self.property_day_settings.update_all(:enable=>true)
|
||||
end
|
||||
end
|
||||
end
|
||||
def calendar_type
|
||||
(self.custom_calendar_type == 0 ? (PropertyHireSetting.first.calendar_type rescue 0) : (self.custom_calendar_type - 1))
|
||||
end
|
||||
def self.init_class_variables
|
||||
setting = PropertyHireSetting.first
|
||||
if setting
|
||||
@@disable_content_page = setting.disable_content_page rescue false
|
||||
@@disable_view_calendar_page = setting.disable_view_calendar_page rescue false
|
||||
@@disable_no_logins_view_calendar = setting.disable_no_logins_view_calendar rescue false
|
||||
else
|
||||
@@disable_content_page = false
|
||||
@@disable_view_calendar_page = false
|
||||
@@disable_no_logins_view_calendar = false
|
||||
end
|
||||
end
|
||||
init_class_variables
|
||||
def disable_content_page
|
||||
@@disable_content_page
|
||||
end
|
||||
def disable_view_calendar_page
|
||||
@@disable_view_calendar_page
|
||||
end
|
||||
def disable_no_logins_view_calendar
|
||||
@@disable_no_logins_view_calendar
|
||||
end
|
||||
def custom_text(field_name,type="name",locale=nil)
|
||||
locale = locale || I18n.locale
|
||||
default_text = I18n.with_locale(locale){I18n.t("property_hire.#{field_name}")}
|
||||
if (self.send(field_name)[type][locale.to_s].present? rescue false)
|
||||
self.send(field_name)[type][locale.to_s]
|
||||
else
|
||||
default_text
|
||||
end
|
||||
end
|
||||
def render_unavailable_message
|
||||
message = ""
|
||||
property = self
|
||||
weekdays_options = self.class::WEEKDAYS
|
||||
weekdays_options = weekdays_options.map do |weekday|
|
||||
trans = I18n.t("property_hire.#{weekday}", :default=>'')
|
||||
if trans != ""
|
||||
trans
|
||||
else
|
||||
weekday
|
||||
end
|
||||
end
|
||||
if property.set_unavailibility
|
||||
if property.weekdays.length > 0
|
||||
translation_missing = (I18n.t('property_hire.unavailable_hint1', {:default => ''}) == "")
|
||||
str1 = (!property.start_date.nil? ? (I18n.t("property_hire.from",:default=>" from ") + property.start_date.strftime("%Y-%m-%d")) : "")
|
||||
str2 = (!property.end_date.nil? ? (I18n.t("property_hire.to",:default=>" to ") + property.end_date.strftime("%Y-%m-%d")) : "")
|
||||
if str1 == "" && str2 != ""
|
||||
str1 = I18n.t("property_hire.from_now_on")
|
||||
end
|
||||
if str1 != "" || str2 != ""
|
||||
str2 += I18n.t("property_hire.of",:default=>"")
|
||||
else
|
||||
str2 += I18n.t("property_hire.at",:default=>"")
|
||||
end
|
||||
week_str = ""
|
||||
if translation_missing
|
||||
week_str += "every "
|
||||
else
|
||||
week_str += I18n.t("property_hire.every")
|
||||
end
|
||||
dot_trans = I18n.t("property_hire.dot",:default=>", ")
|
||||
property.weekdays.each_with_index do |d,i|
|
||||
if i < (property.weekdays.count - 1)
|
||||
week_str += (weekdays_options[d.to_i] + dot_trans)
|
||||
else
|
||||
week_str += weekdays_options[d.to_i]
|
||||
end
|
||||
end
|
||||
str3 = ""
|
||||
if property.end_time.blank?
|
||||
if property.start_time.blank?
|
||||
str3 = "." if translation_missing
|
||||
else
|
||||
str3 = I18n.t("property_hire.from_time",{:time=>property.start_time,:default=>" from #{property.start_time}."})
|
||||
end
|
||||
else
|
||||
if I18n.locale.to_s != "zh_tw"
|
||||
str3 = " between #{property.start_time} & #{property.end_time}."
|
||||
else
|
||||
str3 = I18n.t("property_hire.time1_to_time2",{:time1=>property.start_time,:time2=>property.end_time})
|
||||
end
|
||||
end
|
||||
if str3 != ""
|
||||
str3 = I18n.t("property_hire.of",:default=>"") + str3
|
||||
end
|
||||
hint1 = I18n.t('property_hire.unavailable_hint1', {:str1=>str1,:str2=>str2,:week_str=>week_str,:str3=>str3, :default => ''})
|
||||
if hint1 == ""
|
||||
message += "This property is unavaliable#{str1}#{str2} #{week_str}#{str3}"
|
||||
else
|
||||
message += hint1
|
||||
end
|
||||
end
|
||||
if property.special_unavailable_dates.count > 1
|
||||
message += " And on " + property.special_unavailable_dates.join(", ")
|
||||
end
|
||||
if property.need_hire_before != 0
|
||||
if message != ""
|
||||
message += "<br>"
|
||||
end
|
||||
default_msg = "This property must be reserved #{property.need_hire_before} #{property.need_hire_before_unit}s in advance."
|
||||
message += I18n.t("property_hire.unavailable_hint3",{:month=>property.need_hire_before,:unit=>I18n.t("property_hire._#{property.need_hire_before_unit}",:default=>property.need_hire_before_unit),:default=>default_msg})
|
||||
end
|
||||
if property.can_hire_before_months != 0
|
||||
if message != ""
|
||||
message += "<br>"
|
||||
end
|
||||
default_msg = "This property is unavaliable to reserved before #{property.can_hire_before_months} month ago."
|
||||
message += I18n.t("property_hire.unavailable_hint2",{:month=>property.can_hire_before_months,:default=>default_msg})
|
||||
end
|
||||
if property.hours_restriction > 0
|
||||
message += "<br />" + I18n.t("property_hire.hours_restriction_message", {:no_of_hours => property.hours_restriction, :duration => I18n.t("property_hire._#{property.hours_restriction_duration}") })
|
||||
end
|
||||
end
|
||||
return message.html_safe
|
||||
end
|
||||
def get_location_name
|
||||
return self.property_location.nil? ? self.other_location : self.property_location.title
|
||||
end
|
||||
|
@ -52,92 +306,586 @@ class Property
|
|||
MemberProfile.find(self.owners) rescue []
|
||||
end
|
||||
|
||||
def is_available_for_hire?(stime, etime)
|
||||
return true if self.set_unavailibility == false
|
||||
return true if self.weekdays.empty?
|
||||
return true if !self.start_date.nil? && (self.start_date > stime && self.start_date > etime)
|
||||
return true if !self.end_date.nil? && self.end_date < stime
|
||||
startt = self.start_date.nil? ? self.created_at : self.start_date
|
||||
endt = self.end_date.nil? && !startt.nil? ? (startt + 5.years) : self.end_date
|
||||
def get_user_total_user_hired_hours(start_time, end_time)
|
||||
member_profile_id = OrbitHelper.current_user.member_profile.id.to_s rescue nil
|
||||
return 0 if member_profile_id.nil?
|
||||
hires = self.p_hires.where(:hiring_person_id => member_profile_id, :start_time.gte => start_time, :end_time.lte => end_time)
|
||||
total_hours = 0.0
|
||||
hires.each do |hire|
|
||||
diff = hire.end_time - hire.start_time
|
||||
total_hours += diff * 24.0
|
||||
end
|
||||
return total_hours
|
||||
end
|
||||
|
||||
def is_available_for_hire?(stime, etime, interval = nil, recurring_end_date = nil, time_setting_id = nil, member_profile)
|
||||
available = 0
|
||||
is_user_manager = Admin::PropertyHiresController.helpers.check_if_user_is_manager?
|
||||
return 1 if is_user_manager == true
|
||||
return 1 if self.set_unavailibility == false
|
||||
return 1 if self.weekdays.empty? && self.can_hire_before_months == 0
|
||||
time_now = Time.now.to_datetime
|
||||
if self.can_hire_before_months != 0
|
||||
return 2 if ((stime - (self.can_hire_before_months).month) > time_now)
|
||||
end
|
||||
if self.need_hire_before != 0
|
||||
return 3 if (time_now + (self.need_hire_before).send(self.need_hire_before_unit) > stime)
|
||||
end
|
||||
self.special_unavailable_dates.each do |dt|
|
||||
unavailable_date = Date.parse(dt)
|
||||
cd = (stime..etime) & (unavailable_date..unavailable_date)
|
||||
if !cd.nil?
|
||||
return 0
|
||||
end
|
||||
end
|
||||
if DateTime.now >= (self.start_date || DateTime.now - 1.day) && DateTime.now <= (self.end_date || DateTime.now + 1.month)
|
||||
if self.hours_restriction > 0 && !user.nil?
|
||||
sd = nil
|
||||
edd = nil
|
||||
case self.hours_restriction_duration
|
||||
when "week"
|
||||
sd = stime - stime.wday
|
||||
edd = sd + 6
|
||||
when "month"
|
||||
sd = Date.new(stime.year, stime.month, 1)
|
||||
edd = sd.next_month.prev_day
|
||||
end
|
||||
if self.get_user_total_user_hired_hours(sd, edd) >= self.hours_restriction
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
available = 1 if startt > etime
|
||||
available = 1 if endt < stime
|
||||
weekdays = self.weekdays.collect{|w| w.to_i}
|
||||
if !startt.nil?
|
||||
if available == 0
|
||||
common_dates = (startt..endt) & (stime..etime)
|
||||
return true if common_dates.nil?
|
||||
available = 1 if common_dates.nil?
|
||||
if available == 0
|
||||
time_weekdays = []
|
||||
Property.time_iterate(common_dates.min, common_dates.max, 1.day) do |t|
|
||||
time_weekdays << t.wday
|
||||
end
|
||||
time_weekdays.uniq!
|
||||
weekdays = weekdays & time_weekdays
|
||||
return true if weekdays.blank?
|
||||
startt = DateTime.parse(stime.strftime("%Y-%m-%d " + self.start_time + Time.zone.to_s))
|
||||
endt = DateTime.parse(etime.strftime("%Y-%m-%d " + self.end_time + Time.zone.to_s))
|
||||
common_dates = (startt..endt) & (stime..etime)
|
||||
if common_dates.nil?
|
||||
return true
|
||||
if weekdays.blank?
|
||||
available = 1
|
||||
else
|
||||
return false
|
||||
startt = DateTime.parse(stime.strftime("%Y-%m-%d " + (self.start_time.blank? ? "00:00" : self.start_time) + Time.zone.to_s))
|
||||
endt = DateTime.parse(etime.strftime("%Y-%m-%d " + (self.end_time.blank? ? "23:59" : self.end_time) + Time.zone.to_s))
|
||||
common_dates = (startt..endt) & (stime..etime)
|
||||
available = common_dates.nil? ? 1 : 0
|
||||
end
|
||||
end
|
||||
end
|
||||
if available == 1
|
||||
if !recurring_end_date.blank?
|
||||
case interval
|
||||
when 'week'
|
||||
d_step = 1.week
|
||||
when 'month'
|
||||
d_step = 1.month
|
||||
else
|
||||
d_step = 0
|
||||
end
|
||||
if d_step != 0
|
||||
if etime >= stime
|
||||
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)
|
||||
break if available != 1
|
||||
end
|
||||
else
|
||||
available = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
return available
|
||||
else
|
||||
return available
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def is_already_hired?(stime, etime, interval, recurring_end_date)
|
||||
bookings = self.p_hires.where(:end_time.gte => stime, :recurring => false)
|
||||
def not_yet_hired?(stime, etime, interval, recurring_end_date,phire_id=nil,time_setting_id=nil)
|
||||
phires = self.p_hires
|
||||
stime = stime.utc
|
||||
etime = etime.utc
|
||||
bookings_count = 0
|
||||
reservation_limit = 0
|
||||
if time_setting_id
|
||||
time_setting = PropertyDaySetting.find(time_setting_id)
|
||||
etime = stime + 1.day
|
||||
etime = etime.utc
|
||||
reservation_limit = time_setting.reservation_limit
|
||||
if reservation_limit == 0
|
||||
return true
|
||||
end
|
||||
bookings_count = phires.where(:start_time.lte => stime,:end_time.gte => stime,:recurring => false,:id.ne=>phire_id,:property_day_setting_id=>time_setting_id).count
|
||||
+ phires.where(:start_time.gte => stime,:end_time.lte => etime,:recurring => false,:id.ne=>phire_id,:property_day_setting_id=>time_setting_id).count
|
||||
+phires.where(:start_time.lte => etime,:end_time.gte => etime,:recurring => false,:id.ne=>phire_id,:property_day_setting_id=>time_setting_id).count
|
||||
if bookings_count < reservation_limit
|
||||
bookings_count = 0
|
||||
end
|
||||
else
|
||||
bookings_count = phires.where(:start_time.lte => stime,:end_time.gte => stime,:recurring => false,:id.ne=>phire_id).count
|
||||
+ phires.where(:start_time.gte => stime,:end_time.lte => etime,:recurring => false,:id.ne=>phire_id).count
|
||||
+phires.where(:start_time.lte => etime,:end_time.gte => etime,:recurring => false,:id.ne=>phire_id).count
|
||||
end
|
||||
available = true
|
||||
bookings.each do |booking|
|
||||
common_time = (booking.start_time..booking.end_time) & (stime..etime)
|
||||
if !common_time.nil?
|
||||
if bookings_count != 0
|
||||
available = false
|
||||
end
|
||||
if available
|
||||
recurring_bookings = phires.where(:recurring_end_date.gte => stime, :recurring => true,:id.ne=>phire_id)
|
||||
bookings = phires.where(:recurring => false,:recurring_end_date => nil,:id.ne=>phire_id)
|
||||
case interval
|
||||
when 'week'
|
||||
d_step = 1.week
|
||||
when 'month'
|
||||
d_step = 1.month
|
||||
else
|
||||
d_step = 0
|
||||
end
|
||||
not_in_ids = bookings.any_of([{:end_time.lt=>stime},{:start_time.gt=>etime}]).pluck(:id)
|
||||
bookings = bookings.where(:id.nin=>not_in_ids)
|
||||
if time_setting_id
|
||||
recurring_bookings = recurring_bookings.where(:property_day_setting_id=>time_setting_id)
|
||||
bookings = recurring_bookings.where(:property_day_setting_id=>time_setting_id)
|
||||
end
|
||||
if true#d_step != 0
|
||||
bookings += recurring_bookings
|
||||
end
|
||||
if time_setting_id
|
||||
tmp = {}
|
||||
stime_date = stime.strftime("%Y-%m-%d")
|
||||
bookings = bookings.each_with_index do |booking,i|
|
||||
if booking.date.wday != stime.wday
|
||||
next
|
||||
end
|
||||
b_interval = booking.recurring_interval
|
||||
b_recurring_end_date = booking.recurring_end_date ? booking.recurring_end_date.utc : nil
|
||||
booking_date = booking.start_time.utc.strftime("%Y-%m-%d")
|
||||
if (b_interval == 'month' || b_interval == 'week') && (booking.recurring_end_date.nil? || !booking.recurring)
|
||||
b_interval = nil
|
||||
end
|
||||
if stime_date == booking_date
|
||||
if tmp[booking_date].nil?
|
||||
tmp[booking_date] = 0
|
||||
end
|
||||
tmp[booking_date] += 1
|
||||
available = false if tmp[booking_date] > reservation_limit
|
||||
end
|
||||
break if available == false
|
||||
if b_interval.present?
|
||||
b_interval = (1).send(b_interval)
|
||||
b_sdata = booking.start_time.utc
|
||||
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)
|
||||
if tmp[booking_date].nil?
|
||||
tmp[booking_date] = 0
|
||||
end
|
||||
tmp[booking_date] += 1
|
||||
available = false if tmp[booking_date] > reservation_limit
|
||||
end
|
||||
break if available == false
|
||||
end
|
||||
end
|
||||
break if available == false
|
||||
end
|
||||
else
|
||||
bookings.each_with_index do |booking,i|
|
||||
stime_tp = stime.clone
|
||||
etime_tp = etime.clone
|
||||
b_interval = booking.recurring_interval
|
||||
b_recurring_end_date = booking.recurring_end_date ? booking.recurring_end_date.utc : nil
|
||||
b_sdata = booking.start_time.utc
|
||||
b_edata = booking.end_time.utc
|
||||
b_delta = b_edata - b_sdata
|
||||
if (b_interval == 'month' || b_interval == 'week') && (booking.recurring_end_date.nil? || !booking.recurring)
|
||||
b_interval = nil
|
||||
end
|
||||
b_datas = []
|
||||
if b_interval.present?
|
||||
b_interval = (1).send(b_interval)
|
||||
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|
|
||||
if b_start >= stime_tp || b_end <= etime_tp
|
||||
start_index = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if available
|
||||
case interval
|
||||
when "week"
|
||||
stepu = 1.week
|
||||
when "month"
|
||||
stepu = 1.month
|
||||
b_datas = b_datas[start_index..-1].to_a.map{|b_start,b_end| (b_start..b_end)}
|
||||
else
|
||||
stepu = 0
|
||||
b_datas = [b_sdata..b_edata]
|
||||
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
|
||||
if stepu != 0
|
||||
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
|
||||
while b_datas.present?
|
||||
available = b_datas.find{|b_range| b_range & (stime_tp..etime_tp)}.nil?
|
||||
stime_tp = stime_tp + d_step
|
||||
etime_tp = etime_tp + d_step
|
||||
break if !available || recurring_end_date.blank? || d_step==0
|
||||
start_index = b_datas.find_index{|b_range| b_range.first >= stime_tp}
|
||||
if start_index
|
||||
b_datas = b_datas[start_index..-1]
|
||||
else
|
||||
common_time = (tst..tet) & (st..et)
|
||||
available = false if !common_time.nil?
|
||||
break if !available
|
||||
b_datas = []
|
||||
end
|
||||
break if !available
|
||||
end
|
||||
break if !available
|
||||
break if available == false
|
||||
end
|
||||
end
|
||||
end
|
||||
return available
|
||||
end
|
||||
|
||||
def check_require_fields(booking_p)
|
||||
fields_name = self.get_all_fields
|
||||
has_p_hire_fields = self.p_hire_fields_enabled.count != 0
|
||||
p_hire_fields = {}
|
||||
if has_p_hire_fields
|
||||
p_hire_fields = self.p_hire_fields_enabled.map{|rf| [rf.id.to_s,rf]}.to_h
|
||||
end
|
||||
error_messages = ""
|
||||
form_index = 0
|
||||
cross_lang_types = ['select','date','radio_button','checkbox']
|
||||
unfilled_text = I18n.t('property_hire.unfilled')
|
||||
available_locales = I18n.available_locales
|
||||
available_locales_trans = available_locales.map{|l| [l, I18n.t(l)]}.to_h
|
||||
fields_name.each do |field_name|
|
||||
if has_p_hire_fields && field_name.include?("p_hire_fields")
|
||||
rf = p_hire_fields[field_name.sub("p_hire_fields.",'')]
|
||||
if rf && rf.markup != 'hint_text' && rf.to_require
|
||||
v = booking_p["p_hire_field_values_attributes"][form_index.to_s]['value']
|
||||
if cross_lang_types.include?(rf.markup) || rf.get_data["cross_lang"] == "true"
|
||||
if v.blank?
|
||||
error_messages += "#{rf.title}: #{unfilled_text}\n"
|
||||
end
|
||||
else
|
||||
available_locales.each do |l|
|
||||
if (v[l].blank? rescue true)
|
||||
error_messages += "#{rf.title}(#{available_locales_trans[l]}): #{unfilled_text}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
form_index = form_index +1
|
||||
else
|
||||
field_setting = self.send(field_name)
|
||||
if field_setting && field_setting["required"] == "true" && booking_p[field_name].blank?
|
||||
error_messages += "#{self.custom_text(field_name,"name")}: #{unfilled_text}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
error_messages
|
||||
end
|
||||
def self.time_iterate(start_time, end_time, step, &block)
|
||||
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.first.carousel_image_width : self.custom_carousel_image_width) rescue "75%"
|
||||
end
|
||||
def get_attribute_value(attribute_field, p_hire_id)
|
||||
PHireFieldValue.find_by(p_hire_field_id: attribute_field.id, p_hire_id: p_hire_id)
|
||||
end
|
||||
|
||||
def get_attribute_values(attribute_type=nil)
|
||||
@attribute_values = attribute_type.p_hire_field_values rescue nil
|
||||
end
|
||||
def get_value_from_field_id(field_id,attribute_type=nil)
|
||||
values = get_attribute_values(attribute_type)
|
||||
value = values.detect {|value| value.p_hire_field_id == field_id} rescue nil
|
||||
value ? value : nil
|
||||
end
|
||||
def get_basic_fields
|
||||
basic_fields = self.class::FIELDSNAME
|
||||
basic_fields = basic_fields.select{|f| (self.send(f)["enable"] == "1" rescue true)}
|
||||
end
|
||||
def get_all_fields(get_default=false)
|
||||
@default_field_names = nil if @default_field_names.nil?
|
||||
if get_default
|
||||
if @default_field_names.nil?
|
||||
basic_fields = self.get_basic_fields
|
||||
custom_fields = []
|
||||
self.p_hire_fields_enabled.each do |p_hire_field|
|
||||
unless p_hire_field.disabled
|
||||
custom_fields << "p_hire_fields.#{p_hire_field.id}"
|
||||
end
|
||||
end
|
||||
@default_field_names = basic_fields + custom_fields
|
||||
end
|
||||
return @default_field_names
|
||||
else
|
||||
self.enable_fields_sort ? self.custom_field_names : self.default_field_names
|
||||
end
|
||||
end
|
||||
def can_be_hired_frontend
|
||||
if PropertyHireSetting.first.allow_no_logins_user
|
||||
return true
|
||||
else
|
||||
user = OrbitHelper.current_user
|
||||
return self.can_be_hired || (user && (user.is_admin? || (self.owners && self.owners.include?(user.member_profile_id))))
|
||||
end
|
||||
end
|
||||
def can_be_show_frontend
|
||||
user = OrbitHelper.current_user
|
||||
(!disable_no_logins_view_calendar && self.can_be_hired) || user
|
||||
end
|
||||
def clone_new(clone_mode=false)
|
||||
@records_all = {}
|
||||
if clone_mode
|
||||
clone_target = self.class.find(object.copy_id) rescue nil
|
||||
else
|
||||
clone_target = self
|
||||
end
|
||||
property,clone_target = clone_new_for_object(self,clone_target,clone_mode)
|
||||
property
|
||||
end
|
||||
def fix_uploader(clone_relation, r, f)
|
||||
return r.send(f).blank?
|
||||
if !@clone_mode || (clone_relation[f].blank? && clone_relation.send(f).blank?)
|
||||
clone_relation[f] = r[f]
|
||||
if @clone_mode
|
||||
clone_relation.send(f).retrieve_from_store!(r[f])
|
||||
else
|
||||
org_id = clone_relation.id
|
||||
clone_relation.id = r.id
|
||||
clone_relation.send(f).retrieve_from_store!(r[f])
|
||||
clone_relation.id = org_id
|
||||
end
|
||||
source_filepath = r.send(f).file.file
|
||||
if @clone_mode
|
||||
dest_filepath = clone_relation.send(f).file.file
|
||||
FileUtils.mkdir_p(File.dirname(dest_filepath))
|
||||
FileUtils.cp(source_filepath,dest_filepath)
|
||||
end
|
||||
elsif (clone_relation.send(f).file rescue nil)
|
||||
clone_relation[f] = File.basename(clone_relation.send(f).file.file.to_s)
|
||||
end
|
||||
end
|
||||
def clone_new_for_object(object,clone_target=nil,clone_mode=false,fix_only=false)
|
||||
@except_clone_relations ||= self.except_clone_relations
|
||||
if clone_mode || fix_only
|
||||
new_object = object
|
||||
clone_target = object.class.find(object.copy_id) rescue nil if clone_target.nil?
|
||||
else
|
||||
clone_target = object if clone_target.nil?
|
||||
new_object = object.dup
|
||||
end
|
||||
return if @except_clone_relations.include?(new_object.class.to_s.underscore)
|
||||
@records_all["#{new_object.class.to_s.underscore}_ids"] = {} if @records_all["#{new_object.class.to_s.underscore}_ids"].nil?
|
||||
begin
|
||||
@records_all["#{new_object.class.to_s.underscore}_ids"][clone_target.id] = new_object
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
if !clone_target.nil? && !new_object.nil?
|
||||
unless fix_only
|
||||
if clone_mode
|
||||
initialize_fields = []
|
||||
if new_object.fields.keys.include?("uid")
|
||||
new_object.generate_uid
|
||||
end
|
||||
else
|
||||
initialize_fields = ["uid","created_at","updated_at"]
|
||||
end
|
||||
initialize_fields.each do |f|
|
||||
new_object.send("#{f}=",nil) if new_object.fields.keys.include?(f)
|
||||
end
|
||||
end
|
||||
relations_fields = clone_target.relations.except("impressions").keys
|
||||
all_fields = clone_target.fields.keys - relations_fields
|
||||
all_fields = all_fields - relations_fields.map{|k| "#{k}_id"}
|
||||
all_fields = all_fields - relations_fields.map{|k| "#{k.singularize}_ids"}
|
||||
new_object_class_name = new_object.class.to_s.underscore
|
||||
unless @parent_level
|
||||
unsort_relation_keys = clone_target.relations.keys - ['taggings']
|
||||
fields_to_delete = [new_object_class_name]
|
||||
tmp_relations_fields = [new_object_class_name]
|
||||
while relations_fields.count > 0
|
||||
tmp_singularize_relations_fields = tmp_relations_fields.map{|f| f.singularize}
|
||||
approve_append = nil
|
||||
relations_fields.each do |k|
|
||||
belongs_to_class = clone_target.relations[k].class_name.constantize.relations.select{|k,v| v.macro == :belongs_to}.keys
|
||||
has_many_class = clone_target.relations[k].class_name.constantize.relations.select{|k,v| v.macro.to_s.start_with?('has') }.keys
|
||||
if (belongs_to_class - tmp_singularize_relations_fields).count == 0
|
||||
other_has_many_class = (has_many_class - unsort_relation_keys)
|
||||
if other_has_many_class.count == 0
|
||||
tmp_relations_fields << k
|
||||
else
|
||||
org_k = k.to_s
|
||||
result = other_has_many_class.map do |k|
|
||||
belongs_to_class = k.classify.constantize.relations.select{|kk,v| v.macro == :belongs_to}.keys
|
||||
has_many_class = k.classify.constantize.relations.select{|kk,v| v.macro.to_s.start_with?('has') }.keys
|
||||
if (belongs_to_class - tmp_singularize_relations_fields - [org_k]).count == 0
|
||||
true
|
||||
else
|
||||
fields_to_delete = fields_to_delete.concat(belongs_to_class)
|
||||
tmp_relations_fields.concat(belongs_to_class)
|
||||
false
|
||||
end
|
||||
end
|
||||
if result.select{|t| !t}.count == 0
|
||||
if (fields_to_delete.map{|f| f.pluralize} - tmp_relations_fields).count == 0
|
||||
tmp_relations_fields << k
|
||||
elsif clone_target.relations[k].class_name.constantize.fields.keys.include?("key")
|
||||
tmp_relations_fields << k
|
||||
elsif (clone_target.relations[k].class_name.constantize.relations.keys.map{|f| f.singularize} & fields_to_delete).count != 0
|
||||
approve_append = k
|
||||
end
|
||||
end
|
||||
end
|
||||
elsif !unsort_relation_keys.include?(clone_target.relations[k].class_name.underscore) && !unsort_relation_keys.include?(clone_target.relations[k].class_name.underscore.pluralize)
|
||||
tmp_relations_fields << k
|
||||
end
|
||||
end
|
||||
tmp_relations_fields << approve_append if approve_append.present?
|
||||
approve_append = nil
|
||||
relations_fields = relations_fields - tmp_relations_fields
|
||||
relations_fields -= @relations_fields if @relations_fields
|
||||
end
|
||||
relations_fields = tmp_relations_fields
|
||||
fields_to_delete.each{|f| relations_fields.delete(f)}
|
||||
end
|
||||
if @parent_level
|
||||
relations_fields -= @relations_fields
|
||||
else
|
||||
@clone_mode = clone_mode
|
||||
@relations_fields = relations_fields
|
||||
end
|
||||
@parent_level = true
|
||||
if clone_mode
|
||||
all_fields.each do |f|
|
||||
next if f == "uid"
|
||||
unless new_object.send("#{f}_changed?") && new_object.send("#{f}_changed_from_default?")
|
||||
unless fix_only
|
||||
new_object.send("#{f}=",clone_target.send(f))
|
||||
end
|
||||
if new_object.class.uploaders.include?(f.to_sym)
|
||||
fix_uploader(new_object, clone_target, f)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
all_fields.each do |f|
|
||||
if new_object.class.uploaders.include?(f.to_sym)
|
||||
fix_uploader(new_object, clone_target, f)
|
||||
end
|
||||
end
|
||||
end
|
||||
relations_fields.each do |f|
|
||||
no_dup_flag = false
|
||||
if clone_target.relations[f].macro == :belongs_to || clone_target.relations[f].macro == :has_one
|
||||
no_dup_flag = new_object.send(f).present?
|
||||
elsif clone_target.relations[f].macro == :has_many || clone_target.relations[f].macro == :has_and_belongs_to_many
|
||||
no_dup_flag = new_object.send(f).to_a.count != 0
|
||||
elsif clone_target.relations[f].macro == :embeds_many #Fix localize fields
|
||||
if new_object.send(f).to_a.count != 0
|
||||
need_fix_fields = new_object.send(f).to_a[0].fields.select{|k,v| (v.options[:localize] rescue false)}.keys
|
||||
locale = I18n.locale.to_s
|
||||
embeded_records = new_object.send(f).map do |embeded_record|
|
||||
need_fix_fields.each do |f|
|
||||
if (embeded_record[f][locale].class != String rescue false)
|
||||
embeded_record.send("#{f}_translations=",embeded_record[f][locale])
|
||||
else
|
||||
embeded_record.send("#{f}_translations=",embeded_record[f])
|
||||
end
|
||||
end
|
||||
embeded_record
|
||||
end
|
||||
new_object.send("#{f}=",embeded_records)
|
||||
end
|
||||
end
|
||||
if clone_target.relations[f].macro == :belongs_to || clone_target.relations[f].class_name == "MemberProfile"
|
||||
if f == 'taggable'
|
||||
map_f = @taggable_name
|
||||
else
|
||||
map_f = f
|
||||
end
|
||||
if @records_all["#{map_f}_ids"].nil?
|
||||
new_object.send("#{f}_id=",clone_target.send("#{f}_id"))
|
||||
else
|
||||
obj = @records_all["#{map_f}_ids"][clone_target.send("#{f}_id")]
|
||||
if obj
|
||||
new_object.send("#{f}_id=", obj.id)
|
||||
new_object.send("#{f}=", obj)
|
||||
end
|
||||
end
|
||||
elsif clone_target.relations[f].macro == :has_one
|
||||
next if @except_clone_relations.include?(f)
|
||||
need_clone_relation = clone_target.send(f)
|
||||
next if need_clone_relation.nil?
|
||||
clone_relation = new_object.send(f)
|
||||
if clone_relation.nil?
|
||||
clone_relation, need_clone_relation = clone_new_for_object(need_clone_relation.dup, need_clone_relation, clone_mode, fix_only)
|
||||
else
|
||||
clone_relation, r = clone_new_for_object(clone_relation, r, clone_mode, true)
|
||||
end
|
||||
new_object.send("#{f}=",clone_relation)
|
||||
elsif clone_target.relations[f].macro == :has_many || clone_target.relations[f].macro == :has_and_belongs_to_many
|
||||
next if @except_clone_relations.include?(f)
|
||||
clone_relations = []
|
||||
need_clone_relations = clone_target.send(f).asc(:_id).to_a
|
||||
file_flag = false
|
||||
if f == 'taggings'
|
||||
@taggable_name = new_object.class.to_s.underscore
|
||||
end
|
||||
need_clone_relations.each_with_index do |r,i|
|
||||
clone_relation = new_object.send(f)[i]
|
||||
if clone_relation.nil?
|
||||
clone_relation, r = clone_new_for_object(r.dup, r, clone_mode, fix_only)
|
||||
else
|
||||
clone_relation, r = clone_new_for_object(clone_relation, r, clone_mode, true)
|
||||
end
|
||||
clone_relations << clone_relation
|
||||
end
|
||||
if !no_dup_flag || (no_dup_flag && file_flag)
|
||||
new_object_relations = new_object.send(f).to_a
|
||||
new_object_relations_count = new_object_relations.count
|
||||
if new_object_relations_count != 0
|
||||
if clone_relations.count > new_object_relations_count
|
||||
clone_relations = clone_relations[0...new_object_relations_count]
|
||||
else
|
||||
clone_relations = clone_relations.concat(new_object.send(f)[clone_relations.count...new_object_relations_count])
|
||||
end
|
||||
new_object.send("#{f}=",clone_relations)
|
||||
else
|
||||
new_object.send("#{f}=",clone_relations)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
new_object.copy_id = clone_target.id if new_object.fields.keys.include?("copy_id")
|
||||
return new_object, clone_target
|
||||
end
|
||||
end
|
||||
def get_owner_emails
|
||||
emails = []
|
||||
case self.owner_email_rule
|
||||
when 0
|
||||
emails = MemberProfile.where(:id.in=> self.owners.to_a).pluck(:email)
|
||||
when 1
|
||||
emails = [self.owner_email]
|
||||
when 2
|
||||
emails = MemberProfile.where(:id.in=> self.owners.to_a).pluck(:email) + [self.owner_email]
|
||||
end
|
||||
emails.select{|email| email.present?}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# encoding: utf-8
|
||||
class PropertyCarouselImage
|
||||
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
mount_uploader :file, AssetUploader
|
||||
|
||||
field :description, localize: true
|
||||
|
||||
belongs_to :property
|
||||
def description_text
|
||||
Nokogiri::HTML(self.description.to_s).css("body").text() rescue ""
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
class PropertyDaySetting
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
field :enable, type: Boolean, default: true
|
||||
field :key
|
||||
field :day
|
||||
field :title
|
||||
field :start_time
|
||||
field :end_time
|
||||
field :reservation_limit, type: Integer, default: 1
|
||||
belongs_to :property
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class PropertyFieldSet
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
field :field_name, type: String
|
||||
field :placeholder
|
||||
field :name
|
||||
field :disabled, type: Boolean, default: false
|
||||
field :hidden, type: Boolean, default: false
|
||||
belongs_to :property
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
# encoding: utf-8
|
||||
class PropertyFile
|
||||
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
mount_uploader :file, AssetUploader
|
||||
|
||||
field :description, :type => String, :default=> ""
|
||||
field :title, :type => String, :default=> ""
|
||||
belongs_to :property
|
||||
end
|
|
@ -3,8 +3,19 @@ class PropertyHireSetting
|
|||
include Mongoid::Timestamps
|
||||
|
||||
field :auto_approve, type: Boolean, :default => false
|
||||
|
||||
field :carousel_image_width, type: String, :default => "75%"
|
||||
field :disable_content_page, type: Boolean, :default => false
|
||||
field :disable_view_calendar_page, type: Boolean, :default => false
|
||||
field :disable_no_logins_view_calendar, type: Boolean, :default => false
|
||||
field :allow_no_logins_user, type: Boolean, :default => false
|
||||
field :calendar_type, type: Integer, default: 0 # 0=> 顯示, 1=> 不顯示
|
||||
def self.auto_approve_enabled?
|
||||
self.first.auto_approve
|
||||
self.first.auto_approve rescue false
|
||||
end
|
||||
after_save do
|
||||
Property.init_class_variables
|
||||
end
|
||||
def default_time_settings
|
||||
PropertyDaySetting.where(:property_id=>"default_settings").asc(:key)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
# encoding: utf-8
|
||||
require 'uri'
|
||||
|
||||
class PropertyLink
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
field :url, :type => String, :default=> ""
|
||||
field :title, :type => String, :default=> ""
|
||||
|
||||
before_validation :add_http
|
||||
belongs_to :property
|
||||
|
||||
def display_title
|
||||
self.title.blank? ? self.url : self.title
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def add_http
|
||||
unless self.url[/^http:\/\//] || self.url[/^https:\/\//]
|
||||
self.url = 'http://' + self.url
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,146 @@
|
|||
<div class="attributes default <%= attribute_field.disabled ? 'disabled' : ''%>">
|
||||
<%
|
||||
attribute_field.af_count ? @af_counter = attribute_field_counter + attribute_field.af_count : @af_counter = attribute_field_counter
|
||||
%>
|
||||
<div class="attributes-header clearfix">
|
||||
<div class="toggle-control" style="float: right;">
|
||||
<div class="togglebox <%= attribute_field.disabled ? 'disabled' : ''%>">
|
||||
<%= hidden_field "#{@field_name}[p_hire_fields][#{@af_counter}]","disabled",:value=>attribute_field.disabled,:class=>"toggle-check", :data=>{:deploy=>"right"} %>
|
||||
<label><b></b></label>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-mini pull-right btn-danger delete" href="#"><i class="icon-trash"></i> <%= t(:delete_)%></a>
|
||||
<%= hidden_field "#{@field_name}[p_hire_fields][#{@af_counter}]","to_delete",:value=>false,:class=>"attribute_field_to_delete"%>
|
||||
<a class="btn btn-mini pull-right btn-inverse reply hide" href="#"><i class="icons-reply"></i> Reset</a>
|
||||
<h4>Field <span><%= @af_counter + 1 %></span></h4>
|
||||
</div>
|
||||
<div class="attributes-body">
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="key_<%= @af_counter %>"><%= t(:key) %></label>
|
||||
<div class="controls">
|
||||
<%= text_field "#{@field_name}[p_hire_fields][#{@af_counter}]","key",:value=>attribute_field.key, :data=>{:type=>"key"} %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render :partial=>"shared/attribute_field/placeholder_block",:locals=>{:values=>attribute_field.title_translations,:class_ext=>"pull-left",:label_ext=>t(:name),:field_name=>"#{@field_name}[p_hire_fields][#{@af_counter}][title_translations]"}%>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t('property_hire.to_require') %></label>
|
||||
<div class="controls">
|
||||
<label class="radio inline">
|
||||
<%= radio_button("#{@field_name}[p_hire_fields][#{@af_counter}]", "to_require", "true",:checked => (attribute_field.to_require == true ? true : false), :data=>{:type=>"search_true"}) %><%= t(:yes_)%>
|
||||
</label>
|
||||
<label class="radio inline">
|
||||
<%= radio_button("#{@field_name}[p_hire_fields][#{@af_counter}]", "to_require", "false",:checked => (attribute_field.to_require == false ? true : false), :data=>{:type=>"search_false"}) %><%= t(:no_)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t('property_hire.display_in_reason_for_hire') %></label>
|
||||
<div class="controls">
|
||||
<label class="radio inline">
|
||||
<%= radio_button("#{@field_name}[p_hire_fields][#{@af_counter}]", "display_in_reason_for_hire", "true",:checked => (attribute_field.display_in_reason_for_hire == true ? true : false), :data=>{:type=>"search_true"}) %><%= t(:yes_)%>
|
||||
</label>
|
||||
<label class="radio inline">
|
||||
<%= radio_button("#{@field_name}[p_hire_fields][#{@af_counter}]", "display_in_reason_for_hire", "false",:checked => (attribute_field.display_in_reason_for_hire == false ? true : false), :data=>{:type=>"search_false"}) %><%= t(:no_)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t(:type)%></label>
|
||||
<div class="controls">
|
||||
<select class="dataType" data-type="select" name=<%= "#{@field_name}[p_hire_fields][#{@af_counter}][markup]"%>>
|
||||
<%$property_list[:markups].each do |key,val|%>
|
||||
<% next if val["display_only"] && val["display_only"] != "p_hire_field" %>
|
||||
<% if key != 'address' %>
|
||||
<option value="<%= key %>" <%= attribute_field.markup == key ? 'selected="selected"' : '' %> ref="<%=val["panel"]%>"><%=t("lists.markups."+key)%></option >
|
||||
<% end %>
|
||||
<% end %>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-type fade"></div>
|
||||
|
||||
<%= content_tag :div,:class=>"field-type default fade in #{show_property_type_panel(attribute_field,"typeA")}" do%>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t(:enabled_for)%></label>
|
||||
<div class="controls">
|
||||
<label class="checkbox inline">
|
||||
<%= check_box_tag("#{@field_name}[p_hire_fields][#{@af_counter}][typeA][cross_lang]","true",attribute_field["typeA"]["cross_lang"],:data=>{:type=>"cross_lang"}) %>
|
||||
<%= t(:cross_lang) %>
|
||||
</label>
|
||||
<label class="checkbox inline">
|
||||
<%= check_box_tag("#{@field_name}[p_hire_fields][#{@af_counter}][typeA][add_more]","true",attribute_field["typeA"]["add_more"],:data=>{:type=>"add_more"}) %>
|
||||
<%= t(:add_more)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<%= render :partial=>"shared/attribute_field/placeholder_block",:locals=>{:values=>attribute_field["typeA"]["placeholder"],:field_name=>"#{@field_name}[p_hire_fields][#{@af_counter}][typeA][placeholder]"}%>
|
||||
<% end if show_property_type_panel(attribute_field,"typeA") != 'typeA hide' %>
|
||||
|
||||
<%= content_tag :div,:class=>"field-type default fade in #{show_property_type_panel(attribute_field,"typeB")}" do %>
|
||||
<%= render :partial=>"shared/attribute_field/placeholder_block",:locals=>{:label_ext=>t(:initial),:values=>attribute_field["typeB"]["initial"],:field_name=>"#{@field_name}[p_hire_fields][#{@af_counter}][typeB][initial]"}%>
|
||||
|
||||
<% if attribute_field.self_defined_markup_options?%>
|
||||
<%= render :partial=>"shared/attribute_field/list_block",:locals=>{:values=>attribute_field["option_list"],:field_name=> "#{@field_name}[p_hire_fields][#{@af_counter}][attribute][property][statuses]"} %>
|
||||
<%else #normal list%>
|
||||
<%= render :partial=>"shared/attribute_field/list_block",:locals=>{:values=>attribute_field["option_list"],:field_name=> "#{@field_name}[p_hire_fields][#{@af_counter}][typeB][option_list]"} %>
|
||||
<% end #of self_defined_markup_options?%>
|
||||
|
||||
<% end if show_property_type_panel(attribute_field,"typeB") != 'typeB hide' %>
|
||||
|
||||
<%= content_tag :div,:class=>"field-type default fade in #{show_property_type_panel(attribute_field,"typeC")}" do %>
|
||||
<div class="control-group">
|
||||
<label class="control-label"><%= t("date.format")%></label>
|
||||
<div class="controls">
|
||||
<%= select "#{@field_name}[p_hire_fields][#{@af_counter}][typeC]","format",Admin::AttributeValuesViewHelper::OPT,:class=>"dataType",:selected=>attribute_field["typeC"]["format"] %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label"><%= t("date.range")%></label>
|
||||
<div class="controls">
|
||||
<label class="radio inline">
|
||||
<%= radio_button("#{@field_name}[p_hire_fields][#{@af_counter}][typeC]", "is_range", "false",:checked => (!attribute_field.date_is_range? ? true : false)) %><%= t(:yes_)%>
|
||||
</label>
|
||||
<label class="radio inline">
|
||||
<%= radio_button("#{@field_name}[p_hire_fields][#{@af_counter}][typeC]", "is_range", "true",:checked => (attribute_field.date_is_range? ? true : false)) %><%= t(:no_)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label"><%= t("date.calendar")%></label>
|
||||
<div class="controls">
|
||||
<label class="radio inline">
|
||||
<%= radio_button("#{@field_name}[p_hire_fields][#{@af_counter}][typeC]", "calendar", "west_calendar",:checked =>(attribute_field["typeC"]["calendar"]== "west_calendar" ? true : false)) %><%= t("date.west_calendar")%>
|
||||
</label>
|
||||
<label class="radio inline">
|
||||
<%= radio_button("#{@field_name}[p_hire_fields][#{@af_counter}][typeC]", "calendar", "tw_calendar",:checked =>(attribute_field["typeC"]["calendar"]== "tw_calendar" ? true : false)) %><%= t("date.tw_calendar")%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<% end if show_property_type_panel(attribute_field,"typeC") != 'typeC hide' %>
|
||||
|
||||
<%= content_tag :div,:class=>"field-type default fade in #{show_property_type_panel(attribute_field,"typeD")}" do%>
|
||||
<div class="control-group">
|
||||
<label class="control-label"><%= t(:enabled_for)%></label>
|
||||
<div class="controls">
|
||||
<label class="checkbox inline">
|
||||
<%= check_box_tag("#{@field_name}[p_hire_fields][#{@af_counter}][typeD][cross_lang]","true",attribute_field["typeD"]["cross_lang"]) %>
|
||||
<%= t(:cross_lang)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<%= render :partial=>"shared/attribute_field/placeholder_block",:locals=>{:field_name=>"#{@field_name}[p_hire_fields][#{@af_counter}][typeD][placeholder]",:values=>attribute_field["typeD"]["placeholder"]} %>
|
||||
<% end if show_property_type_panel(attribute_field,"typeD") != 'typeD hide' %>
|
||||
|
||||
<%= content_tag :div,:class=>"field-type default fade in #{show_property_type_panel(attribute_field,"typeE")}" do%>
|
||||
<%= render :partial=>"shared/attribute_field/list_block",:locals=>{:field_name=>"#{@field_name}[p_hire_fields][#{@af_counter}][typeE][option_list]",:values=>attribute_field["typeE"]["option_list"]}%>
|
||||
<% end if show_property_type_panel(attribute_field,"typeE") != 'typeE hide' %>
|
||||
<%= content_tag :div,:class=>"field-type default fade in #{show_property_type_panel(attribute_field,"typeF")}" do%>
|
||||
<%= render :partial=>"shared/attribute_field/hint_block",:locals=>{:values=>attribute_field["typeF"]["placeholder"],:field_name=>"#{@field_name}[p_hire_fields][#{@af_counter}][typeF][placeholder]"}%>
|
||||
<% end if show_property_type_panel(attribute_field,"typeF") != 'typeF hide' %>
|
||||
<%= hidden_field "#{@field_name}[p_hire_fields][#{@af_counter}]","id",:value=>attribute_field.id%>
|
||||
|
||||
</div>
|
|
@ -1,7 +1,75 @@
|
|||
<%
|
||||
hire_method = Admin::PropertyHiresHelper::HireMethod
|
||||
hire_method.set_input_name('property')
|
||||
with_id = !(@property.new_record?)
|
||||
%>
|
||||
<style type="text/css">
|
||||
.tab-panel > .tab-content{
|
||||
display: none;
|
||||
}
|
||||
.tab-panel > .tab-content.active{
|
||||
display: block;
|
||||
}
|
||||
.tab-panel{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.label_left{
|
||||
float: left;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
.select_field_block{
|
||||
border: 0.2em solid #666;
|
||||
padding: 1em;
|
||||
}
|
||||
.remove_btn:hover{
|
||||
font-size: 1.3em;
|
||||
}
|
||||
.remove_btn{
|
||||
cursor: pointer;
|
||||
}
|
||||
.card-header a{
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
.card-header:hover{
|
||||
background: aquamarine;
|
||||
}
|
||||
.card-header:hover a{
|
||||
text-decoration: none;
|
||||
}
|
||||
.add_weekday_setting{
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
}
|
||||
.time_setting_form, .image_group{
|
||||
border: 0.2em solid #333;
|
||||
padding-top: 0;
|
||||
}
|
||||
.add-on.iconbtn{
|
||||
display: none;
|
||||
}
|
||||
.time_setting_form:last-child, .image_group:last-child {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.card-header {
|
||||
padding: 0;
|
||||
}
|
||||
.card-header a {
|
||||
padding: .75rem 1.25rem;
|
||||
}
|
||||
.card-header h4 {
|
||||
margin: 0;
|
||||
}
|
||||
.apply_default_time_settings{
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
||||
<% content_for :page_specific_css do %>
|
||||
<%= stylesheet_link_tag "lib/main-forms" %>
|
||||
<%= stylesheet_link_tag "lib/fileupload" %>
|
||||
<%= stylesheet_link_tag "lib/main-list" %>
|
||||
<%= stylesheet_link_tag "admin/card" %>
|
||||
<% end %>
|
||||
<% content_for :page_specific_javascript do %>
|
||||
<%= javascript_include_tag "lib/bootstrap-fileupload" %>
|
||||
|
@ -18,9 +86,15 @@
|
|||
<div class="nav-name"><strong><%= t(:module) %></strong></div>
|
||||
<ul class="nav nav-pills module-nav">
|
||||
<li class="active"><a href="#basic" data-toggle="tab"><%= t(:basic) %></a></li>
|
||||
<li><a href="#page_setting" data-toggle="tab"><%= t("property_hire.page_setting") %></a></li>
|
||||
<li><a href="#files_links" data-toggle="tab"><%= t("property_hire.files_links") %></a></li>
|
||||
<li><a href="#tag" data-toggle="tab"><%= t(:tags) %></a></li>
|
||||
<li><a href="#imageupload" data-toggle="tab"><%= t(:image) %></a></li>
|
||||
<li><a href="#unavailability" data-toggle="tab"><%= t('property_hire.unavailability')%></a></li>
|
||||
<li><a href="#carousel_image_upload" data-toggle="tab" title="<%= t('property_hire.carousel_image_title') %>"><%= t('property_hire.carousel_image') %></a></li>
|
||||
<li><a href="#unavailability" data-toggle="tab"><%= t('property_hire.unavailable_time')%></a></li>
|
||||
<li><a href="#available_time" data-toggle="tab"><%= t('property_hire.available_time')%></a></li>
|
||||
<li><a href="#auto_send_email_set" data-toggle="tab"><%= t('property_hire.auto_send_email_set') %></a></li>
|
||||
<li><a href="#settings" data-toggle="tab"><%= t('property_hire.reservation_fields') %></a></li>
|
||||
</ul>
|
||||
<!-- Module -->
|
||||
<div class="tab-content module-area">
|
||||
|
@ -51,24 +125,73 @@
|
|||
<%= f.text_field :other_location %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
=begin%>
|
||||
<div class="control-group">
|
||||
<%= f.label :property_number, t("property_hire.property_number"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.text_field :property_number %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
=end%>
|
||||
<div class="control-group">
|
||||
<%= f.label :can_be_hired, t("property_hire.can_be_hired"), :class => "control-label muted" %>
|
||||
<%= f.label :p_display_start_time, t("property_hire.p_display_start_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :can_be_hired %>
|
||||
<%= f.datetime_picker :p_display_start_time, :picker_type => "date", :no_label => true, :new_record => @property.new_record?, :data=>{"picker-type" => "range", "range" => "start"}, :format => "yyyy/MM/dd hh:mm" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :p_display_end_time, t("property_hire.p_display_end_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :p_display_end_time, :picker_type => "date", :no_label => true, :new_record => @property.new_record?, :data=>{"picker-type" => "range", "range" => "end"}, :format => "yyyy/MM/dd hh:mm" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<%= f.label :p_hire_start_time, t("property_hire.p_hire_start_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<div class="muted"><%= t("property_hire.time_period_note") %></div>
|
||||
<%= f.datetime_picker :p_hire_start_time, :picker_type => "date", :no_label => true, :new_record => @property.new_record?, :data=>{"picker-type" => "range", "range" => "start"}, :format => "yyyy/MM/dd hh:mm" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :p_hire_end_time, t("property_hire.p_hire_end_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :p_hire_end_time, :picker_type => "date", :no_label => true, :new_record => @property.new_record?, :data=>{"picker-type" => "range", "range" => "end"}, :format => "yyyy/MM/dd hh:mm" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :recurring_enable, t("property_hire.recurring_enable"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :recurring_enable %>
|
||||
</div>
|
||||
</div>
|
||||
<div id="open-time" >
|
||||
<div class="control-group">
|
||||
<%= f.label :p_open_start_time, t("property_hire.p_open_start_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<div class="muted"><%= t("property_hire.available_time_note") %></div>
|
||||
<%= f.datetime_picker :p_open_start_time, :picker_type => "date", :no_label => true, :new_record => @property.new_record?, :data=>{"picker-type" => "range", "range" => "start"}, :format => "yyyy/MM/dd" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :p_open_end_time, t("property_hire.p_open_end_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :p_open_end_time, :picker_type => "date", :no_label => true, :new_record => @property.new_record?, :data=>{"picker-type" => "range", "range" => "end"}, :format => "yyyy/MM/dd" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
=begin%>
|
||||
<div class="control-group">
|
||||
<%= f.label :purchase_date, t("property_hire.purchase_date"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :purchase_date, :no_label => true, :new_record => @property.new_record?, :picker_type => "date", :format => "yyyy/MM/dd" %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
=end%>
|
||||
<div class="control-group">
|
||||
<%= f.label :owners, t("property_hire.owners"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
|
@ -87,18 +210,41 @@
|
|||
<%= f.text_field :owner_email %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :owner_email_rule, t("property_hire.owner_email_rule"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.select :owner_email_rule, options_for_select([0,1,2].map{|i| [t("property_hire.owner_email_rules.#{i}"), i]}, f.object.owner_email_rule) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :owner_phone, t("property_hire.owner_phone"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.text_field :owner_phone %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
=begin%>
|
||||
<div class="control-group">
|
||||
<%= f.label :price, t("property_hire.price"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.text_field :price %>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
=end%>
|
||||
</div>
|
||||
<!-- page_setting -->
|
||||
<div class="tab-pane fade" id="page_setting">
|
||||
<div class="control-group">
|
||||
<%= f.label :custom_calendar_type, t("property_hire.display_calendar"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.select :custom_calendar_type, options_for_select(Property::CAlENDARTYPE.map.with_index{|type,i| [t("property_hire.custom_calendar_type.#{type}"), i]}, f.object.custom_calendar_type) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- files_links -->
|
||||
<div class="tab-pane fade" id="files_links">
|
||||
<%= render :partial => "form_file_link", :locals=>{:f=>f} %>
|
||||
</div>
|
||||
<!-- tags -->
|
||||
<div class="tab-pane fade" id="tag">
|
||||
|
@ -118,7 +264,7 @@
|
|||
<% if @property.image.file %>
|
||||
<%= image_tag @property.image %>
|
||||
<% else %>
|
||||
<img src="http://www.placehold.it/50x50/EFEFEF/AAAAAA" />
|
||||
<img src="/assets/property_hire/AAAAAA.png" />
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="fileupload-preview fileupload-exists thumbnail pull-left"></div>
|
||||
|
@ -136,8 +282,116 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- display img src -->
|
||||
<div class="control-group">
|
||||
<%= f.label :display_img, t("property_hire.display_img"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :display_img %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Image display setting -->
|
||||
<% image_display_class_relation = {"full_width"=>"full-size-img","up_left_corner"=>"pull-left","up_right_corner"=>"pull-right"} %>
|
||||
<div class="control-group <%='hide' if !f.object.display_img %>" id="image_display_setting">
|
||||
<%= f.label :image_display_class, t("property_hire.cover_image_display_setting"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<% image_display_class_relation.each.with_index do |(key,value),i| %>
|
||||
<label>
|
||||
<%= radio_button_tag "#{f.object_name}[image_display_class]", value , (f.object.image_display_class == value) %>
|
||||
<%= t("property_hire.#{key}") %>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Images Module -->
|
||||
<div class="tab-pane fade" id="carousel_image_upload">
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="carousel_image_width"><%= t("property_hire.carousel_image_width") %></label>
|
||||
<div class="controls">
|
||||
<%= f.text_field :custom_carousel_image_width, :placeholder => t("property_hire.custom_carousel_image_width_hint") %>
|
||||
</div>
|
||||
</div>
|
||||
<% if f.object && !f.object.property_carousel_images.blank? %>
|
||||
<div class="exist">
|
||||
<% f.object.property_carousel_images.each_with_index do |property_carousel_image, i| %>
|
||||
<%= f.fields_for :property_carousel_images, property_carousel_image do |f| %>
|
||||
<%= render :partial => 'form_image', :object => property_carousel_image, :locals => {:f => f, :i => i} %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<hr>
|
||||
</div>
|
||||
<% end %>
|
||||
<!-- Add -->
|
||||
<div class="add-target">
|
||||
</div>
|
||||
<p class="add-btn controls">
|
||||
<%= hidden_field_tag 'property_carousel_image_count', f.object.property_carousel_images.count %>
|
||||
<a id="add_carousel_image" class="trigger btn btn-small btn-primary"><i class="icons-plus"></i> <%= t(:add) %></a>
|
||||
</p>
|
||||
</div>
|
||||
<!-- Email Set Module -->
|
||||
<div class="tab-pane fade" id="auto_send_email_set" style="padding: 1.2em;">
|
||||
<ul class="nav nav-pills module-nav">
|
||||
<li class="active">
|
||||
<a href="#email_set0" data-toggle="tab">
|
||||
<%= t('property_hire.hire') %>
|
||||
</a>
|
||||
</li>
|
||||
<li class="">
|
||||
<a href="#email_set1" data-toggle="tab">
|
||||
<%= t('property_hire.edit') %>
|
||||
</a>
|
||||
</li>
|
||||
<li class="">
|
||||
<a href="#email_set2" data-toggle="tab">
|
||||
<%= t('property_hire.delete') %>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<% (0..2).each do |index1| %>
|
||||
<% active_email_set = index1==0 ? ' active' : '' %>
|
||||
<div class="tab-pane<%= active_email_set %>" id="email_set<%= index1 %>" style="padding: 1.2em;">
|
||||
<table style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<%= t('disable') %>
|
||||
</td>
|
||||
<td>
|
||||
<input type="hidden" class="field_set" name='<%= "property[hire_email_sets][#{index1}][disabled]" %>' value="false">
|
||||
<%= check_box_tag("property[hire_email_sets][#{index1}][disabled]", true ,@email_set[index1].disabled) %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<%= t('property_hire.email_title') %>
|
||||
</td>
|
||||
<td>
|
||||
<%= hire_method.show_set_field(@email_set[index1].id,@email_set[index1]['title'],'hire_email_sets',index1,'title','text_field',with_id) %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<%= t('property_hire.email_content') %>
|
||||
</td>
|
||||
<td>
|
||||
<div class="form-group">
|
||||
<%= hire_method.show_set_field(@email_set[index1].id,@email_set[index1]['content'],'hire_email_sets',index1,'content','text_area',with_id) %>
|
||||
</div>
|
||||
<%= hidden_field_tag("property[hire_email_sets][#{index1}][field_name]",@email_set[index1]['field_name']) %>
|
||||
<% unless @property.new_record? %>
|
||||
<%= hidden_field_tag("property[hire_email_sets][#{index1}][property_id]",@property.id) %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<!-- unavailability -->
|
||||
<div class="tab-pane fade" id="unavailability">
|
||||
<div class="control-group">
|
||||
|
@ -146,50 +400,72 @@
|
|||
<%= f.check_box :set_unavailibility %>
|
||||
</div>
|
||||
</div>
|
||||
<% if @property.new_record? %>
|
||||
<div id="set_unavailibility_div" style="display: none;">
|
||||
<% elsif @property.set_unavailibility %>
|
||||
<% if @property.set_unavailibility %>
|
||||
<div id="set_unavailibility_div">
|
||||
<% else %>
|
||||
<div id="set_unavailibility_div" style="display: none;">
|
||||
<% end %>
|
||||
|
||||
<div class="control-group">
|
||||
<%= f.label :start_time, t("property_hire.start_time"), :class => "control-label muted" %>
|
||||
<%= f.label :can_hire_before_months, t("property_hire.how_many_months_ago_can_be_hired"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :start_time, :picker_type => "time", :no_label => true, :new_record => @property.new_record?, :value => (Time.parse(@property.start_time) rescue "") %>
|
||||
<%= f.select :can_hire_before_months, options_for_select([[t("property_hire.no_limit"),0]] + (1..12).to_a.map{|month| [t("property_hire.month", month: month), month]},f.object.can_hire_before_months) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :end_time, t("property_hire.end_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :end_time, :picker_type => "time", :no_label => true, :new_record => @property.new_record?, :value => (Time.parse(@property.end_time) rescue "") %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted">Weekdays</label>
|
||||
<label class="control-label muted"><%=t("property_hire.weekdays").html_safe%></label>
|
||||
<div class="controls">
|
||||
<% weekdays = @property.weekdays rescue [] %>
|
||||
<label for="sunday">
|
||||
<input id="sunday" type="checkbox" name="property[weekdays][]" value="0" <%= weekdays.include?("0") ? "checked=checked" : "" %> /> Sunday
|
||||
</label>
|
||||
<label for="monday">
|
||||
<input id="monday" type="checkbox" name="property[weekdays][]" value="1" <%= weekdays.include?("1") ? "checked=checked" : "" %> /> Monday
|
||||
</label>
|
||||
<label for="tuesday">
|
||||
<input id="tuesday" type="checkbox" name="property[weekdays][]" value="2" <%= weekdays.include?("2") ? "checked=checked" : "" %> /> Tuesday
|
||||
</label>
|
||||
<label for="wednesday">
|
||||
<input id="wednesday" type="checkbox" name="property[weekdays][]" value="3" <%= weekdays.include?("3") ? "checked=checked" : "" %> /> Wednesday
|
||||
</label>
|
||||
<label for="thursday">
|
||||
<input id="thursday" type="checkbox" name="property[weekdays][]" value="4" <%= weekdays.include?("4") ? "checked=checked" : "" %> /> Thursday
|
||||
</label>
|
||||
<label for="friday">
|
||||
<input id="friday" type="checkbox" name="property[weekdays][]" value="5" <%= weekdays.include?("5") ? "checked=checked" : "" %> /> Friday
|
||||
</label>
|
||||
<label for="saturday">
|
||||
<input id="saturday" type="checkbox" name="property[weekdays][]" value="6" <%= weekdays.include?("6") ? "checked=checked" : "" %> /> Saturday
|
||||
<% Property::WEEKDAYS.each_with_index do |weekday,i| %>
|
||||
<label for="<%=weekday%>">
|
||||
<input id="<%=weekday%>" type="checkbox" name="property[weekdays][]" value="<%=i%>" <%= weekdays.include?(i.to_s) ? "checked=checked" : "" %> /> <% trans = t("property_hire.#{weekday}") %><%= (trans.class == ActiveSupport::SafeBuffer ? weekday : trans) %>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%=t("property_hire.special_unavailable_date")%></label>
|
||||
<div class="controls" id="special_unavailable_date_holder">
|
||||
<% @property.special_unavailable_dates.each_with_index do |dt, idx| %>
|
||||
<div class="temp_date_holder" style="margin-bottom:5px;">
|
||||
<div class="date_picker input-append" style="margin-bottom:3px;">
|
||||
<input placeholder="yyyy/MM/dd" class="input-large" data-format="yyyy/MM/dd" type="text" name="property[special_unavailable_dates][]" title="yyyy/MM/dd" autocomplete="off" value="<%= dt %>">
|
||||
<span class="add-on clearDate"><i class="icons-cross-3"></i></span>
|
||||
<span class="add-on deleteDate"><i class="icon-trash"></i></span>
|
||||
</div>
|
||||
<div class="tab-panel">
|
||||
<div class="tab-content active" id="special_unavailable_title_<%= idx %>_en">
|
||||
<input type="text" name="property[special_unavailable_dates_title][][en]" value="<%= @property.special_unavailable_dates_title[idx]["en"] %>">
|
||||
</div>
|
||||
<div class="tab-content" id="special_unavailable_title_<%= idx %>_zh_tw">
|
||||
<input type="text" name="property[special_unavailable_dates_title][][zh_tw]" value="<%= @property.special_unavailable_dates_title[idx]["zh_tw"] %>">
|
||||
</div>
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
<a data-toggle="tab" class="btn active" for="en" href="#special_unavailable_title_<%= idx %>_en" aria-expanded="true" aria-pressed="true"><%= t("en") %></a>
|
||||
<a data-toggle="tab" class="btn" for="zh_tw" href="#special_unavailable_title_<%= idx %>_zh_tw" aria-expanded="true" aria-pressed="true"><%= t("zh_tw") %></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<button class="primary" id="add_special_unavailable_date">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :need_hire_before, t("property_hire.need_hire_before"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<% units = ['month', 'day', 'hour', 'minute'] %>
|
||||
<%= f.number_field :need_hire_before, :min=>0 %>
|
||||
<%= f.select :need_hire_before_unit, options_for_select(units.map{|unit| [t("property_hire._#{unit}"), unit]},f.object.need_hire_before_unit) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%=t("property_hire.hours_restriction") %></label>
|
||||
<div class="controls">
|
||||
<% units = ['week', 'month'] %>
|
||||
<%= f.number_field :hours_restriction, :min=>0, :max=>24 %>
|
||||
<%= f.select :hours_restriction_duration, options_for_select(units.map{|unit| [t("property_hire._#{unit}"), unit]},f.object.need_hire_before_unit) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
@ -204,6 +480,18 @@
|
|||
<%= f.datetime_picker :end_date, :picker_type => "date", :no_label => true, :new_record => @property.new_record?, :data=>{"picker-type" => "range", "range" => "end"}, :format => "yyyy/MM/dd" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :start_time, t("property_hire.limit_start_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :start_time, :picker_type => "time", :no_label => true, :new_record => @property.new_record?, :value => (Time.parse(@property.start_time) rescue "") %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :end_time, t("property_hire.limit_end_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :end_time, :picker_type => "time", :no_label => true, :new_record => @property.new_record?, :value => (Time.parse(@property.end_time) rescue "") %>
|
||||
</div>
|
||||
</div>
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<%= f.fields_for :description_translations do |f| %>
|
||||
<div class="control-group">
|
||||
|
@ -215,7 +503,7 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<%= f.fields_for :unavailibility_note do |f| %>
|
||||
<%= f.fields_for :unavailibility_note_translations do |f| %>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="note_<%= locale.to_s %>"><%= t(:note) + " (#{t(locale.to_s)})" %></label>
|
||||
<div class="controls">
|
||||
|
@ -226,6 +514,164 @@
|
|||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<!-- available_time -->
|
||||
<div class="tab-pane fade" id="available_time">
|
||||
<div class="control-group">
|
||||
<%= f.label :set_availability, t("property_hire.set_availability"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :set_availability %>
|
||||
</div>
|
||||
</div>
|
||||
<% if @property.set_availability %>
|
||||
<div id="set_availability_div">
|
||||
<% else %>
|
||||
<div id="set_availability_div" style="display: none;">
|
||||
<% end %>
|
||||
<ul>
|
||||
<% all_day_settings = f.object.all_day_settings %>
|
||||
<% setting_count = 0 %>
|
||||
<% Property::WEEKDAYS.each_with_index do |weekday,i| %>
|
||||
<li class="card">
|
||||
<div class="card-header">
|
||||
<h4>
|
||||
<a data-toggle="collapse" href="#<%=weekday%>_setting" role="button" aria-expanded="false" aria-controls="<%=weekday%>_setting"><% trans = t("property_hire.#{weekday}") %><%= (trans.class == ActiveSupport::SafeBuffer ? weekday : trans) %></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="collapse" id="<%=weekday%>_setting">
|
||||
<div class="card card-body">
|
||||
<div>
|
||||
<button type="button" class="btn btn-primary apply_default_time_settings pull-right" data-target="#add_target_weekday_<%=i%>" data-count="0" data-day="<%=i%>"><%=t("property_hire.apply_default_time_settings")%></button>
|
||||
</div>
|
||||
<div id="add_target_weekday_<%=i%>">
|
||||
<% if all_day_settings[i.to_s] %>
|
||||
<% all_day_settings[i.to_s].each_with_index do |setting,j| %>
|
||||
<%= f.fields_for :property_day_settings, setting,:child_index => setting_count do |f| %>
|
||||
<%= render :partial => "time_form", :locals=>{:key=>j,:day=>i,:f=>f} %>
|
||||
<% setting_count += 1 %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<a class="btn btn-primary add_weekday_setting" data-target="#add_target_weekday_<%=i%>" data-count="<%= all_day_settings[i] ? all_day_settings[i].count : 0 %>" data-day="<%=i%>"><%=t(:add)%></a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="settings">
|
||||
<% fields_name = f.object.class::FIELDSNAME %>
|
||||
<div style="padding: 1.2em;">
|
||||
<table style="margin: 0;">
|
||||
<thead>
|
||||
<th><%= t('property_hire.field_name') %></th>
|
||||
<th><%= t('property_hire.name') %></th>
|
||||
<th><%= t('property_hire.placeholder') %></th>
|
||||
<th><%= t('property_hire.disable') %></th>
|
||||
<th><%= t('property_hire.required') %></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% fields_name.each do |field_name| %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= t("property_hire.#{field_name}") %>
|
||||
</td>
|
||||
<td>
|
||||
<%= render_custom_text_field(f,field_name,"name") %>
|
||||
</td>
|
||||
<td>
|
||||
<%= render_custom_text_field(f,field_name,"placeholder") %>
|
||||
</td>
|
||||
<td>
|
||||
<input type="hidden" name='<%= "#{f.object_name}[#{field_name}][enable]" %>' value="1">
|
||||
<%= check_box_tag("#{f.object_name}[#{field_name}][enable]", "0" , (f.object.send(field_name)["enable"] == "0" rescue false)) %>
|
||||
</td>
|
||||
<td>
|
||||
<input type="hidden" name='<%= "#{f.object_name}[#{field_name}][required]" %>' value="false">
|
||||
<%= check_box_tag("#{f.object_name}[#{field_name}][required]", "true" , (f.object.send(field_name)["required"] == "true" rescue false)) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<hr style="border-color: black; ">
|
||||
<div class="control-group">
|
||||
<% field_name = "enable_notes_selector" %>
|
||||
<label class="control-label muted"><%= t("property_hire.#{field_name}") %></label>
|
||||
<div class="controls">
|
||||
<label for="act_enabled_name" class="checkbox inline">
|
||||
<%= hidden_field_tag "property[#{field_name}]", "0" %>
|
||||
<%= f.check_box_tag "property[#{field_name}]", "1" , (@property[field_name] rescue false) %>
|
||||
Enable
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" id="selector_block">
|
||||
<% field_name = "notes_selector" %>
|
||||
<label class="control-label muted"><%= t("property_hire.#{field_name}") %></label>
|
||||
<div class="controls">
|
||||
<div id="select_choice_block">
|
||||
<% @property[field_name].each do |index,sub_hash| %>
|
||||
<div id="select_choice<%=index.to_s%>" class="select_field_block">
|
||||
<span class="remove_btn">❌</span>
|
||||
<div class="field_name_block">
|
||||
<div>
|
||||
<label for="select_choice_type_index<%=index.to_s%>" class="label_left"><%=t("property_hire.field_type")%>:</label>
|
||||
<select name="<%="property[#{field_name}][#{index}][type]"%>">
|
||||
<option value="radio" <%=(@property["#{field_name}"]["#{index}"]["type"] == "radio") ? 'selected="selected"' : ''%>><%=t("property_hire.radio")%></option>
|
||||
<option value="checkbox" <%=(@property["#{field_name}"]["#{index}"]["type"] == "checkbox") ? 'selected="selected"' : ''%>><%=t("property_hire.checkbox")%></option>
|
||||
</select>
|
||||
</div>
|
||||
<div><label for="select_choice_name_index<%=index.to_s%>" class="label_left"><%=t("property_hire.field_name")%>:</label>
|
||||
<div class="input-append">
|
||||
<div class="tab-content">
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
<div class="tab-pane fade <%= ( i == 0 ) ? "active in" : '' %>" id="select_choice_name_index<%=index%>_<%=locale.to_s%>">
|
||||
<input type="text" value="<%=sub_hash['name'][locale.to_s] rescue ''%>" name="<%="property[#{field_name}][#{index}][name][#{locale}]"%>">
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
<a class="btn <%= ( i == 0 ) ? "active" : '' %>" href="#select_choice_name_index<%=index%>_<%=locale.to_s%>" data-toggle="tab"><%= t(locale.to_s) %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field_value_block">
|
||||
<label><%=t("property_hire.field_value")%></label>
|
||||
<% @property["#{field_name}"]["#{index}"]["value"].values.first.each_with_index do |v,val_index|%>
|
||||
<div class="value_choice">
|
||||
<span class="remove_btn">❌</span>
|
||||
<div class="input-append">
|
||||
<div class="tab-content">
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
<div class="tab-pane fade <%= ( i == 0 ) ? "active in" : '' %>" id="select_choice_value_index<%=index.to_s%>_<%=locale.to_s%>_<%=val_index%>">
|
||||
<input type="text" name="property[notes_selector][<%=index.to_s%>][value][<%=locale.to_s%>][]" value="<%=@property["#{field_name}"][index.to_s]["value"][locale.to_s][val_index]%>">
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
<a class="btn <%= ( i == 0 ) ? "active" : '' %>" href="#select_choice_value_index<%=index.to_s%>_<%=locale.to_s%>_<%=val_index%>" data-toggle="tab"><%= t(locale.to_s) %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div style="clear: both;"></div>
|
||||
<a class="btn btn-primary add_choice" data-index="<%=index.to_s%>"><%=t("property_hire.add_choice")%></a>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<a id="add_note_select_field" class="btn btn-primary"><%=t(:add)%></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Language Tabs -->
|
||||
<div class="nav-name"><strong><%= t(:language) %></strong></div>
|
||||
|
@ -253,7 +699,7 @@
|
|||
<label class="control-label muted"><%= t("property_hire.property_usage") %></label>
|
||||
<div class="controls">
|
||||
<%= f.fields_for :property_usage_translations do |f| %>
|
||||
<%= f.text_area locale, class: "input-block-level", placeholder: t("property_hire.property_usage"), value: (@property.property_usage_translations[locale] rescue nil) %>
|
||||
<%= f.text_area locale, class: "ckeditor input-block-level", placeholder: t("property_hire.property_usage"), value: (@property.property_usage_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -261,23 +707,33 @@
|
|||
<label class="control-label muted"><%= t("property_hire.note") %></label>
|
||||
<div class="controls">
|
||||
<%= f.fields_for :note_translations do |f| %>
|
||||
<%= f.text_area locale, class: "input-block-level", placeholder: t("property_hire.note"), value: (@property.note_translations[locale] rescue nil) %>
|
||||
<%= f.text_area locale, class: "ckeditor input-block-level", placeholder: t("property_hire.note"), value: (@property.note_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Form Actions -->
|
||||
<div class="form-actions">
|
||||
<% if params[:page] %>
|
||||
<input type="hidden" name="page" value="<%= params[:page] %>" />
|
||||
<% referer = request.referer rescue nil %>
|
||||
<% referer = get_referer_url if referer.blank? || request.host != URI.parse(URI.encode(referer)).host %>
|
||||
<input type="hidden" name="referer_url" value="<%= referer %>">
|
||||
<% unless @property.new_record? %>
|
||||
<%= hidden_field_tag("property[id]", @property.id) %>
|
||||
<% end %>
|
||||
<%= f.submit t('submit'), class: 'btn btn-primary' %>
|
||||
<%= link_to t('cancel'), admin_property_hires_path, :class=>"btn" %>
|
||||
<%= link_to t('cancel'), referer, :class=>"btn" %>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$("#bulletin_display_img").click(function(){$("#image_display_setting").toggleClass("hide")})
|
||||
$(document).ready(function(){
|
||||
if($("[type=checkbox][name='property[enable_notes_selector]']:checked").length == 0){
|
||||
$("#selector_block").css("display","none");
|
||||
}else{
|
||||
$("#selector_block").css("display","");
|
||||
}
|
||||
})
|
||||
$("#property_set_unavailibility").on("click",function(){
|
||||
if($(this).is(":checked")){
|
||||
$("#set_unavailibility_div").show();
|
||||
|
@ -285,7 +741,13 @@
|
|||
$("#set_unavailibility_div").hide();
|
||||
}
|
||||
})
|
||||
|
||||
$("#property_set_availability").on("click",function(){
|
||||
if($(this).is(":checked")){
|
||||
$("#set_availability_div").show();
|
||||
}else{
|
||||
$("#set_availability_div").hide();
|
||||
}
|
||||
})
|
||||
$("#property_property_location").on("change",function(){
|
||||
if($(this).val() == "other_location"){
|
||||
$("#other-location-div").show();
|
||||
|
@ -293,6 +755,300 @@
|
|||
$("#other-location-div").hide();
|
||||
}
|
||||
})
|
||||
$("#add_note_select_field").on("click",function(){
|
||||
var index = ($("#select_choice_block").find(">div").length == 0) ? 0 : (Number($("#select_choice_block").find(">div").eq(-1).attr("id").split("select_choice").last()) + 1);
|
||||
$("#select_choice_block").append('<div id="select_choice'+String(index)+'" class="select_field_block"><span class="remove_btn">❌</span>'+
|
||||
'<div class="field_name_block">'+
|
||||
'<div>'+
|
||||
'<label for="select_choice_type_index'+String(index)+'" class="label_left"><%=t("property_hire.field_type")%>:</label>'+
|
||||
'<select name="property[notes_selector]['+String(index)+'][type]">'+
|
||||
'<option value="radio"><%=t("property_hire.radio")%></option>'+
|
||||
'<option value="checkbox"><%=t("property_hire.checkbox")%></option>'+
|
||||
'</select>'+
|
||||
'</div>'+
|
||||
'<div><label for="select_choice_name_index'+String(index)+'" class="label_left"><%=t("property_hire.field_name")%>:</label>'+
|
||||
'<div class="input-append" id="select_choice_name_index'+String(index)+'">'+
|
||||
'<div class="tab-content">'+
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
'<div class="tab-pane fade <%= ( i == 0 ) ? "active in" : '' %>" id="select_choice_name_index'+String(index)+'_<%=locale.to_s%>">'+
|
||||
'<input type="text" name="property[notes_selector]['+String(index)+'][name][<%=locale.to_s%>]">'+
|
||||
'</div>'+
|
||||
<% end %>
|
||||
'</div>'+
|
||||
'<div class="btn-group" data-toggle="buttons-radio">'+
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
'<a class="btn <%= ( i == 0 ) ? "active" : '' %>" href="#select_choice_name_index'+String(index)+'_<%=locale.to_s%>" data-toggle="tab"><%= t(locale.to_s) %></a>'+
|
||||
<% end %>
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'<div class="field_value_block">'+
|
||||
'<label><%=t("property_hire.field_value")%></label>'+
|
||||
'<div class="value_choice">'+
|
||||
'<span class="remove_btn">❌</span>'+
|
||||
'<div class="input-append">'+
|
||||
'<div class="tab-content">'+
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
'<div class="tab-pane fade <%= ( i == 0 ) ? "active in" : '' %>" id="select_choice_value_index'+String(index)+'_<%=locale.to_s%>_0">'+
|
||||
'<input type="text" name="property[notes_selector]['+String(index)+'][value][<%=locale.to_s%>][]">'+
|
||||
'</div>'+
|
||||
<% end %>
|
||||
'</div>'+
|
||||
'<div class="btn-group" data-toggle="buttons-radio">'+
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
'<a class="btn <%= ( i == 0 ) ? "active" : '' %>" href="#select_choice_value_index'+String(index)+'_<%=locale.to_s%>_0" data-toggle="tab"><%= t(locale.to_s) %></a>'+
|
||||
<% end %>
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'</div>'+
|
||||
'<div style="clear: both;"></div>'+
|
||||
'<a class="btn btn-primary add_choice" data-index="'+String(index)+'"><%=t("property_hire.add_choice")%></a>'+
|
||||
'</div>'+
|
||||
'</div>');
|
||||
$(".add_choice").off("click").on("click",function(){
|
||||
var index = $(this).attr("data-index");
|
||||
var val_index = $(this).siblings(".value_choice").length;
|
||||
var $last_item = $(this).siblings(".value_choice").eq(-1);
|
||||
if(val_index == 0){
|
||||
$last_item = $(this).siblings("label").eq(-1);
|
||||
}
|
||||
$last_item.after('<div class="value_choice"><span class="remove_btn">❌</span><div class="input-append">'+
|
||||
'<div class="tab-content">'+
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
'<div class="tab-pane fade <%= ( i == 0 ) ? "active in" : '' %>" id="select_choice_value_index'+String(index)+'_<%=locale.to_s%>_'+String(val_index)+'">'+
|
||||
'<input type="text" name="property[notes_selector]['+String(index)+'][value][<%=locale.to_s%>][]">'+
|
||||
'</div>'+
|
||||
<% end %>
|
||||
'</div>'+
|
||||
'<div class="btn-group" data-toggle="buttons-radio">'+
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
'<a class="btn <%= ( i == 0 ) ? "active" : '' %>" href="#select_choice_value_index'+String(index)+'_<%=locale.to_s%>_'+String(val_index)+'" data-toggle="tab"><%= t(locale.to_s) %></a>'+
|
||||
<% end %>
|
||||
'</div>'+
|
||||
'</div></div>');
|
||||
$(".remove_btn").off("click").on("click",function(){
|
||||
$(this).parent().remove();
|
||||
})
|
||||
})
|
||||
$(".remove_btn").off("click").on("click",function(){
|
||||
$(this).parent().remove();
|
||||
})
|
||||
})
|
||||
$(".add_choice").off("click").on("click",function(){
|
||||
var index = $(this).attr("data-index");
|
||||
var val_index = $(this).siblings(".value_choice").length;
|
||||
var $last_item = $(this).siblings(".value_choice").eq(-1);
|
||||
if(val_index == 0){
|
||||
$last_item = $(this).siblings("label").eq(-1);
|
||||
}
|
||||
$last_item.after('<div class="value_choice"><span class="remove_btn">❌</span><div class="input-append">'+
|
||||
'<div class="tab-content">'+
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
'<div class="tab-pane fade <%= ( i == 0 ) ? "active in" : '' %>" id="select_choice_value_index'+String(index)+'_<%=locale.to_s%>_'+String(val_index)+'">'+
|
||||
'<input type="text" name="property[notes_selector]['+String(index)+'][value][<%=locale.to_s%>][]">'+
|
||||
'</div>'+
|
||||
<% end %>
|
||||
'</div>'+
|
||||
'<div class="btn-group" data-toggle="buttons-radio">'+
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
'<a class="btn <%= ( i == 0 ) ? "active" : '' %>" href="#select_choice_value_index'+String(index)+'_<%=locale.to_s%>_'+String(val_index)+'" data-toggle="tab"><%= t(locale.to_s) %></a>'+
|
||||
<% end %>
|
||||
'</div>'+
|
||||
'</div></div>');
|
||||
$(".remove_btn").off("click").on("click",function(){
|
||||
$(this).parent().remove();
|
||||
})
|
||||
});
|
||||
$(".remove_btn").off("click").on("click",function(){
|
||||
$(this).parent().remove();
|
||||
})
|
||||
$("[type=checkbox][name='property[enable_notes_selector]']").click(function(){
|
||||
if(!$(this).prop("checked")){
|
||||
$("#selector_block").css("display","none");
|
||||
}else{
|
||||
$("#selector_block").css("display","");
|
||||
}
|
||||
})
|
||||
var setting_count = <%=setting_count%>;
|
||||
var default_time_settings = <%= PropertyHireSetting.first.default_time_settings.map{|s| s.attributes.except("_id","created_at","updated_at")}.to_s.gsub("=>",": ").html_safe rescue "[]" %>
|
||||
<% property_day_setting = f.object.property_day_settings.new(:id=>nil) %>
|
||||
<%= f.fields_for :property_day_settings,property_day_setting,:child_index => "new_index" do |f| %>
|
||||
var template_html = "<%= escape_javascript(render(:partial=>"time_form",:locals=>{:f=>f})) %>";
|
||||
console.log(template_html);
|
||||
<%end%>
|
||||
$(".apply_default_time_settings").click(function(){
|
||||
var target = $($(this).data("target"));
|
||||
var key = $(this).data("count");
|
||||
var day = $(this).data("day");
|
||||
var new_key = $(this).prev().attr('value');
|
||||
var old_key = new RegExp("new_key", "g");
|
||||
var new_day = day;
|
||||
var old_day = new RegExp("new_day", "g");
|
||||
target.empty();
|
||||
default_time_settings.forEach(function(setting){
|
||||
var old_index = new RegExp("new_index", "g");
|
||||
var new_index = setting_count;
|
||||
var new_key = key;
|
||||
setting_count += 1;
|
||||
|
||||
var tmp = $(template_html.replace(old_index,new_index).replace(old_key,new_key).replace(old_day,new_day));
|
||||
Object.keys(setting).forEach(function(k){
|
||||
if(k != "day" && k != "key"){
|
||||
if(tmp.find("[name*='["+k+"]'").length != 0){
|
||||
tmp.find("[name*='["+k+"]']").val(setting[k]);
|
||||
console.log([k,setting[k]])
|
||||
}
|
||||
}
|
||||
});
|
||||
target.append(tmp);
|
||||
key += 1;
|
||||
})
|
||||
$(this).data("count",key);
|
||||
target.find("input[data-format]").each(function(i,input){
|
||||
var $input = $(input);
|
||||
var format = $input.data("format"),
|
||||
timeOnly = !(format.match(/Y|M|d/)), timeFormat, dateFormat = "";
|
||||
if(timeOnly){
|
||||
timeFormat = format;
|
||||
}else{
|
||||
dateFormat = format.match(/yy(\/|-|)(mm|)(\/|-|)(dd|)/i)[0];
|
||||
timeFormat = $.trim(format.replace(dateFormat,""));
|
||||
}
|
||||
var options = {dateFormat: dateFormat,timeFormat: timeFormat,timeOnly: timeOnly};
|
||||
var additionalOptions = $input.data();
|
||||
$.extend(options, additionalOptions);
|
||||
$input.ui_datetimepicker(options);
|
||||
$input.siblings('.clearDate').click(function(){
|
||||
$input.val('');
|
||||
$input.trigger('change');
|
||||
});
|
||||
})
|
||||
})
|
||||
$(".add_weekday_setting").click(function(){
|
||||
var target = $($(this).data("target"));
|
||||
var key = $(this).data("count");
|
||||
var day = $(this).data("day");
|
||||
var new_key = $(this).prev().attr('value');
|
||||
var old_key = new RegExp("new_key", "g");
|
||||
var new_day = day;
|
||||
var old_day = new RegExp("new_day", "g");
|
||||
var new_key = key;
|
||||
key += 1;
|
||||
$(this).data("count",key);
|
||||
var old_index = new RegExp("new_index", "g");
|
||||
var new_index = setting_count;
|
||||
setting_count += 1;
|
||||
<% property_day_setting = f.object.property_day_settings.new(:id=>nil) %>
|
||||
<%= f.fields_for :property_day_settings,property_day_setting,:child_index => "new_index" do |f| %>
|
||||
var template_html = "<%= escape_javascript(render(:partial=>"time_form",:locals=>{:f=>f})) %>";
|
||||
<%end%>
|
||||
var tmp = $(template_html.replace(old_index,new_index).replace(old_key,new_key).replace(old_day,new_day));
|
||||
target.append(tmp);
|
||||
tmp.find("input[data-format]").each(function(i,input){
|
||||
var $input = $(input);
|
||||
var format = $input.data("format"),
|
||||
timeOnly = !(format.match(/Y|M|d/)), timeFormat, dateFormat = "";
|
||||
if(timeOnly){
|
||||
timeFormat = format;
|
||||
}else{
|
||||
dateFormat = format.match(/yy(\/|-|)(mm|)(\/|-|)(dd|)/i)[0];
|
||||
timeFormat = $.trim(format.replace(dateFormat,""));
|
||||
}
|
||||
var options = {dateFormat: dateFormat,timeFormat: timeFormat,timeOnly: timeOnly};
|
||||
var additionalOptions = $input.data();
|
||||
$.extend(options, additionalOptions);
|
||||
$input.ui_datetimepicker(options);
|
||||
$input.siblings('.clearDate').click(function(){
|
||||
$input.val('');
|
||||
$input.trigger('change');
|
||||
});
|
||||
})
|
||||
})
|
||||
$(document).on('click', '.setting-form-remove', function(){
|
||||
if($(this).find(".remove_existing_record").length != 0){
|
||||
if(confirm("<%= I18n.t(:sure?)%>")){
|
||||
$(this).find('.should_destroy').attr('value', 1);
|
||||
$(this).parents('.time_setting_form').hide();
|
||||
}
|
||||
}else{
|
||||
$(this).parents('.time_setting_form').remove();
|
||||
}
|
||||
});
|
||||
$(document).on('click', '.image-form-remove', function(){
|
||||
if($(this).find(".remove_existing_record").length != 0){
|
||||
if(confirm("<%= I18n.t(:sure?)%>")){
|
||||
$(this).find('.should_destroy').attr('value', 1);
|
||||
$(this).parents('.image_group').hide();
|
||||
}
|
||||
}else{
|
||||
$(this).parents('.image_group').remove();
|
||||
}
|
||||
});
|
||||
$(document).on('click', '#add_carousel_image', function(){
|
||||
var new_id = $(this).prev().attr('value');
|
||||
var old_id = new RegExp("new_property_carousel_images", "g");
|
||||
var on = $('.language-nav li.active').index();
|
||||
var le = $(this).parent('.add-btn').prev('.add-target').children('.start-line').length;
|
||||
$(this).prev().attr('value', parseInt(new_id) + 1);
|
||||
$(this).parent().siblings('.add-target').append(("<%= escape_javascript(add_attribute 'form_image', f, :property_carousel_images) %>").replace(old_id, new_id));
|
||||
$(this).parent('.add-btn').prev('.add-target').children('.start-line').eq(le).children('.input-append').find('.tab-content').each(function() {
|
||||
$(this).children('.tab-pane').eq(on).addClass('in active').siblings().removeClass('in active');
|
||||
});
|
||||
});
|
||||
$(document).on('click', '.fileupload-remove', function(){
|
||||
if($(this).find(".delete_image").length != 0){
|
||||
$(this).parents('.image_group').remove();
|
||||
}
|
||||
});
|
||||
|
||||
// $(document).on("click", "#property_can_be_hired", function () {
|
||||
// if($(this).is(":checked")){
|
||||
// $("#open-time").attr("class","show");
|
||||
// }else{
|
||||
// $("#open-time").attr("class","hide");
|
||||
// $("#open-time").find("input").val("");
|
||||
// }
|
||||
// })
|
||||
var special_unavailable_title_counter = <%= @property.special_unavailable_dates.count %>;
|
||||
$(document).on("click","#add_special_unavailable_date", function(){
|
||||
var datepicker = $('<div class="date_picker input-append" style="margin-bottom:3px;"> \
|
||||
<input placeholder="yyyy/MM/dd" class="input-large" data-format="yyyy/MM/dd" type="text" name="property[special_unavailable_dates][]" title="yyyy/MM/dd" autocomplete="off"> \
|
||||
<span class="add-on clearDate"><i class="icons-cross-3"></i></span> \
|
||||
<span class="add-on deleteDate"><i class="icon-trash"></i></span> \
|
||||
</div>');
|
||||
|
||||
var id = "special_unavailable_title_" + special_unavailable_title_counter;
|
||||
var title = $('<div class="tab-panel"> \
|
||||
<div class="tab-content active" id="' + id + '_en"> \
|
||||
<input type="text" name="property[special_unavailable_dates_title][][en]" value=""> \
|
||||
</div> \
|
||||
<div class="tab-content" id="' + id + '_zh_tw"> \
|
||||
<input type="text" name="property[special_unavailable_dates_title][][zh_tw]" value=""> \
|
||||
</div> \
|
||||
<div class="btn-group" data-toggle="buttons-radio"> \
|
||||
<a data-toggle="tab" class="btn active" for="en" href="#' + id + '_en" aria-expanded="true" aria-pressed="true"><%= t("en") %></a> \
|
||||
<a data-toggle="tab" class="btn" for="zh_tw" href="#' + id + '_zh_tw" aria-expanded="true" aria-pressed="true"><%= t("zh_tw") %></a> \
|
||||
</div> \
|
||||
</div>');
|
||||
|
||||
datepicker.find('input').datepicker({
|
||||
dateFormat : "yy/mm/dd"
|
||||
});
|
||||
var html = $('<div class="temp_date_holder" style="margin-bottom:5px;"></div>');
|
||||
html.append(datepicker);
|
||||
html.append(title);
|
||||
$("#special_unavailable_date_holder").append(html);
|
||||
special_unavailable_title_counter++;
|
||||
return false;
|
||||
})
|
||||
$(document).on("click","#special_unavailable_date_holder .clearDate", function (params) {
|
||||
$(this).parents('.default_picker,.time_picker,.date_picker').eq(-1).find('input').val('')
|
||||
$(this).parents('.default_picker,.time_picker,.date_picker').eq(-1).find('input').trigger('change')
|
||||
})
|
||||
$(document).on("click","#special_unavailable_date_holder .deleteDate", function (params) {
|
||||
$(this).parents('#special_unavailable_date_holder .temp_date_holder').eq(-1).remove();
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<% if form_file.nil? || form_file.file.blank? %>
|
||||
<div class="fileupload fileupload-new start-line" data-provides="fileupload">
|
||||
<% else %>
|
||||
<div class="fileupload fileupload-exists start-line" data-provides="fileupload">
|
||||
<% if form_file.file.blank? %>
|
||||
<%= t(:no_file) %>
|
||||
<% else %>
|
||||
<%= link_to content_tag(:i) + form_file.file_identifier, form_file.file.url, {:class => 'file-link file-type', :target => '_blank', :title => form_file.file_identifier} %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<div class="input-prepend input-append">
|
||||
<label>
|
||||
<span class="add-on btn btn-file" title='<%= t(:file_) %>'>
|
||||
<i class="icons-paperclip"></i>
|
||||
<%= f.file_field :file %>
|
||||
</span>
|
||||
<div class="uneditable-input input-medium">
|
||||
<i class="icon-file fileupload-exists"></i>
|
||||
<span class="fileupload-preview"><%= (form_file.nil? || form_file.file.blank?) ? t(:select_file) : t(:change_file) %></span>
|
||||
</div>
|
||||
</label>
|
||||
<span class="add-on icons-pencil" title='<%= t(:alternative) %>'></span>
|
||||
<span class="tab-content">
|
||||
<% if form_file.fields["title"].options[:localize] %>
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
<span class="tab-pane fade <%= ( i == 0 ) ? "in active" : '' %> <%= locale %>">
|
||||
<%= f.fields_for :title_translations do |f| %>
|
||||
<%= f.text_field locale, :class => "input-medium", placeholder: t(:alternative), :value => (form_file.title_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= f.text_field :title, :class => "input-medium", placeholder: t(:alternative) %>
|
||||
<% end %>
|
||||
</span>
|
||||
<span class="add-on icons-pencil" title='<%= t(:description) %>'></span>
|
||||
<span class="tab-content">
|
||||
<% if form_file.fields["description"].options[:localize] %>
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
<span class="tab-pane fade <%= ( i == 0 ) ? "in active" : '' %> <%= locale %>">
|
||||
<%= f.fields_for :description_translations do |f| %>
|
||||
<%= f.text_field locale, :class => "input-medium", placeholder: t(:description), :value => (form_file.description_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= f.text_field :description, :class => "input-medium", placeholder: t(:description) %>
|
||||
<% end %>
|
||||
</span>
|
||||
</span>
|
||||
<% if form_file.nil? || form_file.new_record? %>
|
||||
<span class="delete_file add-on btn" title="<%= t(:delete_) %>">
|
||||
<a class="icon-trash"></a>
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="remove_existing_record add-on btn" title="<%= t(:remove) %>">
|
||||
<%= f.hidden_field :id %>
|
||||
<a class="icon-remove"></a>
|
||||
<%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %>
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,93 @@
|
|||
<!-- Link -->
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t(:link) %></label>
|
||||
<div class="controls add-input">
|
||||
|
||||
<!-- Exist -->
|
||||
<% if !f.object.nil? && !f.object.property_links.blank? %>
|
||||
<div class="exist">
|
||||
<% f.object.property_links.each_with_index do |property_link, i| %>
|
||||
<%= f.fields_for :property_links, property_link do |f| %>
|
||||
<%= render :partial => 'form_link', :object=> property_link, :locals => {:f => f, :i => i } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<hr>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Add -->
|
||||
<div class="add-target">
|
||||
</div>
|
||||
<p class="add-btn">
|
||||
<%= hidden_field_tag 'property_link_field_count', f.object.property_links.count %>
|
||||
<a id="add_link" class="trigger btn btn-small btn-primary"><i class="icons-plus"></i> <%= t(:add) %></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- File -->
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t(:file_) %></label>
|
||||
<div class="controls">
|
||||
|
||||
<!-- Exist -->
|
||||
<% if !f.object.nil? && !f.object.property_files.blank? %>
|
||||
<div class="exist">
|
||||
<% f.object.property_files.each_with_index do |property_file, i| %>
|
||||
<%= f.fields_for :property_files, property_file do |f| %>
|
||||
<%= render :partial => 'form_file',:object => property_file, :locals => {:f => f, :i => i} %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<hr>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Add -->
|
||||
<div class="add-target">
|
||||
</div>
|
||||
<p class="add-btn">
|
||||
<%= hidden_field_tag 'property_file_field_count', f.object.property_files.count %>
|
||||
<a id="add_file" class="trigger btn btn-small btn-primary"><i class="icons-plus"></i> <%= t(:add) %></a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$(document).on('click', '#add_link', function(){
|
||||
var new_id = $(this).prev().attr('value');
|
||||
var old_id = new RegExp("new_property_links", "g");
|
||||
var on = $('.language-nav li.active').index();
|
||||
var le = $(this).parent('.add-btn').prev('.add-target').children('.start-line').length;
|
||||
$(this).prev().attr('value', parseInt(new_id) + 1);
|
||||
$(this).parent().siblings('.add-target').append(("<%= escape_javascript(add_attribute 'form_link', f, :property_links) %>").replace(old_id, new_id));
|
||||
$(this).parent('.add-btn').prev('.add-target').children('.start-line').eq(le).children('.tab-content').children('.tab-pane').eq(on).addClass('in active').siblings().removeClass('in active');
|
||||
formTip();
|
||||
});
|
||||
$(document).on('click', '#add_file', function(){
|
||||
var new_id = $(this).prev().attr('value');
|
||||
var old_id = new RegExp("new_property_files", "g");
|
||||
var on = $('.language-nav li.active').index();
|
||||
var le = $(this).parent('.add-btn').prev('.add-target').children('.start-line').length;
|
||||
$(this).prev().attr('value', parseInt(new_id) + 1);
|
||||
$(this).parent().siblings('.add-target').append(("<%= escape_javascript(add_attribute 'form_file', f, :property_files) %>").replace(old_id, new_id));
|
||||
$(this).parent('.add-btn').prev('.add-target').children('.start-line').eq(le).children('.input-append').find('.tab-content').each(function() {
|
||||
$(this).children('.tab-pane').eq(on).addClass('in active').siblings().removeClass('in active');
|
||||
});
|
||||
formTip();
|
||||
});
|
||||
$(document).on('click', '.delete_link', function(){
|
||||
$(this).parents('.input-prepend').remove();
|
||||
});
|
||||
$(document).on('click', '.delete_file', function(){
|
||||
$(this).parents('.input-prepend').remove();
|
||||
});
|
||||
$(document).on('click', '.remove_existing_record', function(){
|
||||
if(confirm("<%= I18n.t(:sure?)%>")){
|
||||
$(this).children('.should_destroy').attr('value', 1);
|
||||
$(this).parents('.start-line').hide();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,47 @@
|
|||
<!-- Images Upload -->
|
||||
<div class="image_group">
|
||||
<label class="checkbox inline btn btn-danger image-form-remove">
|
||||
<% if f.object.new_record? %>
|
||||
<span class="delete_form" title="<%= t(:delete_) %>">
|
||||
X
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="remove_existing_record" title="<%= t(:remove) %>">
|
||||
<%= f.hidden_field :id %>
|
||||
<%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %>
|
||||
X
|
||||
</span>
|
||||
<% end %>
|
||||
</label>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t(:image) %></label>
|
||||
<div class="controls">
|
||||
<div class="fileupload fileupload-new clearfix <%= 'fileupload-edit' if form_image.file.present? %>" data-provides="fileupload">
|
||||
<div class="fileupload-new thumbnail pull-left">
|
||||
<% if form_image.file.file %>
|
||||
<%= image_tag form_image.file %>
|
||||
<% else %>
|
||||
<img src="/assets/property_hire/AAAAAA.png" />
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="fileupload-preview fileupload-exists thumbnail pull-left"></div>
|
||||
<span class="btn btn-file">
|
||||
<span class="fileupload-new"><%= t(:select_image) %></span>
|
||||
<span class="fileupload-exists"><%= t(:change) %></span>
|
||||
<%= f.file_field :file %>
|
||||
</span>
|
||||
<a href="#" class="btn fileupload-exists" data-dismiss="fileupload"><%= t(:cancel) %></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<%= f.fields_for :description_translations do |f| %>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="image_description_<%= locale.to_s %>"><%= t(:description) + " (#{t(locale.to_s)})" %></label>
|
||||
<div class="controls">
|
||||
<%= f.text_field locale, value: (form_image.description_translations[locale.to_s] rescue nil) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
|
@ -0,0 +1,30 @@
|
|||
<div class="input-prepend input-append start-line">
|
||||
<span class="add-on icons-link" title="<%= t(:url) %>"></span>
|
||||
<%= f.text_field :url, class: "input-large", placeholder: t(:url) %>
|
||||
<span class="add-on icons-pencil" title="<%= t(:url_alt) %>"></span>
|
||||
<span class="tab-content">
|
||||
<% if form_link.fields["title"].options[:localize] %>
|
||||
<% @site_in_use_locales.each_with_index do |locale, i| %>
|
||||
<span class="tab-pane fade <%= ( i == 0 ) ? "in active" : '' %> <%= locale %>">
|
||||
<%= f.fields_for :title_translations do |f| %>
|
||||
<%= f.text_field locale, :class => "input-large", placeholder: t(:url_alt), :value => (form_link.title_translations[locale] rescue nil) %>
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= f.text_field :title, :class => "input-large", placeholder: t(:url_alt) %>
|
||||
<% end %>
|
||||
</span>
|
||||
|
||||
<% if form_link.nil? || form_link.new_record? %>
|
||||
<span class="delete_link add-on btn" title="<%= t(:delete_) %>">
|
||||
<a class="icon-trash"></a>
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="remove_existing_record add-on btn" title="<%= t(:remove) %>">
|
||||
<%= f.hidden_field :id %>
|
||||
<a class="icon-remove"></a>
|
||||
<%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %>
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
|
@ -0,0 +1,48 @@
|
|||
<table class="table main-list">
|
||||
<thead>
|
||||
<tr class="sort-header">
|
||||
<% @table_fields.each do |f| %>
|
||||
<%= thead(f) %>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @properties.each do |property| %>
|
||||
<tr>
|
||||
<td>
|
||||
<% if can_edit_or_delete?(property) %>
|
||||
<a href="<%= admin_property_hire_path(property) %>"><%= property.title %></a>
|
||||
<div class="quick-edit">
|
||||
<ul class="nav nav-pills">
|
||||
<li><a href="<%= edit_admin_property_hire_path(property, :page => params[:page]) %>"><%= t(:edit) %></a></li>
|
||||
<li><a href="<%= copy_admin_property_hire_path(property, :page => params[:page]) %>"><%= t("property_hire.copy") %></a></li>
|
||||
<li><a href="<%= custom_fields_admin_property_hire_path(property) %>"><%= t("property_hire.custom_fields") %></a></li>
|
||||
<li><a href="<%= fields_display_order_admin_property_hire_path(property) %>"><%= t("property_hire.fields_display_order") %></a></li>
|
||||
<li><a href="<%= export_reservation_data_admin_property_hire_path(property.id) %>" class="export-xls" data-property-id="<%= property.id.to_s %>"><%= t("property_hire.export_reservation_data") %></a></li>
|
||||
<li><a href="<%= admin_property_hire_path(property.id, :page => params[:page]) %>" data-method="delete" data-confirm="Are you sure?"><%= t(:delete_) %></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= property.title %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<%= property.category.title rescue nil %>
|
||||
</td>
|
||||
<td>
|
||||
<%= property.get_location_name %>
|
||||
</td>
|
||||
<td>
|
||||
<% if property.can_reserve %>
|
||||
<span class="badge badge-success">Yes</span>
|
||||
<% else %>
|
||||
<span class="badge badge-important">No</span>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="bottomnav clearfix">
|
||||
<%= content_tag(:div, paginate(@properties), class: "pagination pagination-centered") %>
|
||||
</div>
|
|
@ -0,0 +1,309 @@
|
|||
<%#= encoding: utf-8 %>
|
||||
|
||||
<script id="template-attributes" type="text/x-tmpl">
|
||||
<div class="attributes">
|
||||
<div class="attributes-header clearfix">
|
||||
<input class="toggle-check" data-deploy="right" id="${_disabled[0]}" name="${_disabled[1]}" type="hidden" value="false">
|
||||
<a class="btn btn-mini pull-right btn-danger delete" href="#"><i class="icon-trash"></i> Delete</a>
|
||||
<a class="btn btn-mini pull-right btn-inverse reply hide" href="#"><i class="icons-reply"></i> Reply</a>
|
||||
<input class="attribute_field_to_delete" id="${_to_delete[0]}" name="${_to_delete[1]}" type="hidden" value="false">
|
||||
<h4>Field <span>${attributesHeaderLength}</span></h4>
|
||||
</div>
|
||||
<div class="attributes-body">
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="${_key[0]}"><%= t(:key) %></label>
|
||||
<div class="controls">
|
||||
<input type="text" data-type="key" id="${_key[0]}" name="${_key[1]}" placeholder="<%= t(:key) %>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t(:name) %></label>
|
||||
<div class="controls">
|
||||
<div class="input-append">
|
||||
<div class="tab-content">
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
<div class="tab-pane <%= active %> fade in" id="${_title_translations[0]+'_<%= locale%>'}">
|
||||
<input type="text" data-type="lang_<%= locale%>" name="${_title_translations[1]+'[<%= locale%>]'}" placeholder="<%= t(locale).to_s %>">
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
<a class="btn <%= active %>" href="${'#'+_title_translations[0]+'_<%= locale%>'}" data-toggle="tab"><%= t(locale).to_s %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t('property_hire.to_require') %></label>
|
||||
<div class="controls">
|
||||
<label class="radio inline">
|
||||
<input type="radio" data-type="search_true" id="${_to_require[0]+'_true'}" name="${_to_require[1]}" value="true" checked=""> <%= t(:yes_)%>
|
||||
</label>
|
||||
<label class="radio inline">
|
||||
<input type="radio" data-type="search_false" id="${_to_require[0]+'_false'}" name="${_to_require[1]}" value="false"> <%= t(:no_)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t('property_hire.display_in_reason_for_hire') %></label>
|
||||
<div class="controls">
|
||||
<label class="radio inline">
|
||||
<input type="radio" data-type="search_true" id="${_display_in_reason_for_hire[0]+'_true'}" name="${_display_in_reason_for_hire[1]}" value="true"> <%= t(:yes_)%>
|
||||
</label>
|
||||
<label class="radio inline">
|
||||
<input type="radio" data-type="search_false" id="${_display_in_reason_for_hire[0]+'_false'}" name="${_display_in_reason_for_hire[1]}" value="false" checked=""> <%= t(:no_)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t(:type)%></label>
|
||||
<div class="controls">
|
||||
<select class="dataType" data-type="select" name="${_markup}">
|
||||
<%$property_list[:markups].each do |key,val|%>
|
||||
<% next if val["display_only"] && val["display_only"] != params["action"] %>
|
||||
<% if key != 'address' %>
|
||||
<option value="<%= key %>" ref="<%=val["panel"]%>"><%=t("lists.markups."+key)%></option >
|
||||
<% end %>
|
||||
<% end %>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-type fade in typeA">
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t(:enabled_for)%></label>
|
||||
<div class="controls">
|
||||
<label class="checkbox inline">
|
||||
<input type="checkbox" data-type="enable_monolingual" id="${_cross_lang[0]}" name="${_cross_lang[1]}" value="true">
|
||||
<%= t(:cross_lang) %>
|
||||
</label>
|
||||
<label class="checkbox inline">
|
||||
<input type="checkbox" data-type="extendable_field" id="${_add_more[0]}" name="${_add_more[1]}" value="true">
|
||||
<%= t(:add_more)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t(:placeholder) %></label>
|
||||
<div class="controls">
|
||||
<div class="input-append">
|
||||
<div class="tab-content">
|
||||
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
|
||||
<div class="tab-pane <%= active %> fade in" id="${_placeholder[0]+'_<%= locale %>'}">
|
||||
<input type="text" data-type="lang_<%= locale %>" placeholder="<%= t(locale).to_s %>" name="${_placeholder[1]+'[<%= locale %>]'}">
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
|
||||
<a class="btn <%= active %>" href="${'#'+_placeholder[0]+'_<%= locale %>'}" data-toggle="tab"><%= t(locale).to_s %></a>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script id="template-type" type="text/x-tmpl">
|
||||
{{if templateType == 'typeA' || templateType == 'typeD' || templateType == 'typeG'}}
|
||||
<div class="control-group">
|
||||
<label class="control-label muted"><%= t(:enabled_for)%></label>
|
||||
<div class="controls">
|
||||
{{if templateType == 'typeA' || templateType == 'typeD'}}
|
||||
<label class="checkbox inline">
|
||||
<input type="checkbox" data-type="enable_monolingual" id="${_cross_lang[0]}" name="${_cross_lang[1]}" value="true">
|
||||
<%= t(:cross_lang) %>
|
||||
</label>
|
||||
{{/if}}
|
||||
{{if templateType == 'typeA' || templateType == 'typeG'}}
|
||||
<label class="checkbox inline">
|
||||
<input type="checkbox" data-type="extendable_field" id="${_add_more[0]}" name="${_add_more[1]}" value="true">
|
||||
<%= t(:add_more)%>
|
||||
</label>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{if templateType == 'typeA' || templateType == 'typeB' || templateType == 'typeD'}}
|
||||
<div class="control-group">
|
||||
<label class="control-label muted">
|
||||
{{if templateType == 'typeB'}}
|
||||
<%= t(:initial) %>
|
||||
{{else}}
|
||||
<%= t(:placeholder) %>
|
||||
{{/if}}
|
||||
</label>
|
||||
<div class="controls">
|
||||
<div class="input-append">
|
||||
<div class="tab-content">
|
||||
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
|
||||
<div class="tab-pane <%= active %> fade in" id=
|
||||
{{if templateType == 'typeB'}}
|
||||
"${_initial[0]+'_<%= locale %>'}"
|
||||
{{else}}
|
||||
"${_placeholder[0]+'_<%= locale %>'}"
|
||||
{{/if}}
|
||||
>
|
||||
<input type="text" data-type="lang_<%= locale %>" placeholder="<%= t(locale).to_s %>" name=
|
||||
{{if templateType == 'typeB'}}
|
||||
"${_initial[1]+'[<%= locale %>]' }"
|
||||
{{else}}
|
||||
"${_placeholder[1]+'[<%= locale %>]'}"
|
||||
{{/if}}
|
||||
>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
|
||||
<a class="btn <%= active %>" href=
|
||||
{{if templateType == 'typeB'}}
|
||||
"${'#'+_initial[0]+'_<%= locale %>'}"
|
||||
{{else}}
|
||||
"${'#'+_placeholder[0]+'_<%= locale %>'}"
|
||||
{{/if}}
|
||||
data-toggle="tab"><%= t(locale).to_s %></a>
|
||||
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{if templateType == 'typeB' || templateType == 'typeE'}}
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t(:options)%></label>
|
||||
<div class="controls add-input">
|
||||
<div class="add-target single">
|
||||
<%= content_tag :div,:class=>"input-append" do%>
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% last = (locale == @site_in_use_locales.last ? true : false) %>
|
||||
<input type="text" data-type="${_option_list[2]+'_<%= locale %>' }" id="${_option_list[0]+'_<%= locale %>'}" name="${_option_list[1]+'[<%= locale %>]'}" class="input-medium" placeholder="<%= t(locale).to_s %>">
|
||||
<% if last %>
|
||||
<a href="#" class="btn remove-input"> <i class="icon-trash"></i> </a>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<p class="add-btn">
|
||||
<a href="#" class="${templateType+' trigger btn btn-mini btn-primary'}"><i class="icons-plus"></i> Add</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{if templateType == 'typeC'}}
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t("date.format")%></label>
|
||||
<div class="controls">
|
||||
<select data-type="date" id="${_format[0]}" name="${_format[1]}">
|
||||
<option value="format1">YYYY / MM / DD hh : mm</option>
|
||||
<option value="format2">YYYY / MM / DD</option>
|
||||
<option value="format3">YYYY / MM</option>
|
||||
<option value="format4">YYYY</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t("date.range")%></label>
|
||||
<div class="controls">
|
||||
<label class="radio inline">
|
||||
<input type="radio" data-type="time_period_flase" id="${_is_range[0]+'_false'}" name="${_is_range[1]}" value="false" checked="checked"> <%= t(:yes_)%>
|
||||
</label>
|
||||
<label class="radio inline">
|
||||
<input type="radio" data-type="time_period_true" id="${_is_range[0]+'_true'}" name="${_is_range[1]}" value="true"> <%= t(:no_)%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for=""><%= t("date.calendar")%></label>
|
||||
<div class="controls">
|
||||
<label class="radio inline">
|
||||
<input type="radio" data-type="calendar_ac" id="${_calendar[0]+'_west_calendar'}" name="${_calendar[1]}" value="west_calendar" checked="checked"> <%= t("date.west_calendar")%>
|
||||
</label>
|
||||
<label class="radio inline">
|
||||
<input type="radio" data-type="calendar_roc" id="${_calendar[0]+'_tw_calendar'}" name="${_calendar[1]}" value="tw_calendar"> <%= t("date.tw_calendar")%>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{if templateType == 'typeF'}}
|
||||
<div class="control-group">
|
||||
<label class="control-label muted">
|
||||
<%= t("lists.markups.hint_text") %>
|
||||
</label>
|
||||
<div class="controls">
|
||||
<div class="input-append">
|
||||
<div class="tab-content">
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
|
||||
<div class="tab-pane <%= active %> fade in" id=
|
||||
"${_placeholder[0]+'_<%= locale %>'}">
|
||||
<textarea data-type="lang_<%= locale %>" placeholder="<%= t(locale).to_s %>" name="${_placeholder[1]+'[<%= locale %>]'}"></textarea>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
<a class="btn <%= active %>" href="${'#'+_placeholder[0]+'_<%= locale %>'}"data-toggle="tab">
|
||||
<%= t(locale).to_s %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</script>
|
||||
|
||||
|
||||
<script id="template-input-append" type="text/x-tmpl">
|
||||
<%= content_tag :div,:class=>"input-append" do%>
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% last = (locale == @site_in_use_locales.last ? true : false) %>
|
||||
<input type="text" data-type="${_option_list[2]+'_<%= locale %>' }" id="${_option_list[0]+'_<%= locale %>'}" name="${_option_list[1]+'[<%= locale %>]'}" class="input-medium" placeholder="<%= t(locale).to_s %>">
|
||||
<% if last %>
|
||||
<a href="#" class="btn remove-input"> <i class="icon-trash"></i> </a>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</script>
|
||||
|
||||
<script id="template-text" type="text/x-tmpl">
|
||||
<div class="input-append">
|
||||
<input type="text" id="${'text'+_text[0]}" name="${_text[1]+'[text]'}" class="input-medium" placeholder="Text">
|
||||
<a href="#" class="btn remove-input">
|
||||
<i class="icon-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
</script>
|
|
@ -0,0 +1,44 @@
|
|||
<div class="time_setting_form">
|
||||
<% key = (defined?(key) && key) ? key : "new_key"
|
||||
day = (defined?(day) && day) ? day : "new_day"
|
||||
%>
|
||||
<label class="checkbox inline btn btn-danger setting-form-remove">
|
||||
<% if f.object.new_record? %>
|
||||
<span class="delete_form" title="<%= t(:delete_) %>">
|
||||
X
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="remove_existing_record" title="<%= t(:remove) %>">
|
||||
<%= f.hidden_field :id %>
|
||||
<%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %>
|
||||
X
|
||||
</span>
|
||||
<% end %>
|
||||
</label>
|
||||
<div class="control-group">
|
||||
<%= f.label "time_title_#{key}_#{day}", t("property_hire.time_title"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.text_field :title, :id=>"time_title_#{key}_#{day}" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :start_time, t("property_hire.limit_start_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :start_time, :picker_type => "time", :no_label => true, :new_record => (@property.new_record? rescue true) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :end_time, t("property_hire.limit_end_time"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.datetime_picker :end_time, :picker_type => "time", :no_label => true, :new_record => (@property.new_record? rescue true) %>
|
||||
</div>
|
||||
</div>
|
||||
<%= f.hidden_field :key, :value => key, :data => {"type" => "key"} %>
|
||||
<%= f.hidden_field :day, :value => day, :data => {"type" => "day"} %>
|
||||
<div class="control-group">
|
||||
<%= f.label "reservation_limit_#{key}_#{day}", t("property_hire.reservation_limit"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.number_field :reservation_limit, :id=>"reservation_limit_#{key}_#{day}" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,6 @@
|
|||
<%= form_for @property , :url => {:action => "create"}, html: {class: "form-horizontal main-forms"} do |f| %>
|
||||
<fieldset>
|
||||
<%= f.hidden_field :copy_id %>
|
||||
<%= render :partial => "form", locals: {:f => f} %>
|
||||
</fieldset>
|
||||
<% end %>
|
|
@ -0,0 +1,44 @@
|
|||
<% content_for :page_specific_css do -%>
|
||||
<%= stylesheet_link_tag "lib/wrap-nav.css" %>
|
||||
<%= stylesheet_link_tag "lib/pageslide.css" %>
|
||||
<%= stylesheet_link_tag "lib/main-forms.css" %>
|
||||
<%= stylesheet_link_tag "lib/togglebox.css" %>
|
||||
<% end -%>
|
||||
|
||||
<% content_for :page_specific_javascript do -%>
|
||||
<%= javascript_include_tag "lib/jquery.tmpl.min.js" %>
|
||||
<%= javascript_include_tag "property_hire/property-field-forms.js" %>
|
||||
<% end -%>
|
||||
<style type="text/css">
|
||||
.input-append, .input-prepend{
|
||||
font-size: 1em;
|
||||
}
|
||||
</style>
|
||||
<%= form_for @attribute,:url => admin_property_hire_path(@attribute) , :html => { :class=> "form-horizontal main-forms" } do |f| %>
|
||||
<% if flash.now[:notice].present? %>
|
||||
<%= flash.now[:notice]%>
|
||||
<% end %>
|
||||
|
||||
<h3><%= @attribute.title %></h3>
|
||||
<fieldset>
|
||||
|
||||
<div id="attributes-area" class="input-area">
|
||||
<%= render partial: "attribute_field",collection: @attribute.p_hire_fields_enabled.asc(:_id)%>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-success add-attributes"><%= t(:add_attribute_field) %></button>
|
||||
<% referer = request.referer rescue nil %>
|
||||
<% referer = get_referer_url if referer.blank? || request.host != URI.parse(URI.encode(referer)).host %>
|
||||
<input type="hidden" name="referer_url" value="<%= referer %>">
|
||||
<%= hidden_field_tag 'id', params[:id] if !params[:id].blank? %>
|
||||
<%= f.submit t(:submit),:class=>"btn btn-primary"%>
|
||||
<%= link_to t('cancel'), get_go_back, :class=>"btn" %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% content_for :page_specific_javascript do -%>
|
||||
<%= render 'support_member_form_js' %>
|
||||
<% end -%>
|
|
@ -0,0 +1,940 @@
|
|||
<style type="text/css">
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.row{
|
||||
margin-left: 0;
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 0.9375em;
|
||||
clear: both;
|
||||
}
|
||||
@media (min-width:768px){
|
||||
.modal-content {
|
||||
-webkit-box-shadow: 0 0.3125em 0.9375em rgb(0 0 0 / 50%);
|
||||
box-shadow: 0 0.3125em 0.9375em rgb(0 0 0 / 50%);
|
||||
}
|
||||
.col-sm-offset-2 {
|
||||
margin-left: 16.66666667%;
|
||||
}
|
||||
.form-horizontal .control-label {
|
||||
padding-top: 0.4375em;
|
||||
margin-bottom: 0;
|
||||
width: auto;
|
||||
text-align: right;
|
||||
}
|
||||
[class*="col-sm"],[class*="col-md"]{
|
||||
float: left;
|
||||
position: relative;
|
||||
min-height: 0.0625em;
|
||||
padding-right: 0.9375em;
|
||||
padding-left: 0.9375em;
|
||||
}
|
||||
.form-horizontal .col-sm-2 {
|
||||
width: 16.66666667%;
|
||||
}
|
||||
.form-horizontal .col-sm-5 {
|
||||
width: 41.66666667%;
|
||||
}
|
||||
.form-horizontal .col-sm-10 {
|
||||
width: 83.33333333%;
|
||||
}
|
||||
.form-horizontal .col-md-4 > * {
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
.form-horizontal .col-md-8 > * {
|
||||
padding: 0 1em;
|
||||
}
|
||||
.form-horizontal .col-md-4{
|
||||
width: 33.3%;
|
||||
}
|
||||
.form-horizontal .col-md-8{
|
||||
width: 66.6%;
|
||||
}
|
||||
}
|
||||
.modal-content {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
border: 0.0625em solid #999;
|
||||
border: 0.0625em solid rgba(0,0,0,.2);
|
||||
border-radius: 0.375em;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: 0 0.1875em 0.5625em rgb(0 0 0 / 50%);
|
||||
box-shadow: 0 0.1875em 0.5625em rgb(0 0 0 / 50%);
|
||||
}
|
||||
.modal-header {
|
||||
padding: 0.9375em;
|
||||
border-bottom: 0.0625em solid #e5e5e5;
|
||||
}
|
||||
.modal-body {
|
||||
position: relative;
|
||||
padding: 0.9375em;
|
||||
max-height: 400px;
|
||||
overflow: initial;
|
||||
}
|
||||
.input-append{
|
||||
font-size: 1em;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<%= content_for :page_specific_css do %>
|
||||
<% ["basic/bootstrap-datetimepicker.css","property_hire_fullcalendar.css","property_hire_calendar"].each do |css| %>
|
||||
<%= stylesheet_link_tag css %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<script src="/assets/validator.js"></script>
|
||||
<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>
|
||||
<%
|
||||
hire = @phire
|
||||
property = @phire.property
|
||||
%>
|
||||
<% data = {"carousel_display_style"=>"width: #{property.carousel_image_width};"}
|
||||
recover = true
|
||||
allow_no_logins_user = false
|
||||
calendar_type = property.calendar_type.to_i rescue 0
|
||||
right_col = 12
|
||||
label_col = 2
|
||||
input_col = 10
|
||||
if calendar_type == 0
|
||||
right_col -= 7
|
||||
label_col += 2
|
||||
input_col -= 2
|
||||
end
|
||||
url = "admin"
|
||||
all_day_settings = property.all_day_settings
|
||||
%>
|
||||
<style type="text/css">
|
||||
.w-ba-banner{
|
||||
position: relative;
|
||||
}
|
||||
ul.list-unstyled li {
|
||||
list-style: none;
|
||||
}
|
||||
.s-annc__related-link-list, .s-annc__related-file-list{
|
||||
display: inline-block;
|
||||
}
|
||||
#sec1{
|
||||
float: left;
|
||||
}
|
||||
.btn-toolbar {
|
||||
margin-top: 0;
|
||||
}
|
||||
.form-group .controls{
|
||||
margin-left: 0;
|
||||
}
|
||||
@media (min-width: 1200px){
|
||||
.col-lg-7{
|
||||
width: 58.3%;
|
||||
float: left;
|
||||
}
|
||||
.col-lg-5{
|
||||
width: 41.7%;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px){
|
||||
.form-horizontal .col-sm-4 {
|
||||
width: 33.33333333%;
|
||||
}
|
||||
.form-horizontal .col-sm-8 {
|
||||
width: 66.66666667%;
|
||||
}
|
||||
.form-horizontal .col-sm-2 {
|
||||
width: 16.66666667%;
|
||||
}
|
||||
.form-horizontal .col-sm-10 {
|
||||
width: 83.33333333%;
|
||||
}
|
||||
.form-horizontal .col-sm-offset-4 {
|
||||
margin-left: 33.33%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
.full-size-img img {
|
||||
width: 100%;
|
||||
}
|
||||
.full-size-img {
|
||||
width: 100%;
|
||||
}
|
||||
.s-annc__sub-img.pull-right {
|
||||
margin-left: 2em;
|
||||
}
|
||||
.s-annc__sub-img.pull-left {
|
||||
margin-right: 2em;
|
||||
}
|
||||
strong.carousel__description {
|
||||
color: white;
|
||||
}
|
||||
.carousel_images{
|
||||
<%=data["carousel_display_style"]%>
|
||||
}
|
||||
@media (max-width: 767px){
|
||||
.carousel_images{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.carousel_img_item{
|
||||
display: none;
|
||||
float: left;
|
||||
}
|
||||
.controlplay {
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 3%;
|
||||
z-index: 200;
|
||||
}
|
||||
.controlplay a {
|
||||
display: inline-block;
|
||||
margin-right: 0.25em;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid rgba(255,255,255,0.5);
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.controlplay a i {
|
||||
font-family: FontAwesome;
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
color: #FFF;
|
||||
vertical-align: middle;
|
||||
font-style: unset;
|
||||
}
|
||||
.controlplay .resume-slide i::before {
|
||||
content: "\f04b";
|
||||
}
|
||||
.controlplay .pause-slide i::before {
|
||||
content: "\f04c";
|
||||
}
|
||||
ul.button-mid .prev-button {
|
||||
transition: 0.4s;
|
||||
position: relative;
|
||||
float: left;
|
||||
left: 0.5rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: #ffffff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
line-height: 2.5rem;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
z-index: 999;
|
||||
}
|
||||
ul.button-mid .next-button {
|
||||
float: right;
|
||||
transition: 0.4s;
|
||||
position: relative;
|
||||
right: 0.5rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: #fff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
line-height: 2.5rem;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
z-index: 999;
|
||||
}
|
||||
.carousel_images_slide{
|
||||
padding: 3em;
|
||||
}
|
||||
.carousel_img_item img{
|
||||
cursor: pointer;
|
||||
}
|
||||
@media (max-width: 479px){
|
||||
.carousel_img_item:nth-child(-n+1){
|
||||
display: block;
|
||||
width: 100%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 480px){
|
||||
.carousel_img_item:nth-child(-n+2){
|
||||
display: block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px){
|
||||
.carousel_img_item:nth-child(-n+3){
|
||||
display: block;
|
||||
width: 33%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 33%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1280px){
|
||||
.carousel_img_item:nth-child(-n+4){
|
||||
display: block;
|
||||
width: 25%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
form#hire_form .form-group input,form#hire_form .form-group select, form#hire_form .form-group textarea{
|
||||
min-width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
form#hire_form .form-group input[name="_rucaptcha"], form#hire_form .form-group input[type="submit"], form#hire_form .form-group input[type="radio"], form#hire_form .form-group input[type="checkbox"]{
|
||||
width: auto;
|
||||
min-width: auto;
|
||||
position: relative;
|
||||
margin-left: 0;
|
||||
}
|
||||
form#hire_form .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 0.375em 1.125em;
|
||||
font-size: 0.875em;
|
||||
line-height: 1.42857143;
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 0.0625em solid #ccc;
|
||||
border-radius: 0.25em;
|
||||
-webkit-box-shadow: inset 0 0.0625em 0.0625em rgb(0 0 0 / 8%);
|
||||
box-shadow: inset 0 0.0625em 0.0625em rgb(0 0 0 / 8%);
|
||||
-webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
||||
}
|
||||
.form-horizontal .form-group {
|
||||
margin-bottom: 0.9375em;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<% if !property.can_be_hired_frontend %>
|
||||
<script type="text/javascript">
|
||||
alert("This property is unavailable for hire.");
|
||||
window.location.href = "<%= "/" + I18n.locale.to_s + url %>";
|
||||
</script>
|
||||
<% end %>
|
||||
<% if !allow_no_logins_user && current_user.nil? %>
|
||||
<script type="text/javascript">
|
||||
alert("Please login before you hire.");
|
||||
window.location.href = "<%= "/" + I18n.locale.to_s + url %>";
|
||||
</script>
|
||||
<% else %>
|
||||
<script type="text/javascript">
|
||||
var pick_date_mode = <%=property.set_availability%>;
|
||||
</script>
|
||||
<h3 class="property_title"><%= property.title.html_safe %></h3>
|
||||
<article class="s-annc s-property">
|
||||
<section class="s-annc__post-wrap">
|
||||
<% if property.display_img %>
|
||||
<div class="s-annc__sub-img full-size-img">
|
||||
<img src="<%=property.image.url%>" alt="<%=property.title%>">
|
||||
<span class="s-annc__img_description"><%=property.title.html_safe%></span>
|
||||
</div>
|
||||
<% end %>
|
||||
<h4 class="property_subtitle"><%= property.property_usage.html_safe %></h4>
|
||||
<% property_carousel_images = property.property_carousel_images %>
|
||||
<% if property_carousel_images.count != 0 %>
|
||||
<div class="carousel_images">
|
||||
<div class="w-ba-banner ba-banner-widget-1">
|
||||
<div class="w-ba-banner__wrap cycle-slideshow"
|
||||
data-list="property_carousel_images"
|
||||
data-level="0"
|
||||
data-cycle-slides=".property_carousel_slide"
|
||||
data-cycle-log="false"
|
||||
data-cycle-auto-height="0"
|
||||
data-cycle-speed="300"
|
||||
data-cycle-timeout="5000"
|
||||
data-cycle-fx="fade"
|
||||
data-pager-active-class="active-slide"
|
||||
data-cycle-swipe=true
|
||||
data-cycle-swipe-fx="scrollHorz"
|
||||
>
|
||||
<% property_carousel_images.each do |carousel_image| %>
|
||||
<div class="w-ba-banner__slide property_carousel_slide"
|
||||
data-cycle-title="{{description_text}}"
|
||||
>
|
||||
<img class="w-ba-banner__image banner-responsive" src="<%=carousel_image.file.url %>" alt="<%=carousel_image.description_text %>">
|
||||
<div class="ad-overlay w-ad-banner__overlay property_carousel__overlay">
|
||||
<p><strong class="carousel__description"><%=carousel_image.description %></strong></p>
|
||||
</div>
|
||||
<div class="transitionfade"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<ul class="controlplay"><a class="resume-slide" title="<%=data["resume_btn_title"]%>"><i></i></a><a class="pause-slide" title="<%=data["pause_btn_title"]%>"><i></i></a></ul>
|
||||
<ul class="button-mid">
|
||||
<i class="fa fa-angle-left prev-button" aria-hidden="true" title="<%=data["prev_btn_title"]%>"></i>
|
||||
<i class="fa fa-angle-right next-button" aria-hidden="true" title="<%=data["next_btn_title"]%>"></i>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="property_note"><%= property.note.html_safe %></div>
|
||||
</section>
|
||||
<ul class="s-property__related-wrap list-unstyled no-print">
|
||||
<% if property.property_files.count != 0%>
|
||||
<li class="s-annc__related-file s-property__related-file">
|
||||
<i class="fa fa-fw fa-paperclip"></i>
|
||||
<div class="s-annc__related-file-list s-property__related-file-list" data-list="property_files" data-level="0">
|
||||
<% property.property_files.each do |property_file| %>
|
||||
<a class="s-annc__flie-title s-property__flie-title btn btn-default btn-sm" href="<%=property_file.file.url %>" title="<%=property_file.title %>"><%=property_file.title %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if property.property_links.count != 0%>
|
||||
<li class="s-annc__related-link s-property__related-link">
|
||||
<i class="fa fa-fw fa-link"></i>
|
||||
<div class="s-annc__related-link-list s-property__related-link-list" data-list="bulletin_links" data-level="0">
|
||||
<% property.property_links.each do |property_link| %>
|
||||
<a class="s-annc__link-title s-property__link-title btn btn-default btn-sm" href="<%=property_link.url %>" target="_blank"><%=property_link.display_title %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% 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>
|
||||
<script type="text/javascript">alert("<%= session["hire-save-msg"] %>")</script>
|
||||
<% session.delete("hire-save-msg") %>
|
||||
<% end %>
|
||||
</article>
|
||||
<% if property.calendar_type == 0 %>
|
||||
<div id="orbit_calendar" class="col-lg-<%=12-right_col%>">
|
||||
<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="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 class="pull-right">
|
||||
<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>
|
||||
</div>
|
||||
<div class="clearfix"></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 id="calendar-loading"></div>
|
||||
<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? && !recover,: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>
|
||||
</div>
|
||||
<div id="event_quick_view" class="modal" style="width: 300px; display:none; margin:0 0 0 0;"></div>
|
||||
<script type="text/javascript">
|
||||
var property_id = "<%= property.id.to_s %>";
|
||||
var calendar = new Calendar("#calendar",property_id);
|
||||
function pick_hire_date(date,allow_times){
|
||||
if(window.processing_hire)
|
||||
return;
|
||||
window.processing_hire = true;
|
||||
try{
|
||||
var date_target = $("#date_target_block").find("input");
|
||||
var offset = date_target.offset();
|
||||
if(date_target.val() == date){
|
||||
scrollTo(0,offset.top - 40);
|
||||
return;
|
||||
}
|
||||
$("#date_target_block").find("input").val(date);
|
||||
var select_target;
|
||||
if($("#hire_time_range_block").find("select").length == 0){
|
||||
select_target = $("<select name=\""+$("#hire_time_range_block").find("input").attr("name")+"\"></select>");
|
||||
$("#hire_time_range_block").find("input").remove();
|
||||
}
|
||||
else{
|
||||
select_target = $("#hire_time_range_block").find("select").eq(0);
|
||||
}
|
||||
select_target = select_target.empty();
|
||||
select_target.append("<option value=\"\"><%=t("property_hire.please_select")%></option>");
|
||||
allow_times.forEach(function(allow_time){
|
||||
select_target.append("<option value=\""+allow_time[2]+"\">"+allow_time[3]+"</option>");
|
||||
});
|
||||
select_target.appendTo($("#hire_time_range_block"));
|
||||
scrollTo(0,offset.top - 40);
|
||||
}catch(e){};
|
||||
window.processing_hire = false;
|
||||
}
|
||||
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");
|
||||
goto_calendar();
|
||||
}
|
||||
$("#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"){
|
||||
if(pick_date_mode){
|
||||
start_date = $("#p_hire_date").val();
|
||||
end_date = start_date;
|
||||
}else{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 offset = $('#orbit_calendar').offset();
|
||||
scrollTo(0,offset.top-40);
|
||||
window.setTimeout(function(){
|
||||
scrollTo(0,offset.top-40);
|
||||
},500);
|
||||
}
|
||||
</script>
|
||||
<% end %>
|
||||
<div class="col-lg-<%=right_col%>">
|
||||
<%= form_for hire, :url => "/xhr/property_hires/make_booking", html: { class: "form-horizontal", id: "hire_form" } do |f| %>
|
||||
<% if property.set_availability %>
|
||||
<div class="form-group">
|
||||
<%= f.label :date, "*"+t("property_hire.date"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>" id="date_target_block">
|
||||
<% if calendar_type == 0 %>
|
||||
<%= f.text_field :date, :value=>(recover ? f.object.date.to_s : t("property_hire.please_choose_date")),:readonly=>"",:onclick=>"goto_calendar()" %>
|
||||
<% else %>
|
||||
<%= f.datetime_picker :date, :no_label => true, :new_record => hire.new_record? && !recover ,:class => "pull-left", :picker_type => "date", :format=>"yyyy/MM/dd", :data=>{ "fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :time, "*"+t("property_hire.time"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>" id="hire_time_range_block">
|
||||
<% property_day_setting = recover ? hire.property_day_setting : nil %>
|
||||
<% if property_day_setting %>
|
||||
<%= select_tag "#{f.object_name}[time]", options_for_select([[t("property_hire.please_select"),""],[property_day_setting.title,property_day_setting.id.to_s]],hire.property_day_setting_id), :required=>"required" %>
|
||||
<% else %>
|
||||
<% if property.calendar_type == 0 %>
|
||||
<%= f.text_field :time, :value=>t("property_hire.please_choose_date"),:readonly=>"",:onclick=>"goto_calendar()" %>
|
||||
<% else %>
|
||||
<%= select_tag "#{f.object_name}[time]", options_for_select([[t("property_hire.please_choose_date"),""]]), :required=>"required" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="form-group">
|
||||
<%= f.label :start_time, "*"+t("property_hire.start_time"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<% if property.calendar_type == 0 %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%= f.datetime_picker :start_time, :no_label => true, :new_record => hire.new_record? && !recover,: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>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :end_time, "*"+t("property_hire.end_time"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%= f.datetime_picker :end_time, :no_label => true, :new_record => hire.new_record? && !recover,: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>
|
||||
<% end %>
|
||||
<!-- ############# recurring ############# -->
|
||||
<div class="form-group">
|
||||
<%= f.label :recurring, t("property_hire.recurring"), :class => "col-sm-#{label_col} 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-#{label_col} 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-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%= f.datetime_picker :recurring_end_date, :no_label => true, :new_record => hire.new_record? && !recover, :class=>"pull-left", :data=>{"fv-validation" => "requiredifrecurring;", "fv-messages" => "Cannot be empty;"} %>
|
||||
<% if calendar_type == 0 %>
|
||||
<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>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-<%=label_col%> col-sm-<%=input_col%>">
|
||||
<div id="property-avaialable-alert" style="margin-bottom: 5px; padding: 10px;<%= 'display: none;' unless recover %>" class="alert alert-success" role="alert"><%=t("property_hire.this_property_is_available",:default=>"<b>Hooray! </b>This property is available.").html_safe%></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-<%=label_col%> col-sm-<%=input_col%>">
|
||||
<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-<%=label_col%> control-label"></label>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<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>
|
||||
<% default_values = {"hiring_person_email" => ( current_user.member_profile.email rescue ""),
|
||||
"hiring_person_number" => ( current_user.member_profile.mobile_no rescue ""),
|
||||
"hiring_person_name" => ( current_user.name rescue "")
|
||||
} %>
|
||||
<% if recover
|
||||
default_values = default_values.merge(Property::FIELDSNAME.map{|f| [f,hire.send(f)]}.to_h)
|
||||
end %>
|
||||
<%= f.hidden_field :hiring_person_id, :value => (current_user.member_profile.id.to_s rescue "") %>
|
||||
<% custom_field_inputs = {} %>
|
||||
<% custom_field_type = {"note_for_hire"=>"text_area"} %>
|
||||
<% if(property.enable_notes_selector rescue false) %>
|
||||
<% custom_field_inputs["note_for_hire"] = render(:partial=>"property_hires/notes_selector",:locals=>{:f=>f,:property=>property,:label_col=>label_col,:input_col=>input_col,:hire=>hire}) %>
|
||||
<% end %>
|
||||
<% fields_name = property.get_all_fields %>
|
||||
<% has_p_hire_fields = property.p_hire_fields_enabled.count != 0
|
||||
p_hire_fields = {}
|
||||
if has_p_hire_fields
|
||||
p_hire_fields = property.p_hire_fields_enabled.map{|rf| [rf.id.to_s,rf]}.to_h
|
||||
end
|
||||
%>
|
||||
<% @form_index = 0 %>
|
||||
<% fields_name.each do |field_name| %>
|
||||
<% if has_p_hire_fields && field_name.include?("p_hire_fields") %>
|
||||
<div class="form-group">
|
||||
<% rf = p_hire_fields[field_name.sub("p_hire_fields.",'')] %>
|
||||
<% next if rf.nil? %>
|
||||
<%= rf.block_helper(property,@form_index,false,"p_hire",hire, rf.to_require,label_col) %>
|
||||
</div>
|
||||
<% @form_index = @form_index +1 %>
|
||||
<% else %>
|
||||
<% if(property[field_name]["enable"] == "1" rescue true) %>
|
||||
<% required = (property[field_name]["required"] == "true" rescue false) %>
|
||||
<% if custom_field_inputs[field_name] %>
|
||||
<%= custom_field_inputs[field_name] %>
|
||||
<% else %>
|
||||
<div class="form-group">
|
||||
<%= f.label field_name, (required ? "*" : "") + property.custom_text(field_name,"name"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<% placeholder = property.custom_text(field_name,"placeholder") %>
|
||||
<% if custom_field_type[field_name] %>
|
||||
<%= f.send(custom_field_type[field_name], field_name , {:class => "form-control", :placeholder => placeholder, :value => default_values[field_name], :data => (required ? {"fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} : nil)}) %>
|
||||
<% else %>
|
||||
<%= f.text_field field_name, :class => "form-control", :placeholder => placeholder, :value => default_values[field_name], :data => (required ? {"fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} : nil) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if allow_no_logins_user && current_user.nil? %>
|
||||
<!-- 驗證碼 -->
|
||||
<div class="form-group">
|
||||
<label for="note" class="col-sm-<%=label_col%> control-label"><%= t('property_hire.recaptcha.recaptcha') %></label>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%= gotcha_error %>
|
||||
<%= gotcha %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-<%=label_col%> col-sm-<%=input_col%>">
|
||||
<% if f.object.id.present? %>
|
||||
<%= f.hidden_field :id %>
|
||||
<% end %>
|
||||
<%= 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="<%=recover ? 1 : 0 %>" data-fv-validation="checkForDates;" data-fv-messages="Please make sure first if dates are available.;">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<div style="height: 50px;"></div>
|
||||
<script type="text/javascript">
|
||||
var property_id = "<%= property.id.to_s %>";
|
||||
var timezone = (new Date().getTimezoneOffset() / -60).toString();
|
||||
var all_day_settings = <%= all_day_settings.to_json.html_safe %>;
|
||||
if(timezone[0] != "-"){
|
||||
timezone = "+" + timezone;
|
||||
}
|
||||
$("#p_hire_date").on("change",function(){
|
||||
var _this = $(this);
|
||||
var date = new Date(_this.val());
|
||||
if(date.getTime()){
|
||||
var wday = date.getDay();
|
||||
var select_target = $("#p_hire_time");
|
||||
if(select_target.data("wday") == wday){
|
||||
return;
|
||||
}
|
||||
select_target.empty();
|
||||
select_target.data("wday",wday);
|
||||
if(all_day_settings[wday]){
|
||||
select_target.append("<option value=\"\"><%=t("property_hire.please_select")%></option>");
|
||||
all_day_settings[wday].forEach(function(allow_time){
|
||||
select_target.append("<option value=\""+allow_time[0]+"\">"+allow_time[1]+"</option>");
|
||||
});
|
||||
}else{
|
||||
select_target.append("<option value=\"\"><%=t("property_hire.no_time_can_select",:default=>"No time can be selected!")%></option>");
|
||||
}
|
||||
}
|
||||
})
|
||||
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"),
|
||||
time_setting_id = $("#hire_time_range_block select").val();
|
||||
if(Number.isNaN(new Date(stime).getDate())){
|
||||
window.check_message = "<%=t("property_hire.please_choose_date")%>";
|
||||
if(!check_only){
|
||||
$("#property-unavaialable-alert").find("span").html(window.check_message);
|
||||
$("#property-unavaialable-alert").show();
|
||||
}
|
||||
spinner.hide();
|
||||
el.show();
|
||||
return false;
|
||||
}
|
||||
if(time_setting_id == ""){
|
||||
window.check_message = "<%=t("property_hire.please_select_time")%>";
|
||||
if(!check_only){
|
||||
$("#property-unavaialable-alert").find("span").html(window.check_message);
|
||||
$("#property-unavaialable-alert").show();
|
||||
}
|
||||
$("#hire_time_range_block select").focus();
|
||||
$("#hire_time_range_block select").css("border","2px solid red");
|
||||
spinner.hide();
|
||||
el.show();
|
||||
return false;
|
||||
}
|
||||
stime = stime || etime;
|
||||
etime = etime || stime;
|
||||
property_id = property_id || window.property_id;
|
||||
data = {
|
||||
"stime": stime,
|
||||
"etime": etime,
|
||||
"property_id": property_id,
|
||||
"locale": "<%=I18n.locale%>",
|
||||
"timezone": timezone,
|
||||
"time_setting_id": time_setting_id,
|
||||
"phire_id": "<%=hire.id.to_s%>"
|
||||
}
|
||||
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;
|
||||
}
|
||||
$(document).on("change","#hire_time_range_block select",function(){
|
||||
$(this).css("border","");
|
||||
})
|
||||
$("#check-avail-btn").on("click",function(){
|
||||
var el = $(this),
|
||||
url = $(this).attr("href"),
|
||||
spinner = $("#spinner");
|
||||
$(".alert").hide();
|
||||
var stime, etime;
|
||||
if(pick_date_mode){
|
||||
stime = $("#p_hire_date").val();
|
||||
etime = stime;
|
||||
}else{
|
||||
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($("#hire_form"));
|
||||
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 %>
|
|
@ -0,0 +1,207 @@
|
|||
<style>
|
||||
.icons-list-2 {
|
||||
cursor: all-scroll;
|
||||
}
|
||||
legend{
|
||||
width: auto;
|
||||
text-align: center;
|
||||
padding: 0 1em;
|
||||
}
|
||||
.position-text-div {
|
||||
cursor: text;
|
||||
margin: -8px;
|
||||
padding: 8px;
|
||||
}
|
||||
.position-text-div:hover {
|
||||
background: aqua;
|
||||
}
|
||||
</style>
|
||||
<%= form_for @property , :url => {:action => "update_fields_display_order"}, html: {class: "form-horizontal main-forms"} do |f| %>
|
||||
<% p_hire_fields = @property.p_hire_fields_enabled.map{|rf| [rf.id.to_s,rf]}.to_h %>
|
||||
<fieldset>
|
||||
<legend><%= @property.title %></legend>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="enable_fields_sort"><%=t("property_hire.enable_fields_sort")%></label>
|
||||
<div class="controls">
|
||||
<%= f.check_box :enable_fields_sort, :id=>"enable_fields_sort" %>
|
||||
</div>
|
||||
</div>
|
||||
<div id="fields_sort_block" class="<%= 'hide' unless f.object.enable_fields_sort %>">
|
||||
<table width="100%" id="property_order_table" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><%= t("property_hire.sort_number") %></th>
|
||||
<th><%= t("property_hire.field_name") %></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @property.custom_field_names.each_with_index do |field_name,i| %>
|
||||
<% p_hire_field = nil
|
||||
if field_name.include?("p_hire_fields")
|
||||
p_hire_field = p_hire_fields[field_name.sub("p_hire_fields.",'')]
|
||||
next if p_hire_field.nil?
|
||||
end %>
|
||||
<tr data-index="<%=i%>">
|
||||
<td><span class="brand"><i class="icons-list-2"></i></span></td>
|
||||
<td class="position-text">
|
||||
<div class="position-text-div" data-value="<%= (i + 1).to_s %>"><%= (i + 1).to_s %></div>
|
||||
</td>
|
||||
<td>
|
||||
<% if p_hire_field %>
|
||||
<%= p_hire_field.title %>
|
||||
<% else %>
|
||||
<%= @property.custom_text(field_name) %>
|
||||
<% end %>
|
||||
<%= hidden_field_tag "#{f.object_name}[custom_field_names][]", field_name %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<% referer = request.referer rescue nil %>
|
||||
<% referer = get_referer_url if referer.blank? || request.host != URI.parse(URI.encode(referer)).host %>
|
||||
<%= f.submit t('submit'), class: 'btn btn-primary' %>
|
||||
<input type="hidden" name="referer_url" value="<%= referer %>">
|
||||
<%= link_to t('cancel'), referer, :class=>"btn" %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
<script>
|
||||
$("#enable_fields_sort").click(function(){
|
||||
$("#fields_sort_block").toggleClass("hide");
|
||||
update_table_cache_width();
|
||||
})
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var makeEditable = function(){
|
||||
var input_box = $("<input type='text'/>"),
|
||||
el = $(this);
|
||||
input_box.addClass("editable-input");
|
||||
input_box.val(el.data("value"));
|
||||
input_box.attr("data-old-id",el.data("value"));
|
||||
input_box.on("blur",function(){
|
||||
putBackdiv($(this));
|
||||
});
|
||||
input_box.on("keypress",function(e){
|
||||
if(e.keyCode == 13 || e.keyCode == 27){
|
||||
putBackdiv($(this),e.keyCode);
|
||||
}
|
||||
})
|
||||
el.parent().html(input_box);
|
||||
input_box.focus();
|
||||
}
|
||||
|
||||
var putBackdiv = function(el,keyCode){
|
||||
current_value = parseInt((el.val() == "" ? el.data("old-id") : el.val())),
|
||||
old_value = parseInt(el.data("old-id"));
|
||||
if(isNaN(current_value) || keyCode == 27){
|
||||
current_value = old_value;
|
||||
}
|
||||
if(old_value != current_value){
|
||||
var new_index_value = (current_value > old_value ? current_value + 1 : current_value - 1),
|
||||
div = $("<div class='position-text-div' data-value='" + current_value + "'>" + new_index_value + "</div>");
|
||||
div.on("click",makeEditable);
|
||||
el.parent().html(div);
|
||||
sortTable(el.data("old-id"),current_value);
|
||||
}else{
|
||||
var div = $("<div class='position-text-div' data-value='" + current_value + "'>" + current_value + "</div>");
|
||||
div.on("click",makeEditable);
|
||||
el.parent().html(div);
|
||||
}
|
||||
}
|
||||
var sortTable = function(changed_index,changed_to){
|
||||
var table_element = document.getElementById("property_order_table"),
|
||||
data = [],
|
||||
allRows = table_element.rows;
|
||||
for(i = 1; i < allRows.length; i++){
|
||||
var thisRow = allRows[i],
|
||||
text = thisRow.cells[1].textContent.trim(),
|
||||
hash = {};
|
||||
hash.index = parseInt(text);
|
||||
text = thisRow.cells[2].innerHTML.trim();
|
||||
if(text != " "){
|
||||
hash.property = text;
|
||||
}
|
||||
data.push(hash);
|
||||
}
|
||||
data = data.sort(function(a,b){return a.index - b.index});
|
||||
renderSortedTable(data,table_element);
|
||||
}
|
||||
var renderSortedTable = function(data,table_element){
|
||||
var allRows = table_element.rows;
|
||||
for(i = 0;i < data.length; i++){
|
||||
var thisRow = allRows[i + 1],
|
||||
current_value = i + 1;
|
||||
thisRow.cells[1].innerHTML = "<div class='position-text-div' data-value='" + current_value + "'>" + current_value + "</div>";
|
||||
thisRow.cells[2].innerHTML = data[i].property;
|
||||
}
|
||||
$("#property_order_table div.position-text-div").on("click",makeEditable);
|
||||
}
|
||||
$("#property_order_table div.position-text-div").on("click",makeEditable);
|
||||
</script>
|
||||
<script>
|
||||
window.update_table_cache_width = function(){
|
||||
$( ".table tbody" ).each(function(i,tbody){
|
||||
var table = $(tbody).parents("table").eq(0);
|
||||
table.data("index",i);
|
||||
th_width[i] = [];
|
||||
table.find("thead th").each(function(j,th){
|
||||
th_width[i].push($(th).outerWidth(true));
|
||||
})
|
||||
})
|
||||
}
|
||||
var th_width = {};
|
||||
$(document).ready(function(){
|
||||
update_table_cache_width();
|
||||
$( ".table tbody" ).sortable({
|
||||
revert: true,
|
||||
axis: "y",
|
||||
handle: ".brand",
|
||||
start: function(event, ui){
|
||||
var item = ui.item;
|
||||
var target = $(event.target);
|
||||
var index = target.parents(".table").eq(0).data("index");
|
||||
item.css("width",target.width());
|
||||
item.find("td").each(function(i,td){
|
||||
$(td).width(th_width[index][i]);
|
||||
})
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
var item = ui.item;
|
||||
item.css("width","");
|
||||
item.find("td").css("width","");
|
||||
},
|
||||
update: function(event, ui) {
|
||||
var item = ui.item;
|
||||
var org_index = item.data("index");
|
||||
console.log(org_index);
|
||||
var new_index = item.index();
|
||||
var indices = [org_index,new_index].sort();
|
||||
var table = item.parents(".table").eq(0);
|
||||
table.find("tbody tr").each(function(i,tr){
|
||||
if(i >= indices[0] && i <= indices[1]){
|
||||
var position_text_div = $(tr).find(".position-text-div");
|
||||
position_text_div.text(i+1).data("value",i+1);
|
||||
$(tr).data("index",i);
|
||||
}
|
||||
if(i > indices[1]){
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
})
|
||||
$(window).resize(function(){
|
||||
th_width = {};
|
||||
$( ".table tbody" ).each(function(i,tbody){
|
||||
var table = $(tbody).parents("table").eq(0);
|
||||
th_width[i] = [];
|
||||
table.find("thead th").each(function(j,th){
|
||||
th_width[i].push($(th).outerWidth(true));
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
|
@ -1,44 +1,74 @@
|
|||
<table class="table main-list">
|
||||
<thead>
|
||||
<tr class="sort-header">
|
||||
<% @table_fields.each do |f| %>
|
||||
<%= thead(f) %>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @properties.each do |property| %>
|
||||
<tr>
|
||||
<td>
|
||||
<% if can_edit_or_delete?(property) %>
|
||||
<a href="<%= admin_property_hire_path(property) %>"><%= property.title %></a>
|
||||
<div class="quick-edit">
|
||||
<ul class="nav nav-pills">
|
||||
<li><a href="<%= edit_admin_property_hire_path(property, :page => params[:page]) %>"><%= t(:edit) %></a></li>
|
||||
<li><a href="<%= admin_property_hire_path(property.id, :page => params[:page]) %>" data-method="delete" data-confirm="Are you sure?"><%= t(:delete_) %></a></li>
|
||||
</ul>
|
||||
<%= render_filter @filter_fields, "index_table" %>
|
||||
<span id="index_table">
|
||||
<%= render 'index'%>
|
||||
</span>
|
||||
<div id="downloadModal" data-backdrop="static" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="downloadModalLabel" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<h3 id="downloadModalLabel">Download</h3>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= property.title %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<%= property.category.title %>
|
||||
</td>
|
||||
<td>
|
||||
<%= property.get_location_name %>
|
||||
</td>
|
||||
<td>
|
||||
<% if property.can_be_hired %>
|
||||
<span class="badge badge-success">Yes</span>
|
||||
<% else %>
|
||||
<span class="badge badge-important">No</span>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="bottomnav clearfix">
|
||||
<%= content_tag(:div, paginate(@properties), class: "pagination pagination-centered") %>
|
||||
<div class="modal-body">
|
||||
<p id="wait-zone" style="text-align: center;">
|
||||
Please wait while we prepare your download. This may take a while.
|
||||
<br />
|
||||
<img src="/assets/spin.gif" />
|
||||
</p>
|
||||
<p id="link-zone" style="display: none; text-align: center;">
|
||||
Please click the link below to download.
|
||||
<br />
|
||||
<a href="" id="download-link" target="_blank">Download</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" id="modal-close-btn" style="display:none;" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="/assets/lib/process.manager.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var downloadModal = $("#downloadModal"),
|
||||
checkForThread = null,
|
||||
waitZone = $("#wait-zone"),
|
||||
linkZone = $("#link-zone"),
|
||||
downloadLink = $("a#download-link"),
|
||||
modalBtn = $("#modal-close-btn"),
|
||||
processManager = new ProcessManager();
|
||||
|
||||
$(document).on("click", ".export-xls", function(){
|
||||
var link = $(this).attr("href"),
|
||||
title = null,
|
||||
id = $(this).data("property-id");
|
||||
|
||||
linkZone.hide();
|
||||
waitZone.show();
|
||||
modalBtn.hide();
|
||||
$.ajax({
|
||||
url : link,
|
||||
type : "get",
|
||||
dataType : "json"
|
||||
}).done(function(data){
|
||||
title = data.title;
|
||||
checkForThread = new Process(function(){
|
||||
$.ajax({
|
||||
url : "/admin/property_hires/checkforthread",
|
||||
type : "get",
|
||||
data : {"property_id" : id, "property_title" : title},
|
||||
dataType : "json"
|
||||
}).done(function(data){
|
||||
if(!data.status){
|
||||
downloadLink.attr("href", "/uploads/reservation_export/" + id + "/" + title + ".xlsx");
|
||||
waitZone.hide();
|
||||
linkZone.show();
|
||||
modalBtn.show();
|
||||
checkForThread.kill();
|
||||
}
|
||||
})
|
||||
})
|
||||
checkForThread.setTimeInterval(1000);
|
||||
checkForThread.setRepeat(Process.CONSTANTS.REPEAT_INFINITE);
|
||||
processManager.queue(checkForThread);
|
||||
})
|
||||
downloadModal.modal("show");
|
||||
return false;
|
||||
})
|
||||
|
||||
</script>
|
|
@ -61,7 +61,7 @@
|
|||
<div class="bottomnav clearfix">
|
||||
<%= content_tag(:div, paginate(@locations), class: "pagination pagination-centered") %>
|
||||
<div class="pull-right">
|
||||
<%= link_to t(:add), add_location_admin_property_hires_path, :class => "btn btn-primary", :data => {"toggle" => "modal", "target" => "#location-modal"} %>
|
||||
<%= link_to t(:add), add_location_admin_property_hires_path, :id=>'create_new_location', :class => "btn btn-primary", :data => {"toggle" => "modal", "target" => "#location-modal"} %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -72,4 +72,16 @@
|
|||
$("#edit-location-btn").on("click",function(){
|
||||
$("#edit-location-modal form").submit();
|
||||
})
|
||||
$("#create_new_location").on("click",function(){
|
||||
var url = $(this).attr("href");
|
||||
$.get(url).done(function(data){
|
||||
$("#location-modal .modal-body").html(data);
|
||||
})
|
||||
})
|
||||
$('[data-target="#edit-location-modal"]').on("click",function(){
|
||||
var url = $(this).attr("href");
|
||||
$.get(url).done(function(data){
|
||||
$("#edit-location-modal .modal-body").html(data);
|
||||
})
|
||||
})
|
||||
</script>
|
|
@ -10,6 +10,9 @@
|
|||
<tbody>
|
||||
<% @bookings.each do |p_hire| %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= p_hire.property.title rescue nil %>
|
||||
</td>
|
||||
<td>
|
||||
<%= p_hire.hirer_name %>
|
||||
</td>
|
||||
|
@ -30,7 +33,11 @@
|
|||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
<a href="<%= show_booking_details_admin_property_hire_path(p_hire, :page => params[:page]) %>" class="btn btn-info">View</a>
|
||||
|
||||
|
||||
<a href="<%= delete_booking_details_admin_property_hire_path(p_hire, :page => params[:page]) %>" class="btn btn-danger" data-method="delete" data-confirm="Are you sure?">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
<% content_for :page_specific_css do %>
|
||||
<%= stylesheet_link_tag "admin/properties" %>
|
||||
<% end %>
|
||||
<style>
|
||||
.icons-list-2 {
|
||||
cursor: all-scroll;
|
||||
}
|
||||
.position-text-div {
|
||||
cursor: text;
|
||||
margin: -8px;
|
||||
padding: 8px;
|
||||
}
|
||||
.position-text-div:hover {
|
||||
background: aqua;
|
||||
}
|
||||
</style>
|
||||
<div class="order-edit-notification"><%= t("property_hire.please_save") %></div>
|
||||
<table width="100%" id="property_order_table" class="table table-striped" class="web_soursce_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><%= t("property_hire.position") %></th>
|
||||
<th><%= t("property_hire.title") %></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @properties.each_with_index do |property,i| %>
|
||||
<tr data-index="<%=i%>">
|
||||
<td><span class="brand"><i class="icons-list-2"></i></span></td>
|
||||
<td class="position-text">
|
||||
<div class="position-text-div" data-value="<%= (i + 1).to_s %>"><%= (i + 1).to_s %></div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="property-text-id" data-property-id="<%= property.id.to_s %>"><%= property.title %></div>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="bottomnav clearfix" style="left: 81px;">
|
||||
<div class="action pull-right">
|
||||
<a class="btn btn-info disabled" id="save-order-button" href="#"><%= t("property.save_order") %></a>
|
||||
</div>
|
||||
<div class="pagination pagination-centered"></div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
var makeEditable = function(){
|
||||
var input_box = $("<input type='text'/>"),
|
||||
el = $(this);
|
||||
input_box.addClass("editable-input");
|
||||
input_box.val(el.data("value"));
|
||||
input_box.attr("data-old-id",el.data("value"));
|
||||
input_box.on("blur",function(){
|
||||
putBackdiv($(this));
|
||||
});
|
||||
input_box.on("keypress",function(e){
|
||||
if(e.keyCode == 13 || e.keyCode == 27){
|
||||
putBackdiv($(this),e.keyCode);
|
||||
}
|
||||
})
|
||||
el.parent().html(input_box);
|
||||
input_box.focus();
|
||||
}
|
||||
|
||||
var putBackdiv = function(el,keyCode){
|
||||
current_value = parseInt((el.val() == "" ? el.data("old-id") : el.val())),
|
||||
old_value = parseInt(el.data("old-id"));
|
||||
if(isNaN(current_value) || keyCode == 27){
|
||||
current_value = old_value;
|
||||
}
|
||||
if(old_value != current_value){
|
||||
var new_index_value = (current_value > old_value ? current_value + 1 : current_value - 1),
|
||||
div = $("<div class='position-text-div' data-value='" + current_value + "'>" + new_index_value + "</div>");
|
||||
div.on("click",makeEditable);
|
||||
el.parent().html(div);
|
||||
$("#save-order-button").removeClass("disabled");
|
||||
$(".order-edit-notification").slideDown();
|
||||
sortTable(el.data("old-id"),current_value);
|
||||
}else{
|
||||
var div = $("<div class='position-text-div' data-value='" + current_value + "'>" + current_value + "</div>");
|
||||
div.on("click",makeEditable);
|
||||
el.parent().html(div);
|
||||
}
|
||||
}
|
||||
|
||||
var sortTable = function(changed_index,changed_to){
|
||||
var table_element = document.getElementById("property_order_table"),
|
||||
data = [],
|
||||
allRows = table_element.rows;
|
||||
for(i = 1; i < allRows.length; i++){
|
||||
var thisRow = allRows[i],
|
||||
text = thisRow.cells[1].textContent.trim(),
|
||||
hash = {};
|
||||
hash.index = parseInt(text);
|
||||
text = thisRow.cells[2].innerHTML.trim();
|
||||
if(text != " "){
|
||||
hash.property = text;
|
||||
}
|
||||
data.push(hash);
|
||||
}
|
||||
data = data.sort(function(a,b){return a.index - b.index});
|
||||
renderSortedTable(data,table_element);
|
||||
}
|
||||
|
||||
var renderSortedTable = function(data,table_element){
|
||||
var allRows = table_element.rows;
|
||||
for(i = 0;i < data.length; i++){
|
||||
var thisRow = allRows[i + 1],
|
||||
current_value = i + 1;
|
||||
thisRow.cells[1].innerHTML = "<div class='position-text-div' data-value='" + current_value + "'>" + current_value + "</div>";
|
||||
thisRow.cells[2].innerHTML = data[i].property;
|
||||
}
|
||||
$("#property_order_table div.position-text-div").on("click",makeEditable);
|
||||
}
|
||||
|
||||
$("#save-order-button").on("click",function(){
|
||||
var el = $(this);
|
||||
if(!el.hasClass("disabled")){
|
||||
var data = [];
|
||||
$("#property_order_table .property-text-id").each(function(){
|
||||
data.push($(this).data("property-id"));
|
||||
})
|
||||
$.ajax({
|
||||
url : "<%=updateorder_admin_property_hires_path%>",
|
||||
data : {"order" : data},
|
||||
dataType : "json",
|
||||
type : "post"
|
||||
}).done(function(){
|
||||
el.addClass("disabled");
|
||||
$(".order-edit-notification").slideUp();
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
$("#property_order_table div.position-text-div").on("click",makeEditable);
|
||||
|
||||
</script>
|
||||
<script>
|
||||
var th_width = {};
|
||||
$(document).ready(function(){
|
||||
$( ".table tbody" ).each(function(i,tbody){
|
||||
var table = $(tbody).parents("table").eq(0);
|
||||
table.data("index",i);
|
||||
th_width[i] = [];
|
||||
table.find("thead th").each(function(j,th){
|
||||
th_width[i].push($(th).outerWidth(true));
|
||||
})
|
||||
})
|
||||
$( ".table tbody" ).sortable({
|
||||
revert: true,
|
||||
axis: "y",
|
||||
handle: ".brand",
|
||||
start: function(event, ui){
|
||||
var item = ui.item;
|
||||
var target = $(event.target);
|
||||
var index = target.parents(".table").eq(0).data("index");
|
||||
item.css("width",target.width());
|
||||
item.find("td").each(function(i,td){
|
||||
$(td).width(th_width[index][i]);
|
||||
})
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
var item = ui.item;
|
||||
item.css("width","");
|
||||
item.find("td").css("width","");
|
||||
},
|
||||
update: function(event, ui) {
|
||||
var item = ui.item;
|
||||
var org_index = item.data("index");
|
||||
console.log(org_index);
|
||||
var new_index = item.index();
|
||||
var indices = [org_index,new_index].sort();
|
||||
var table = item.parents(".table").eq(0);
|
||||
table.find("tbody tr").each(function(i,tr){
|
||||
if(i >= indices[0] && i <= indices[1]){
|
||||
var position_text_div = $(tr).find(".position-text-div");
|
||||
position_text_div.text(i+1).data("value",i+1);
|
||||
$(tr).data("index",i);
|
||||
}
|
||||
if(i > indices[1]){
|
||||
return;
|
||||
}
|
||||
})
|
||||
$("#save-order-button").removeClass("disabled");
|
||||
$(".order-edit-notification").slideDown();
|
||||
}
|
||||
});
|
||||
})
|
||||
$(window).resize(function(){
|
||||
th_width = {};
|
||||
$( ".table tbody" ).each(function(i,tbody){
|
||||
var table = $(tbody).parents("table").eq(0);
|
||||
th_width[i] = [];
|
||||
table.find("thead th").each(function(j,th){
|
||||
th_width[i].push($(th).outerWidth(true));
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
|
@ -6,6 +6,18 @@
|
|||
<% content_for :page_specific_javascript do %>
|
||||
<%= javascript_include_tag "lib/module-area" %>
|
||||
<% end %>
|
||||
<style>
|
||||
.time_setting_form, .image_group{
|
||||
border: 0.2em solid #333;
|
||||
padding-top: 0;
|
||||
}
|
||||
.add-on.iconbtn{
|
||||
display: none;
|
||||
}
|
||||
.time_setting_form:last-child, .image_group:last-child {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
||||
<%= form_for @settings , :url => settings_admin_property_hires_path, html: {class: "form-horizontal main-forms"} do |f| %>
|
||||
<fieldset>
|
||||
<% if @saved %>
|
||||
|
@ -23,12 +35,68 @@
|
|||
<div class="tab-content module-area">
|
||||
<!-- Basic Module -->
|
||||
<div class="tab-pane fade in active" id="basic">
|
||||
<div class="control-group">
|
||||
<%= f.label :allow_no_logins_user, t("property_hire.allow_no_logins_user"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :allow_no_logins_user %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :calendar_type, t("property_hire.display_calendar_default"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :calendar_type, {}, "0", "1" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :auto_approve, t("property_hire.auto_approve"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :auto_approve %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :disable_content_page, t("property_hire.disable_content_page"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :disable_content_page %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :disable_view_calendar_page, t("property_hire.disable_view_calendar_page"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :disable_view_calendar_page %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :disable_no_logins_view_calendar, t("property_hire.disable_no_logins_view_calendar"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.check_box :disable_no_logins_view_calendar %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :carousel_image_width, t("property_hire.default_carousel_image_width"), :class => "control-label muted" %>
|
||||
<div class="controls">
|
||||
<%= f.text_field :carousel_image_width %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<%= f.label :default_time_settings, t("property_hire.default_time_settings"), :class => "control-label muted" %>
|
||||
<% default_time_settings = f.object.default_time_settings %>
|
||||
<% setting_count = 0 %>
|
||||
<div class="controls">
|
||||
<div id="default_time_settings">
|
||||
<% if default_time_settings %>
|
||||
<% default_time_settings.each_with_index do |setting,j| %>
|
||||
<%= f.fields_for :property_day_settings do |f| %>
|
||||
<%= f.fields_for setting_count.to_s, setting do |f| %>
|
||||
<%= render :partial => "time_form", :locals=>{:key=>j,:day=>0,:f=>f} %>
|
||||
<% setting_count += 1 %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<a class="btn btn-primary add_weekday_setting" data-target="#default_time_settings" data-count="<%= default_time_settings.count %>" data-day="0"><%=t(:add)%></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,4 +105,59 @@
|
|||
<%= f.submit t('submit'), class: 'btn btn-primary' %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<script>
|
||||
var setting_count = <%=setting_count%>;
|
||||
$(".add_weekday_setting").click(function(){
|
||||
var target = $($(this).data("target"));
|
||||
var key = $(this).data("count");
|
||||
var day = $(this).data("day");
|
||||
var new_key = $(this).prev().attr('value');
|
||||
var old_key = new RegExp("new_key", "g");
|
||||
var new_day = day;
|
||||
var old_day = new RegExp("new_day", "g");
|
||||
var new_key = key;
|
||||
key += 1;
|
||||
$(this).data("count",key);
|
||||
var old_index = new RegExp("new_index", "g");
|
||||
var new_index = setting_count;
|
||||
setting_count += 1;
|
||||
<% property_day_setting = PropertyDaySetting.new(:id=>nil,:property_id=>"default_settings") %>
|
||||
<%= f.fields_for :property_day_settings do |f| %>
|
||||
<%= f.fields_for "new_index",property_day_setting do |f| %>
|
||||
var template_html = "<%= escape_javascript(render(:partial=>"time_form",:locals=>{:f=>f})) %>";
|
||||
<%end%>
|
||||
<%end%>
|
||||
var tmp = $(template_html.replace(old_index,new_index).replace(old_key,new_key).replace(old_day,new_day));
|
||||
target.append(tmp);
|
||||
tmp.find("input[data-format]").each(function(i,input){
|
||||
var $input = $(input);
|
||||
var format = $input.data("format"),
|
||||
timeOnly = !(format.match(/Y|M|d/)), timeFormat, dateFormat = "";
|
||||
if(timeOnly){
|
||||
timeFormat = format;
|
||||
}else{
|
||||
dateFormat = format.match(/yy(\/|-|)(mm|)(\/|-|)(dd|)/i)[0];
|
||||
timeFormat = $.trim(format.replace(dateFormat,""));
|
||||
}
|
||||
var options = {dateFormat: dateFormat,timeFormat: timeFormat,timeOnly: timeOnly};
|
||||
var additionalOptions = $input.data();
|
||||
$.extend(options, additionalOptions);
|
||||
$input.ui_datetimepicker(options);
|
||||
$input.siblings('.clearDate').click(function(){
|
||||
$input.val('');
|
||||
$input.trigger('change');
|
||||
});
|
||||
})
|
||||
})
|
||||
$(document).on('click', '.setting-form-remove', function(){
|
||||
if($(this).find(".remove_existing_record").length != 0){
|
||||
if(confirm("<%= I18n.t(:sure?)%>")){
|
||||
$(this).find('.should_destroy').attr('value', 1);
|
||||
$(this).parents('.time_setting_form').hide();
|
||||
}
|
||||
}else{
|
||||
$(this).parents('.time_setting_form').remove();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<% end %>
|
|
@ -1,4 +1,96 @@
|
|||
<%= csrf_meta_tag %>
|
||||
<div class="pull-right">
|
||||
<a href="?type=" class="btn <%= 'active' if params[:type] != 'Calendar' %>"><%= t("property_hire.table") %></a>
|
||||
<a href="?type=Calendar" class="btn <%= 'active' if params[:type] == 'Calendar' %>"><%= t("property_hire.calendar") %></a>
|
||||
</div>
|
||||
<hr>
|
||||
<% if params[:type] == "Calendar" %>
|
||||
<style type="text/css">
|
||||
.row{
|
||||
margin-left: 0;
|
||||
}
|
||||
.modal-content {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #999;
|
||||
border: 1px solid rgba(0,0,0,0.2);
|
||||
border-radius: 6px;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: 0 3px 9px rgb(0 0 0 / 50%);
|
||||
box-shadow: 0 3px 9px rgb(0 0 0 / 50%);
|
||||
}
|
||||
@media (min-width:768px){
|
||||
.modal-content {
|
||||
-webkit-box-shadow: 0 5px 15px rgb(0 0 0 / 50%);
|
||||
box-shadow: 0 5px 15px rgb(0 0 0 / 50%);
|
||||
}
|
||||
.col-md-4 > * {
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
.col-md-8 > * {
|
||||
padding: 0 1em;
|
||||
}
|
||||
.col-md-4{
|
||||
float: left;
|
||||
width: 33.3%;
|
||||
}
|
||||
.col-md-8{
|
||||
float: left;
|
||||
width: 66.6%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<%= content_for :page_specific_css do %>
|
||||
<% ["basic/bootstrap-datetimepicker.css","property_hire_fullcalendar.css","property_hire_calendar"].each do |css| %>
|
||||
<%= stylesheet_link_tag css %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<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>
|
||||
<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 mode_switch btn-sm" data-mode="dayGridMonth" >month</button>
|
||||
<button class="btn btn-default active mode_switch btn-sm" data-mode="agenda" >agenda</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,"agenda",false);
|
||||
</script>
|
||||
<% else %>
|
||||
<table class="table main-list">
|
||||
<thead>
|
||||
<tr class="sort-header">
|
||||
|
@ -14,7 +106,7 @@
|
|||
<%= p_hire.hirer_name %>
|
||||
</td>
|
||||
<td>
|
||||
<%= p_hire.reason_for_hire %>
|
||||
<%= p_hire.reason_for_hire.to_s + p_hire.tmp_reason_for_hire %>
|
||||
</td>
|
||||
<td>
|
||||
<%= p_hire.hiring_person_number %>
|
||||
|
@ -31,13 +123,14 @@
|
|||
</td>
|
||||
<td>
|
||||
<% if can_edit_or_delete?(p_hire.property) %>
|
||||
<a href="<%= show_booking_details_admin_property_hire_path(p_hire, :page => params[:page]) %>" class="btn btn-info">View</a>
|
||||
<a href="<%= edit_hire_admin_property_hire_path(p_hire) %>" class="btn btn-info"><%= t("property_hire.edit") %></a>
|
||||
<a href="<%= show_booking_details_admin_property_hire_path(p_hire, :page => params[:page]) %>" class="btn btn-info"><%= t("property_hire.view") %></a>
|
||||
<% if p_hire.passed %>
|
||||
<a href="<%= pass_booking_admin_property_hire_path(p_hire, :page => params[:page], :status => "reject", :ref => "index") %>" class="btn btn-warning">Reject</a>
|
||||
<a href="<%= pass_booking_admin_property_hire_path(p_hire, :page => params[:page], :status => "reject", :ref => "index") %>" class="btn btn-warning"><%= t("property_hire.reject") %></a>
|
||||
<% else %>
|
||||
<a href="<%= pass_booking_admin_property_hire_path(p_hire, :page => params[:page], :status => "accept", :ref => "index") %>" class="btn btn-success">Accept</a>
|
||||
<a href="<%= pass_booking_admin_property_hire_path(p_hire, :page => params[:page], :status => "accept", :ref => "index") %>" class="btn btn-success"><%= t("property_hire.accept") %></a>
|
||||
<% end %>
|
||||
<a href="<%= delete_booking_details_admin_property_hire_path(p_hire, :page => params[:page]) %>" class="btn btn-danger" data-method="delete" data-confirm="Are you sure?">Delete</a>
|
||||
<a href="<%= delete_booking_details_admin_property_hire_path(p_hire, :page => params[:page]) %>" class="btn btn-danger" data-method="delete" data-confirm="Are you sure?"><%= t("property_hire.delete") %></a>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -48,3 +141,4 @@
|
|||
<a href="<%= admin_property_hires_path %>" class="btn btn-warning">Back</a>
|
||||
<%= content_tag(:div, paginate(@bookings), class: "pagination pagination-centered") %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,5 +1,6 @@
|
|||
<%= csrf_meta_tag %>
|
||||
<h3><%= @booking.property.title %></h3>
|
||||
<% property = @booking.property %>
|
||||
<h3><%= property.title %></h3>
|
||||
<table class="table main-list">
|
||||
<tbody>
|
||||
<tr>
|
||||
|
@ -34,8 +35,26 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><%= t("property_hire.note_for_hire") %></td>
|
||||
<td><%= @booking.note_for_hire %></td>
|
||||
<td><%= @booking.note_for_hire.html_safe %></td>
|
||||
</tr>
|
||||
<% 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) %>
|
||||
<tr>
|
||||
<td><%= property.custom_text(field_name,"name") %></td>
|
||||
<td><%= @booking[field_name].to_s %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% @booking.p_hire_field_values.each do |v| %>
|
||||
<% field_info = v.get_field_value rescue {} %>
|
||||
<% if field_info["title"].present? && !field_info["value"].nil? && !field_info["hint"] %>
|
||||
<tr>
|
||||
<td><%=field_info["title"]%>: </td>
|
||||
<td><%=field_info["value"]%></td>
|
||||
</tr>
|
||||
<% end%>
|
||||
<% end%>
|
||||
<tr>
|
||||
<td><%= t("property_hire.passed") %></td>
|
||||
<td>
|
||||
|
@ -50,12 +69,13 @@
|
|||
</table>
|
||||
<a href="" onclick="window.history.back();return false;" class="btn btn-warning">Back</a>
|
||||
<% if can_edit_or_delete?(@booking.property) %>
|
||||
<a href="<%= edit_hire_admin_property_hire_path(@booking) %>" class="btn btn-info"><%= t("property_hire.edit") %></a>
|
||||
<% if @booking.passed %>
|
||||
<a href="<%= pass_booking_admin_property_hire_path(@booking, :status => "reject") %>" class="btn btn-warning">Reject</a>
|
||||
<a href="<%= pass_booking_admin_property_hire_path(@booking, :status => "reject") %>" class="btn btn-warning"><%= t("property_hire.reject") %></a>
|
||||
<% else %>
|
||||
<a href="<%= pass_booking_admin_property_hire_path(@booking, :status => "accept") %>" class="btn btn-success">Accept</a>
|
||||
<a href="<%= pass_booking_admin_property_hire_path(@booking, :status => "accept") %>" class="btn btn-success"><%= t("property_hire.accept") %></a>
|
||||
<% end %>
|
||||
<a href="<%= delete_booking_details_admin_property_hire_path(@booking, :page => params[:page]) %>" class="btn btn-danger" data-method="delete" data-confirm="Are you sure?">Delete</a>
|
||||
<a href="<%= delete_booking_details_admin_property_hire_path(@booking, :page => params[:page]) %>" class="btn btn-danger" data-method="delete" data-confirm="Are you sure?"><%= t("property_hire.delete") %></a>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<% if !@data['email_set_content'].nil? %>
|
||||
<% email_set_content = YAML.load(@data['email_set_content'])
|
||||
now_locale = @data['locale'] %>
|
||||
<%= email_set_content[now_locale].html_safe rescue nil %>
|
||||
<% end %>
|
||||
<br>
|
||||
<%= @data['content'].html_safe %>
|
||||
|
||||
<% property = Property.where(id: @data['property_id']).first %>
|
||||
<% if !property.nil? %>
|
||||
<h3><%= property.title_translations.collect{|k,v| v}.select{|v| v.present?}.uniq.join('/') rescue nil %></h3>
|
||||
<% I18n.with_locale(@data['locale']) do %>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% ['editor','property_usage','note','category','property_location','property_number','can_be_hired','purchase_date','owners','other_owner','owner_email','owner_phone','price'].each do |k| %>
|
||||
<% v = property.send(k) rescue nil %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= k=='category' ? t('category') : t("property_hire.#{k}") %>:
|
||||
</td>
|
||||
<td>
|
||||
<% if k == 'editor' %>
|
||||
<%= User.find(user_id).name rescue nil %>
|
||||
<% elsif ['purchase_date'].include?(k) %>
|
||||
<%= v.strftime('%Y/%m/%d %H:%M') rescue nil %>
|
||||
<% elsif ['property_usage','note'].include?(k) %>
|
||||
<%= property.send("#{k}_translations").collect{|k,v| v}.select{|v| v.present?}.uniq.join('/') rescue nil %>
|
||||
<% elsif k=='owners' %>
|
||||
<%= property.owner_profiles.collect{|v| v.name}.join(', ') %>
|
||||
<% elsif ['category','property_location'].include?(k) %>
|
||||
<%= v.title %>
|
||||
<% elsif k == 'can_be_hired' %>
|
||||
<%= v ? t('yes_') : t('no_') %>
|
||||
<% else %>
|
||||
<%= v %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
<% end %>
|
|
@ -0,0 +1,47 @@
|
|||
<% property = Property.where(id: @data['property_id']).first %>
|
||||
<% email_set = property.hire_email_sets.select{|v| v.field_name == 'edit'} %>
|
||||
<% if email_set.length != 0 %>
|
||||
<% if !(email_set[0].content.nil?) %>
|
||||
<%= email_set[0].content[@data['locale']].html_safe %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= t('property_hire.email_edit_success') %>
|
||||
<% end %>
|
||||
<h3><%= property.title_translations.collect{|k,v| v}.select{|v| v.present?}.uniq.join('/') rescue nil %></h3>
|
||||
<% I18n.with_locale(@data['locale']) do %>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% ['editor','property_usage','note','category','property_location','property_number','can_be_hired','purchase_date','owners','other_owner','owner_email','owner_phone','price'].each do |k| %>
|
||||
<% v = property.send(k) rescue nil %>
|
||||
<tr>
|
||||
<td>
|
||||
<%= k=='category' ? t('category') : t("property_hire.#{k}") %>:
|
||||
</td>
|
||||
<td>
|
||||
<% if k == 'editor' %>
|
||||
<%= User.find(user_id).name rescue nil %>
|
||||
<% elsif ['purchase_date'].include?(k) %>
|
||||
<%= v.strftime('%Y/%m/%d %H:%M') rescue nil %>
|
||||
<% elsif ['property_usage','note'].include?(k) %>
|
||||
<%= property.send("#{k}_translations").collect{|k,v| v}.select{|v| v.present?}.uniq.join('/') rescue nil %>
|
||||
<% elsif k=='owners' %>
|
||||
<%= property.owner_profiles.collect{|v| v.name}.join(', ') rescue nil %>
|
||||
<% elsif ['category','property_location'].include?(k) %>
|
||||
<%= v.title rescue nil %>
|
||||
<% elsif k == 'can_be_hired' %>
|
||||
<%= v ? t('yes_') : t('no_') %>
|
||||
<% else %>
|
||||
<%= v %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
|
@ -0,0 +1,95 @@
|
|||
<% property = Property.where(id: @data['property_id']).first%>
|
||||
<% email_set = property.hire_email_sets.select{|v| v.field_name == 'p_hire'} %>
|
||||
<% if email_set.length != 0 %>
|
||||
<% if !(email_set[0].content.nil?) %>
|
||||
<%= email_set[0].content[@data['locale']].html_safe %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= t('property_hire.email_p_hire_content') %>
|
||||
<% end %>
|
||||
<br>
|
||||
<style>
|
||||
.hire_infos td:first-child {
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
<% I18n.with_locale(@data['locale']) do %>
|
||||
<h3><%= property.title rescue nil %></h3>
|
||||
<% if !@data['hire_id'].nil? %>
|
||||
<% hire = PHire.where(id: @data['hire_id']).first %>
|
||||
<table id="hire_infos">
|
||||
<thead>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%
|
||||
p_hire_fields = property.p_hire_fields_enabled.map{|rf| [rf.id.to_s,rf]}.to_h
|
||||
fields_name = property.get_all_fields
|
||||
basic_keys = []
|
||||
if (property.set_availability rescue false)
|
||||
basic_keys = ['date','time','hiring_person_name','hiring_person_email','recurring','recurring_interval','recurring_end_date','passed']
|
||||
else
|
||||
basic_keys = ['hiring_person_name','hiring_person_email','start_time','end_time','recurring','recurring_interval','recurring_end_date','passed']
|
||||
end
|
||||
fields_name = fields_name - basic_keys
|
||||
keys = basic_keys + fields_name
|
||||
keys = keys.select do |field_name|
|
||||
return true if field_name.include?('p_hire_fields.')
|
||||
tmp = property[field_name]
|
||||
tmp.is_a?(Hash) ? (tmp["enable"] == "1") : true
|
||||
end
|
||||
p_hire_fields = property.p_hire_fields_enabled.map{|rf| [rf.id.to_s,rf]}.to_h
|
||||
has_p_hire_fields = p_hire_fields.count != 0
|
||||
tmp_keys = []
|
||||
all_trans = keys.map do |k|
|
||||
if has_p_hire_fields && k.include?("p_hire_fields")
|
||||
tmp_keys << k.sub("p_hire_fields.",'')
|
||||
nil
|
||||
else
|
||||
tmp_keys << k
|
||||
property.custom_text(k,"name")
|
||||
end
|
||||
end
|
||||
%>
|
||||
<% p_hire_field_values = hire.p_hire_field_values.to_a %>
|
||||
<% keys.each_with_index do |k,i| %>
|
||||
<% if has_p_hire_fields && k.include?("p_hire_fields")
|
||||
p_hire_field_id = tmp_keys[i]
|
||||
v = p_hire_field_values.select{|v| v.p_hire_field_id.to_s == p_hire_field_id}.first
|
||||
field_info = v.get_field_value rescue {}
|
||||
if field_info["title"].present? && !field_info["value"].nil?
|
||||
all_trans[i] = field_info["title"]
|
||||
v = field_info["value"]
|
||||
end
|
||||
else
|
||||
v = hire.send(k)
|
||||
end
|
||||
%>
|
||||
<% if !v.nil? && !(k.include?('recurring') && hire.recurring != true)%>
|
||||
<tr>
|
||||
<td>
|
||||
<%= all_trans[i] %>:
|
||||
</td>
|
||||
<td>
|
||||
<% if ['start_time','end_time','recurring','recurring_interval','recurring_end_date','passed'].exclude?(k) %>
|
||||
<%= v.to_s.html_safe %>
|
||||
<% elsif ['start_time','end_time','recurring_end_date'].include?(k) %>
|
||||
<%= v.strftime('%Y/%m/%d %H:%M') rescue nil %>
|
||||
<% elsif k == 'recurring_interval' %>
|
||||
<%= t("property_hire.recurring_interval_types.#{v}") %>
|
||||
<% elsif 'recurring' == k %>
|
||||
<%= v ? t('property_hire.yes') : t('property_hire.no') %>
|
||||
<% else %>
|
||||
<%= v ? t('property_hire.yes') : t('property_hire.wait_for_permit') %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
<% end %>
|
|
@ -0,0 +1,51 @@
|
|||
# encoding: utf-8
|
||||
|
||||
wb = xlsx_package.workbook
|
||||
|
||||
wb.add_worksheet(name: "Reservations") do |sheet|
|
||||
heading = sheet.styles.add_style(:b => true, :locked => true)
|
||||
type = sheet.styles.add_style(:i => true)
|
||||
wrap = sheet.styles.add_style alignment: {wrap_text: true}
|
||||
|
||||
row = [
|
||||
t("property_hire.hiring_person_name"),
|
||||
t("property_hire.hiring_person_number"),
|
||||
t("property_hire.hiring_person_email"),
|
||||
t("property_hire.period"),
|
||||
t("property_hire.recurring_interval"),
|
||||
t("property_hire.recurring_end_date"),
|
||||
t("property_hire.reason_for_hire"),
|
||||
t("property_hire.note_for_hire")
|
||||
]
|
||||
|
||||
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)
|
||||
row << property.custom_text(field_name,"name")
|
||||
end
|
||||
end
|
||||
|
||||
sheet.add_row row, :style => heading
|
||||
|
||||
property.p_hires.asc(:created_at).each do |entry|
|
||||
row = [
|
||||
entry.hirer_name,
|
||||
entry.hiring_person_number,
|
||||
entry.hiring_person_email,
|
||||
entry.period,
|
||||
entry.recurring_interval,
|
||||
entry.recurring_end_date,
|
||||
entry.reason_for_hire,
|
||||
entry.note_for_hire.html_safe
|
||||
]
|
||||
entry.p_hire_field_values.each do |v|
|
||||
field_info = v.get_field_value rescue {}
|
||||
if field_info["title"].present? && !field_info["value"].nil? && !field_info["hint"]
|
||||
row << field_info["title"] + ": " + field_info["value"]
|
||||
end
|
||||
end
|
||||
sheet.add_row row, style: wrap
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,50 @@
|
|||
<%
|
||||
hire = (defined?(hire) ? hire : nil)
|
||||
if hire
|
||||
notes_selector_value = hire.note_for_hire.split('<br>').map{|s| s.split(':', 2)}.to_h
|
||||
use_default = false
|
||||
else
|
||||
use_default = true
|
||||
end
|
||||
%>
|
||||
<% 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-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%
|
||||
if use_default
|
||||
if type == "radio"
|
||||
selected_indices = [0]
|
||||
else
|
||||
selected_indices = []
|
||||
end
|
||||
else
|
||||
selected_indices = []
|
||||
sub_hash["name"].each do |l, k|
|
||||
if notes_selector_value.has_key?(k)
|
||||
sub_hash["value"][l].each_with_index do |v, i|
|
||||
if notes_selector_value[k].match(/(^|,)#{::Regexp.escape(v)}(,|$)/)
|
||||
selected_indices << i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
%>
|
||||
<% values.each_with_index do |v,i| %>
|
||||
<label class="checkbox-inline">
|
||||
<input type="<%=type%>" name="p_hire[notes_selector][<%=index.to_s%>][]" value="<%=i%>" <%= (selected_indices.include?(i)) ? "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 %>
|
|
@ -1,188 +1,782 @@
|
|||
<% OrbitHelper.render_css_in_head(["basic/bootstrap-datetimepicker.css"]) %>
|
||||
<%= javascript_include_tag "lib/bootstrap-datetimepicker" %>
|
||||
<%= javascript_include_tag "lib/datetimepicker/datetimepicker.js" %>
|
||||
<% 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>
|
||||
<script type="text/javascript" src="/assets/locale-all.min.js"></script>
|
||||
|
||||
<%= javascript_include_tag "basic/jquery.nanoscroller.js" %>
|
||||
<%
|
||||
data = action_data
|
||||
hire = data["hire"]
|
||||
property = data["property"]
|
||||
is_user_manager = data["is_user_manager"]
|
||||
url = data["page"]
|
||||
current_user = data["current_user"]
|
||||
allow_no_logins_user = data["allow_no_logins_user"]
|
||||
all_day_settings = data["all_day_settings"]
|
||||
recover = data["recover"]
|
||||
locale = data["language"]
|
||||
calendar_type = property.calendar_type.to_i rescue 0
|
||||
right_col = 12
|
||||
label_col = 2
|
||||
input_col = 10
|
||||
if calendar_type == 0
|
||||
right_col -= 7
|
||||
label_col += 2
|
||||
input_col -= 2
|
||||
end
|
||||
%>
|
||||
|
||||
<style type="text/css">
|
||||
.full-size-img img {
|
||||
width: 100%;
|
||||
}
|
||||
.full-size-img {
|
||||
width: 100%;
|
||||
}
|
||||
.s-annc__sub-img.pull-right {
|
||||
margin-left: 2em;
|
||||
}
|
||||
.s-annc__sub-img.pull-left {
|
||||
margin-right: 2em;
|
||||
}
|
||||
strong.carousel__description {
|
||||
color: white;
|
||||
}
|
||||
.carousel_images{
|
||||
<%=data["carousel_display_style"]%>
|
||||
}
|
||||
@media (max-width: 767px){
|
||||
.carousel_images{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.carousel_img_item{
|
||||
display: none;
|
||||
float: left;
|
||||
}
|
||||
.controlplay {
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 3%;
|
||||
z-index: 200;
|
||||
}
|
||||
.controlplay a {
|
||||
display: inline-block;
|
||||
margin-right: 0.25em;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid rgba(255,255,255,0.5);
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.controlplay a i {
|
||||
font-family: FontAwesome;
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
color: #FFF;
|
||||
vertical-align: middle;
|
||||
font-style: unset;
|
||||
}
|
||||
.controlplay .resume-slide i::before {
|
||||
content: "\f04b";
|
||||
}
|
||||
.controlplay .pause-slide i::before {
|
||||
content: "\f04c";
|
||||
}
|
||||
ul.button-mid .prev-button {
|
||||
transition: 0.4s;
|
||||
position: relative;
|
||||
float: left;
|
||||
left: 0.5rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: #ffffff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
line-height: 2.5rem;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
z-index: 999;
|
||||
}
|
||||
ul.button-mid .next-button {
|
||||
float: right;
|
||||
transition: 0.4s;
|
||||
position: relative;
|
||||
right: 0.5rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: #fff;
|
||||
background: rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
line-height: 2.5rem;
|
||||
top: 50%;
|
||||
position: absolute;
|
||||
transform: translateY(-50%);
|
||||
z-index: 999;
|
||||
}
|
||||
.carousel_images_slide{
|
||||
padding: 3em;
|
||||
}
|
||||
.carousel_img_item img{
|
||||
cursor: pointer;
|
||||
}
|
||||
@media (max-width: 479px){
|
||||
.carousel_img_item:nth-child(-n+1){
|
||||
display: block;
|
||||
width: 100%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 480px){
|
||||
.carousel_img_item:nth-child(-n+2){
|
||||
display: block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px){
|
||||
.carousel_img_item:nth-child(-n+3){
|
||||
display: block;
|
||||
width: 33%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 33%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1280px){
|
||||
.carousel_img_item:nth-child(-n+4){
|
||||
display: block;
|
||||
width: 25%;
|
||||
float: left;
|
||||
}
|
||||
.carousel_img_item{
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
form#hire_form .form-group input,form#hire_form .form-group select, form#hire_form .form-group textarea{
|
||||
min-width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
form#hire_form .form-group input[name="_rucaptcha"], form#hire_form .form-group input[type="submit"], form#hire_form .form-group input[type="radio"], form#hire_form .form-group input[type="checkbox"]{
|
||||
width: auto;
|
||||
min-width: auto;
|
||||
position: relative;
|
||||
margin-left: 0;
|
||||
}
|
||||
</style>
|
||||
<% 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? %>
|
||||
<% if !allow_no_logins_user && current_user.nil? %>
|
||||
<script type="text/javascript">
|
||||
alert("Please login before you hire.");
|
||||
window.location.href = "<%= "/" + I18n.locale.to_s + url %>";
|
||||
</script>
|
||||
<% else %>
|
||||
<h3><%= property.title %></h3>
|
||||
<script type="text/javascript">
|
||||
var pick_date_mode = <%=property.set_availability%>;
|
||||
</script>
|
||||
<h3 class="property_title"><%= property.title.html_safe %></h3>
|
||||
<article class="s-annc s-property">
|
||||
<section class="s-annc__post-wrap">
|
||||
<% if property.display_img %>
|
||||
<div class="s-annc__sub-img full-size-img">
|
||||
<img src="<%=property.image.url%>" alt="<%=property.title%>">
|
||||
<span class="s-annc__img_description"><%=property.title.html_safe%></span>
|
||||
</div>
|
||||
<% end %>
|
||||
<h4 class="property_subtitle"><%= property.property_usage.html_safe %></h4>
|
||||
<% property_carousel_images = property.property_carousel_images %>
|
||||
<% if property_carousel_images.count != 0 %>
|
||||
<div class="carousel_images">
|
||||
<div class="w-ba-banner ba-banner-widget-1">
|
||||
<div class="w-ba-banner__wrap cycle-slideshow"
|
||||
data-list="property_carousel_images"
|
||||
data-level="0"
|
||||
data-cycle-slides=".property_carousel_slide"
|
||||
data-cycle-log="false"
|
||||
data-cycle-auto-height="0"
|
||||
data-cycle-speed="300"
|
||||
data-cycle-timeout="5000"
|
||||
data-cycle-fx="fade"
|
||||
data-pager-active-class="active-slide"
|
||||
data-cycle-swipe=true
|
||||
data-cycle-swipe-fx="scrollHorz"
|
||||
>
|
||||
<% property_carousel_images.each do |carousel_image| %>
|
||||
<div class="w-ba-banner__slide property_carousel_slide"
|
||||
data-cycle-title="{{description_text}}"
|
||||
>
|
||||
<img class="w-ba-banner__image banner-responsive" src="<%=carousel_image.file.url %>" alt="<%=carousel_image.description_text %>">
|
||||
<div class="ad-overlay w-ad-banner__overlay property_carousel__overlay">
|
||||
<p><strong class="carousel__description"><%=carousel_image.description %></strong></p>
|
||||
</div>
|
||||
<div class="transitionfade"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<ul class="controlplay"><a class="resume-slide" title="<%=data["resume_btn_title"]%>"><i></i></a><a class="pause-slide" title="<%=data["pause_btn_title"]%>"><i></i></a></ul>
|
||||
<ul class="button-mid">
|
||||
<i class="fa fa-angle-left prev-button" aria-hidden="true" title="<%=data["prev_btn_title"]%>"></i>
|
||||
<i class="fa fa-angle-right next-button" aria-hidden="true" title="<%=data["next_btn_title"]%>"></i>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="property_note"><%= property.note.html_safe %></div>
|
||||
</section>
|
||||
<ul class="s-property__related-wrap list-unstyled no-print">
|
||||
<% if property.property_files.count != 0%>
|
||||
<li class="s-annc__related-file s-property__related-file">
|
||||
<i class="fa fa-fw fa-paperclip"></i>
|
||||
<div class="s-annc__related-file-list s-property__related-file-list" data-list="property_files" data-level="0">
|
||||
<% property.property_files.each do |property_file| %>
|
||||
<a class="s-annc__flie-title s-property__flie-title btn btn-default btn-sm" href="<%=property_file.file.url %>" title="<%=property_file.title %>"><%=property_file.title %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if property.property_links.count != 0%>
|
||||
<li class="s-annc__related-link s-property__related-link">
|
||||
<i class="fa fa-fw fa-link"></i>
|
||||
<div class="s-annc__related-link-list s-property__related-link-list" data-list="bulletin_links" data-level="0">
|
||||
<% property.property_links.each do |property_link| %>
|
||||
<a class="s-annc__link-title s-property__link-title btn btn-default btn-sm" href="<%=property_link.url %>" target="_blank"><%=property_link.display_title %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% 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>
|
||||
<div id="property-unavaialable-alert" class="alert alert-danger" role="alert"><b>Sorry! </b><br><span> <%= session["hire-save-msg"].gsub("\n",'<br>').html_safe %></span></div>
|
||||
<script type="text/javascript">alert("<%= escape_javascript(session["hire-save-msg"]) %>")</script>
|
||||
<% session.delete("hire-save-msg") %>
|
||||
<% end %>
|
||||
<%= form_for hire, :url => "/xhr/property_hires/make_booking", html: { class: "form-horizontal" } do |f| %>
|
||||
</article>
|
||||
<% if calendar_type == 0 %>
|
||||
<div id="orbit_calendar" class="col-lg-<%=12-right_col%>">
|
||||
<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="today_btn"><%= t("property_hire.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" ><%= t("property_hire.day") %></button>
|
||||
<button class="btn btn-default mode_switch btn-sm" data-mode="timeGridWeek" ><%= t("property_hire.week") %></button>
|
||||
<button class="btn btn-default active mode_switch btn-sm" data-mode="dayGridMonth" ><%= t("property_hire.month") %></button>
|
||||
</div>
|
||||
<button id="refresh_btn" class="btn btn-default btn-sm">
|
||||
<i class="icons-cycle"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<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>
|
||||
</div>
|
||||
<div class="clearfix"></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 id="calendar-loading"></div>
|
||||
<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? && !recover,:format=>"HH:mm", :class => "pull-left", :data=>{"picker-type" => "range", "range" => "end"} %>
|
||||
<% 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>
|
||||
</div>
|
||||
<div id="event_quick_view" class="modal" style="width: 300px; display:none; margin:0 0 0 0;"></div>
|
||||
<script type="text/javascript">
|
||||
var property_id = "<%= property.id.to_s %>";
|
||||
var valid_range = {}
|
||||
<% if property.p_open_start_time %>
|
||||
valid_range["start"] = "<%= property.p_open_start_time.strftime("%Y-%m-%d") %>"
|
||||
<% end %>
|
||||
<% if property.p_open_end_time %>
|
||||
valid_range["end"] = "<%= (property.p_open_end_time + 1.day).strftime("%Y-%m-%d") %>"
|
||||
<% end %>
|
||||
var calendar = new Calendar("#calendar", property_id, valid_range,"",true, "<%= locale %>");
|
||||
function pick_hire_date(date,allow_times){
|
||||
if(window.processing_hire)
|
||||
return;
|
||||
window.processing_hire = true;
|
||||
try{
|
||||
var date_target = $("#date_target_block").find("input");
|
||||
var offset = date_target.offset();
|
||||
if(date_target.val() == date){
|
||||
scrollTo(0,offset.top - 40);
|
||||
return;
|
||||
}
|
||||
$("#date_target_block").find("input").val(date);
|
||||
var select_target;
|
||||
if($("#hire_time_range_block").find("select").length == 0){
|
||||
select_target = $("<select name=\""+$("#hire_time_range_block").find("input").attr("name")+"\"></select>");
|
||||
$("#hire_time_range_block").find("input").remove();
|
||||
}
|
||||
else{
|
||||
select_target = $("#hire_time_range_block").find("select").eq(0);
|
||||
}
|
||||
select_target = select_target.empty();
|
||||
select_target.append("<option value=\"\"><%=t("property_hire.please_select")%></option>");
|
||||
allow_times.forEach(function(allow_time){
|
||||
select_target.append("<option value=\""+allow_time[2]+"\">"+allow_time[3]+"</option>");
|
||||
});
|
||||
select_target.appendTo($("#hire_time_range_block"));
|
||||
scrollTo(0,offset.top - 40);
|
||||
}catch(e){};
|
||||
window.processing_hire = false;
|
||||
}
|
||||
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");
|
||||
goto_calendar();
|
||||
}
|
||||
$("#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"){
|
||||
if(pick_date_mode){
|
||||
start_date = $("#p_hire_date").val();
|
||||
end_date = start_date;
|
||||
}else{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 offset = $('#orbit_calendar').offset();
|
||||
scrollTo(0,offset.top-40);
|
||||
window.setTimeout(function(){
|
||||
scrollTo(0,offset.top-40);
|
||||
},500);
|
||||
}
|
||||
</script>
|
||||
<% end %>
|
||||
<div class="col-lg-<%=right_col%>">
|
||||
<% if property.can_reserve === true || is_user_manager %>
|
||||
<%= form_for hire, :url => "/xhr/property_hires/make_booking", html: { class: "form-horizontal", id: "hire_form" } do |f| %>
|
||||
<% if property.set_availability %>
|
||||
<div class="form-group">
|
||||
<%= f.label :start_time, t("property_hires.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?, :data=>{"picker-type" => "range", "range" => "start", "fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
||||
<%= f.label :date, "*"+t("property_hire.date"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>" id="date_target_block">
|
||||
<% if calendar_type == 0 %>
|
||||
<%= f.text_field :date, :value=>(recover ? f.object.date.to_s : t("property_hire.please_choose_date")),:readonly=>"",:onclick=>"goto_calendar()" %>
|
||||
<% else %>
|
||||
<%= f.datetime_picker :date, :no_label => true, :new_record => hire.new_record? && !recover ,:class => "pull-left", :picker_type => "date", :format=>"yyyy/MM/dd", :data=>{ "fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :end_time, t("property_hires.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?, :data=>{"picker-type" => "range", "range" => "end", "fv-validation" => "required;", "fv-messages" => "Cannot be empty;"} %>
|
||||
<%= f.label :time, "*"+t("property_hire.time"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>" id="hire_time_range_block">
|
||||
<% property_day_setting = recover ? hire.property_day_setting : nil %>
|
||||
<% if property_day_setting %>
|
||||
<%= select_tag "#{f.object_name}[time]", options_for_select([[t("property_hire.please_select"),""],[property_day_setting.title,property_day_setting.id.to_s]],hire.property_day_setting_id), :required=>"required" %>
|
||||
<% else %>
|
||||
<% if property.calendar_type == 0 %>
|
||||
<%= f.text_field :time, :value=>t("property_hire.please_choose_date"),:readonly=>"",:onclick=>"goto_calendar()" %>
|
||||
<% else %>
|
||||
<%= select_tag "#{f.object_name}[time]", options_for_select([[t("property_hire.please_choose_date"),""]]), :required=>"required" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="form-group">
|
||||
<%= f.label :start_time, "*"+t("property_hire.start_time"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<% if calendar_type == 0 %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%= f.datetime_picker :start_time, :no_label => true, :new_record => hire.new_record? && !recover, :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>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<%= f.label :end_time, "*"+t("property_hire.end_time"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%= f.datetime_picker :end_time, :no_label => true, :new_record => hire.new_record? && !recover,: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>
|
||||
<% end %>
|
||||
<% if property.recurring_enable %>
|
||||
<!-- ############# recurring ############# -->
|
||||
<div class="form-group">
|
||||
<%= f.label :recurring, t("property_hires.recurring"), :class => "col-sm-2 control-label" %>
|
||||
<%= f.label :recurring, t("property_hire.recurring"), :class => "col-sm-#{label_col} 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" %>
|
||||
<%= f.label :recurring_interval, t("property_hire.recurring_interval"), :class => "col-sm-#{label_col} 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;"}} %>
|
||||
<%= 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_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;"} %>
|
||||
<%= f.label :recurring_end_date, "*"+t("property_hire.recurring_end_date"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%= f.datetime_picker :recurring_end_date, :no_label => true, :new_record => hire.new_record? && !recover, :class=>"pull-left", :data=>{"fv-validation" => "requiredifrecurring;", "fv-messages" => "Cannot be empty;"} %>
|
||||
<% if calendar_type == 0 %>
|
||||
<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>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
<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 class="col-sm-offset-<%=label_col%> col-sm-<%=input_col%>">
|
||||
<div id="property-avaialable-alert" style="margin-bottom: 5px; padding: 10px;<%= 'display: none;' unless recover %>" class="alert alert-success" role="alert"><%=t("property_hire.this_property_is_available",:default=>"<b>Hooray! </b>This property is available.").html_safe%></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 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>Unavailibility Schedule</b>
|
||||
<div class="col-sm-offset-<%=label_col%> col-sm-<%=input_col%>">
|
||||
<b><%= t("property_hire.Unavailibility_Schedule") %></b>
|
||||
<div>
|
||||
This property is unavaliable <%= !property.start_date.nil? ? " from " + property.start_date.strftime("%Y-%m-%d") : "" %> <%= !property.end_date.nil? ? " to " + property.end_date.strftime("%Y-%m-%d") : "" %> every
|
||||
<% property.weekdays.each_with_index do |d,i| %>
|
||||
<% if i < (property.weekdays.count - 1) %>
|
||||
<%= Property::WEEKDAYS[d.to_i] + ", " %>
|
||||
<% else %>
|
||||
<%= Property::WEEKDAYS[d.to_i] %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
between <%= property.start_time %> & <%= property.end_time %>.
|
||||
<%= 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">Check Availibility</a>
|
||||
<label for="" class="col-sm-<%=label_col%> control-label"></label>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<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_hires.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_hires.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_hires.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;"} %>
|
||||
<% default_values = {"hiring_person_email" => ( current_user.member_profile.email rescue ""),
|
||||
"hiring_person_number" => ( current_user.member_profile.mobile_no rescue ""),
|
||||
"hiring_person_name" => ( current_user.name rescue "")
|
||||
} %>
|
||||
<% if recover
|
||||
default_values = default_values.merge(Property::FIELDSNAME.map{|f| [f,hire.send(f)]}.to_h)
|
||||
end %>
|
||||
<%= f.hidden_field :hiring_person_id, :value => (current_user.member_profile.id.to_s rescue "") %>
|
||||
</div>
|
||||
</div>
|
||||
<% custom_field_inputs = {} %>
|
||||
<% custom_field_type = {"note_for_hire"=>"text_area"} %>
|
||||
<% if(property.enable_notes_selector rescue false) %>
|
||||
<% custom_field_inputs["note_for_hire"] = render(:partial=>"property_hires/notes_selector",:locals=>{:f=>f,:property=>property,:label_col=>label_col,:input_col=>input_col,:hire=>nil}) %>
|
||||
<% end %>
|
||||
<% fields_name = property.get_all_fields %>
|
||||
<% has_p_hire_fields = property.p_hire_fields_enabled.count != 0
|
||||
p_hire_fields = {}
|
||||
if has_p_hire_fields
|
||||
p_hire_fields = property.p_hire_fields_enabled.map{|rf| [rf.id.to_s,rf]}.to_h
|
||||
end
|
||||
%>
|
||||
<% @form_index = 0 %>
|
||||
<% fields_name.each do |field_name| %>
|
||||
<% if has_p_hire_fields && field_name.include?("p_hire_fields") %>
|
||||
<div class="form-group">
|
||||
<%= f.label :reason_for_hire, t("property_hires.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>
|
||||
<% rf = p_hire_fields[field_name.sub("p_hire_fields.",'')] %>
|
||||
<% next if rf.nil? %>
|
||||
<%= rf.block_helper(property,@form_index,false,"p_hire",hire, rf.to_require,label_col) %>
|
||||
</div>
|
||||
<% @form_index = @form_index +1 %>
|
||||
<% else %>
|
||||
<% if(property[field_name]["enable"] == "1" rescue true) %>
|
||||
<% required = (property[field_name]["required"] == "true" rescue false) %>
|
||||
<% if custom_field_inputs[field_name] %>
|
||||
<%= custom_field_inputs[field_name] %>
|
||||
<% else %>
|
||||
<div class="form-group">
|
||||
<%= f.label :note_for_hire, t("property_hires.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>
|
||||
<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.;">
|
||||
<%= f.label field_name, (required ? "*" : "") + property.custom_text(field_name,"name"), :class => "col-sm-#{label_col} control-label" %>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<% placeholder = property.custom_text(field_name,"placeholder") %>
|
||||
<% if custom_field_type[field_name] %>
|
||||
<%= f.send(custom_field_type[field_name], field_name , {:class => "form-control", :placeholder => placeholder, :value => default_values[field_name], :required=>(required ? 'required' : nil)}) %>
|
||||
<% else %>
|
||||
<%= f.text_field field_name, :class => "form-control", :placeholder => placeholder, :value => default_values[field_name], :required=>(required ? 'required' : nil) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if allow_no_logins_user && current_user.nil? %>
|
||||
<!-- 驗證碼 -->
|
||||
<div class="form-group">
|
||||
<label for="note" class="col-sm-<%=label_col%> control-label"><%= t('property_hire.recaptcha.recaptcha') %></label>
|
||||
<div class="col-sm-<%=input_col%>">
|
||||
<%= gotcha_error %>
|
||||
<%= gotcha %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-<%=label_col%> col-sm-<%=input_col%>">
|
||||
<% if f.object.id.present? %>
|
||||
<%= f.hidden_field :id %>
|
||||
<% end %>
|
||||
<div class="nano"><div class="content"></div></div>
|
||||
<%= 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="<%=recover ? 1 : 0 %>" data-fv-validation="checkForDates;" data-fv-messages="Please make sure first if dates are available.;">
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<div style="height: 50px;"></div>
|
||||
<script type="text/javascript">
|
||||
var property_id = "<%= property.id.to_s %>";
|
||||
var timezone = (new Date().getTimezoneOffset() / -60).toString();
|
||||
var all_day_settings = <%= all_day_settings.to_json.html_safe %>;
|
||||
if(timezone[0] != "-"){
|
||||
timezone = "+" + timezone;
|
||||
}
|
||||
|
||||
$("#p_hire_date").on("change",function(){
|
||||
var _this = $(this);
|
||||
var date = new Date(_this.val());
|
||||
if(date.getTime()){
|
||||
var wday = date.getDay();
|
||||
var select_target = $("#p_hire_time");
|
||||
if(select_target.data("wday") == wday){
|
||||
return;
|
||||
}
|
||||
select_target.empty();
|
||||
select_target.data("wday",wday);
|
||||
if(all_day_settings[wday]){
|
||||
select_target.append("<option value=\"\"><%=t("property_hire.please_select")%></option>");
|
||||
all_day_settings[wday].forEach(function(allow_time){
|
||||
select_target.append("<option value=\""+allow_time[0]+"\">"+allow_time[1]+"</option>");
|
||||
});
|
||||
}else{
|
||||
select_target.append("<option value=\"\"><%=t("property_hire.no_time_can_select",:default=>"No time can be selected!")%></option>");
|
||||
}
|
||||
}
|
||||
})
|
||||
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"),
|
||||
time_setting_id = $("#hire_time_range_block select").val();
|
||||
if(Number.isNaN(new Date(stime).getDate())){
|
||||
window.check_message = "<%=t("property_hire.please_choose_date")%>";
|
||||
if(!check_only){
|
||||
$("#property-unavaialable-alert").find("span").html(window.check_message);
|
||||
$("#property-unavaialable-alert").show();
|
||||
}
|
||||
spinner.hide();
|
||||
el.show();
|
||||
return false;
|
||||
}
|
||||
if(time_setting_id == ""){
|
||||
window.check_message = "<%=t("property_hire.please_select_time")%>";
|
||||
if(!check_only){
|
||||
$("#property-unavaialable-alert").find("span").html(window.check_message);
|
||||
$("#property-unavaialable-alert").show();
|
||||
}
|
||||
$("#hire_time_range_block select").focus();
|
||||
$("#hire_time_range_block select").css("border","2px solid red");
|
||||
spinner.hide();
|
||||
el.show();
|
||||
return false;
|
||||
}
|
||||
stime = stime || etime;
|
||||
etime = etime || stime;
|
||||
property_id = property_id || window.property_id;
|
||||
data = {
|
||||
"stime": stime,
|
||||
"etime": etime,
|
||||
"property_id": property_id,
|
||||
"locale": "<%=I18n.locale%>",
|
||||
"timezone": timezone,
|
||||
"time_setting_id": time_setting_id,
|
||||
"phire_id": "<%=hire.id.to_s%>"
|
||||
}
|
||||
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;
|
||||
}
|
||||
$(document).on("change","#hire_time_range_block select",function(){
|
||||
$(this).css("border","");
|
||||
})
|
||||
$("#check-avail-btn").on("click",function(){
|
||||
var el = $(this),
|
||||
url = $(this).attr("href"),
|
||||
spinner = $("#spinner");
|
||||
|
||||
$(".alert").hide();
|
||||
data = {
|
||||
"stime" : $("#p_hire_start_time").val(),
|
||||
"etime" : $("#p_hire_end_time").val(),
|
||||
"property_id" : property_id
|
||||
var stime, etime;
|
||||
if(pick_date_mode){
|
||||
stime = $("#p_hire_date").val();
|
||||
etime = stime;
|
||||
}else{
|
||||
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")){
|
||||
var interval = $("#p_hire_recurring_interval").val(),
|
||||
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;
|
||||
}
|
||||
data["interval"] = interval;
|
||||
data["recurring_end_date"] = recurring_end_date;
|
||||
}
|
||||
spinner.show();
|
||||
el.hide();
|
||||
$.ajax({
|
||||
"url" : url,
|
||||
"type" : "get",
|
||||
"data" : data,
|
||||
"dataType" : "json"
|
||||
}).done(function(data){
|
||||
if(data.success){
|
||||
$("#property-avaialable-alert").show();
|
||||
$("#dates_validated").val("1");
|
||||
}else{
|
||||
$("#property-unavaialable-alert").find("span").text(data.msg);
|
||||
$("#property-unavaialable-alert").show();
|
||||
}
|
||||
spinner.hide();
|
||||
el.show();
|
||||
})
|
||||
check_available(stime,etime,interval,recurring_end_date);
|
||||
return false;
|
||||
})
|
||||
|
||||
$("#unavailable-schedule").on("click",function(){
|
||||
|
||||
})
|
||||
|
||||
var hireForm = new FormValidator($("#new_p_hire"));
|
||||
if( document.createElement('canvas').getContext == undefined ){ //html5 not supported
|
||||
$('[required]:not([readonly])').attr({"data-fv-validation": "required;", "data-fv-messages": "Cannot be empty;"});
|
||||
}
|
||||
var hireForm = new FormValidator($("#hire_form"));
|
||||
hireForm.validate_functions.checkForDates = function(value,element){
|
||||
return value == "1";
|
||||
}
|
||||
|
@ -193,8 +787,11 @@
|
|||
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{
|
||||
|
@ -202,10 +799,18 @@
|
|||
}
|
||||
})
|
||||
</script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
<% if property.p_open_start_time %>
|
||||
$("#p_hire_start_time").datepicker('option', 'minDate', new Date("<%= property.p_open_start_time.strftime("%Y-%m-%d") %>"));
|
||||
$("#p_hire_end_time").datepicker('option', 'minDate', new Date("<%= property.p_open_start_time.strftime("%Y-%m-%d") %>"));
|
||||
$("#p_hire_recurring_end_date").datepicker('option', 'minDate', new Date("<%= property.p_open_start_time.strftime("%Y-%m-%d") %>"));
|
||||
<% end %>
|
||||
<% if property.p_hire_end_time && property.p_open_end_time %>
|
||||
$("#p_hire_start_time").datepicker('option', 'maxDate', new Date("<%= property.p_open_end_time.strftime("%Y-%m-%d") %>"));
|
||||
$("#p_hire_end_time").datepicker('option', 'maxDate', new Date("<%= property.p_open_end_time.strftime("%Y-%m-%d") %>"));
|
||||
$("#p_hire_recurring_end_date").datepicker('option', 'maxDate', new Date("<%= property.p_open_end_time.strftime("%Y-%m-%d") %>"));
|
||||
<% end %>
|
||||
})
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,440 @@
|
|||
<% 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_frontend %>
|
||||
<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 %>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<%
|
||||
data = action_data
|
||||
back_url = data["back_url"]
|
||||
back_button_text = data["back_button_text"]
|
||||
%>
|
||||
<h4><%=t("property_hire.the_reservation_was_successfully_sent")%></h4>
|
||||
<div>
|
||||
<a href="<%=back_url%>" class="btn btn-warning"><%=back_button_text%></a>
|
||||
</div>
|
|
@ -1 +1,11 @@
|
|||
<% OrbitHelper.render_css_in_head(["property_hire_fullcalendar.css","property_hire_calendar"]) %>
|
||||
<script type="text/javascript" src="/assets/property_hire_fullcalendar.min.js"></script>
|
||||
<script type="text/javascript" src="/assets/property_hire_calendar_frontend.js"></script>
|
||||
<script type="text/javascript" src="/assets/locale-all.min.js"></script>
|
||||
<% data = action_data %>
|
||||
<% if data["manage_booking_btn"] %>
|
||||
<div class="pull-right">
|
||||
<a href="<%= data["manage_booking_url"] %>" class="btn btn-primary" target="_blank"><%= data["manage_booking"] %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= render_view %>
|
|
@ -1,5 +1,5 @@
|
|||
<% OrbitHelper.render_css_in_head(["property_hire_fullcalendar.css","property_hire_calendar.scss"]) %>
|
||||
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||
<% OrbitHelper.render_css_in_head(["property_hire_fullcalendar.css","property_hire_calendar"]) %>
|
||||
<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>
|
||||
<%
|
||||
|
@ -7,7 +7,7 @@
|
|||
property = data["property"]
|
||||
url = data["url"]
|
||||
%>
|
||||
<% if !property.can_be_hired %>
|
||||
<% if property.disable_view_calendar_page %>
|
||||
<script type="text/javascript">
|
||||
alert("This property is unavailable for hire.");
|
||||
window.location.href = "<%= "/" + I18n.locale.to_s + url %>";
|
||||
|
@ -25,7 +25,7 @@
|
|||
<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>
|
||||
<button class="btn btn-default btn-sm" id="today_btn"><%= t("property_hire.today") %></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -33,9 +33,9 @@
|
|||
</div>
|
||||
<div id='sec3' class="btn-toolbar">
|
||||
<div class="btn-group calendar_mode">
|
||||
<button class="btn btn-default mode_switch btn-sm" data-mode="agendaDay" >day</button>
|
||||
<button class="btn btn-default mode_switch btn-sm" data-mode="agendaWeek" >week</button>
|
||||
<button class="btn btn-default active mode_switch btn-sm" data-mode="month" >month</button>
|
||||
<button class="btn btn-default mode_switch btn-sm" data-mode="timeGridDay" ><%= t("property_hire.day") %></button>
|
||||
<button class="btn btn-default mode_switch btn-sm" data-mode="timeGridWeek" ><%= t("property_hire.week") %></button>
|
||||
<button class="btn btn-default active mode_switch btn-sm" data-mode="dayGridMonth" ><%= t("property_hire.month") %></button>
|
||||
</div>
|
||||
<button id="refresh_btn" class="btn btn-default btn-sm">
|
||||
<i class="icons-cycle"></i>
|
||||
|
@ -52,5 +52,5 @@
|
|||
<a href="<%= "/" + I18n.locale.to_s + url %>" class="btn btn-warning">Back</a>
|
||||
<script type="text/javascript">
|
||||
var property_id = "<%= property.id.to_s %>";
|
||||
var calendar = new Calendar("#calendar",property_id);
|
||||
var calendar = new Calendar("#calendar",property_id,false);
|
||||
</script>
|
|
@ -0,0 +1,72 @@
|
|||
<% site = Site.first%>
|
||||
<div id="address-field" class="modal hide fade">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3><%= (field_name rescue nil) || t("address_modal.default_title") %></h3>
|
||||
</div>
|
||||
<div class="modal-body form-horizontal address-modal">
|
||||
<div class="tabbable">
|
||||
<ul class="nav nav-tabs">
|
||||
<% site.valid_locales.each do |locale|%>
|
||||
<% active = (locale == I18n.locale.to_s ? ["active"] : [] ) %>
|
||||
<%= content_tag :li,:class=>active,:for=>locale do%>
|
||||
<%= link_to t(locale).to_s,".#{btn_class}.address_modal.#{locale}",:data=>{:toggle=>"tab"}%>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
|
||||
<% site.valid_locales.each do |locale|%>
|
||||
<!-- start of lang tab context -->
|
||||
<% active = (locale == I18n.locale.to_s ? "active" : "" ) %>
|
||||
<div class="tab-pane fade <%= active %> in %>" for="<%= locale %>">
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="street_address"><%= t("address_modal.street_address") %></label>
|
||||
<div class="controls">
|
||||
|
||||
<%= text_area_tag("#{field_name_basic}[temp][address_ext][#{locale}][street_address]",nil,:rows=>3,:func=>'street_address', :class=>"input-xlarge") %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="city"><%= t("address_modal.city") %></label>
|
||||
<div class="controls">
|
||||
<%= text_field_tag("#{field_name_basic}[temp][address_ext][#{locale}][city]",'',:func=>'city', :class=>"input-xlarge") %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="counties"><%= t("address_modal.county") %></label>
|
||||
<div class="controls">
|
||||
<%= text_field_tag("#{field_name_basic}[temp][address_ext][#{locale}][county]",'',:func=>'county', :class=>"input-xlarge") %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="zip"><%= t("address_modal.zip") %></label>
|
||||
<div class="controls">
|
||||
<%= text_field_tag("#{field_name_basic}[temp][address_ext][#{locale}][zip]",nil,:class=>"input-mini",:func=>'zip', :class=>"input-xlarge") %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label muted" for="country"><%= t("address_modal.country") %></label>
|
||||
<div class="controls">
|
||||
<%= text_field_tag("#{field_name_basic}[temp][address_ext][#{locale}][country]",'',:func=>'country', :class=>"input-xlarge") %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group hide">
|
||||
<label class="control-label muted" for="indicator"><%= t("address_modal.Indicator") %></label>
|
||||
<div class="controls">
|
||||
<%= text_field_tag("#{field_name_basic}[temp][address_ext][#{locale}][indicator]",'',:func=>'country', :class=>"input-xlarge") %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end of tab context -->
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn" data-dismiss="modal" aria-hidden="true"><%=t(:close)%></a>
|
||||
<a class="btn btn-primary returnDecide" data-dismiss="modal" aria-hidden="true"><%=t(:save_and_close)%></a>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,2 @@
|
|||
<% @field_name = 'info' %>
|
||||
<%= render :partial=>'admin/roles/attribute_field.html.erb',:locals => {attribute_field: attribute_field,attribute_field_counter: attribute_field_counter} %>
|
|
@ -0,0 +1,25 @@
|
|||
<% values ||=[]%>
|
||||
<%= content_tag :div,:class=>"control-group" do%>
|
||||
<label class="control-label muted" for=""><%= (defined? label_ext) ? label_ext : t("lists.markups.hint_text") %></label>
|
||||
<div class="controls">
|
||||
<div class="input-append">
|
||||
<div class="tab-content">
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active in" : "'") %>
|
||||
<%= content_tag :div,:class=>"tab-pane fade #{active}",:id=>"#{name_to_id(field_name)}_#{locale}" do%>
|
||||
<% locale_value = values[locale.to_s] rescue nil%>
|
||||
<%= text_area(field_name, locale,:value=>locale_value,:placeholder=> "#{t(locale).to_s}",:data=>{:type=>"lang_#{locale}"}) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" data-toggle="buttons-radio">
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% active = (locale == @site_in_use_locales.first ? "active" : "") %>
|
||||
<%= link_to t(locale).to_s,"##{name_to_id(field_name)}_#{locale}",:class=>"btn #{active}",:data=>{:toggle=>"tab"}%>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -0,0 +1,62 @@
|
|||
<% temp_field_name = field_name.gsub /\[\D*\]$/,'[temp]'%>
|
||||
<% flag = (field_name.split(/\[.*\](?=\[)/)[-1][1...-1] != 'member_relations') %>
|
||||
<div class="control-group" style="<%= 'display: flex;' if !flag %>">
|
||||
<% if flag %>
|
||||
<%= hidden_field_tag "#{temp_field_name}[count]",((values.keys.collect{|t| t.to_i}.max rescue nil) || 0 ),:class=>"list_count"%>
|
||||
<%= hidden_field_tag "#{temp_field_name}[name]",field_name,:class=>"field_name"%>
|
||||
<label class="control-label muted" for=""><%= t(:options)%></label>
|
||||
<% else %>
|
||||
<div>
|
||||
<label class="control-label muted"><%= t('list.mode')%></label>
|
||||
<div class="member_related">
|
||||
<br>
|
||||
<label class="control-label muted"><%= t('list.related')%></label>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="controls add-input" style="<%= 'margin-left: 1em;' if !flag %>">
|
||||
<div class="add-target single">
|
||||
<% if flag %>
|
||||
<%if values.blank? %>
|
||||
<%= content_tag :div,:class=>"input-append" do%>
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% last = (locale == @site_in_use_locales.last ? true : false) %>
|
||||
<% p_value = value[locale.to_s] rescue nil%>
|
||||
<%= text_field("#{field_name}[0]", locale,:placeholder=>t(locale).to_s,:class=>"input-medium",:data=>{:type=>"option_lang_0_#{locale}"}) %>
|
||||
<% if last %>
|
||||
<a href="#" class="btn remove-input"> <i class="icon-trash"></i> </a>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%else%>
|
||||
<%values.each do |index,value|%>
|
||||
<%= content_tag :div,:class=>"input-append" do%>
|
||||
<% @site_in_use_locales.each do |locale| %>
|
||||
<% last = (locale == @site_in_use_locales.last ? true : false) %>
|
||||
<% p_value = value[locale.to_s] rescue nil%>
|
||||
<%= text_field("#{field_name}[#{index}]", locale,:value=>p_value,:placeholder=>t(locale).to_s,:class=>"input-medium", :data=>{:type=>"option_lang_#{index}_#{locale}"}) %>
|
||||
<% if last %>
|
||||
<a href="#" class="btn remove-input"> <i class="icon-trash"></i> </a>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= content_tag :div,:class=>"input-append" do %>
|
||||
<%= (hidden_field_tag "#{field_name}[0][_id]",values[0].id.to_s) if !values.blank? %>
|
||||
<%= select_tag "#{field_name}[0][mode]", options_for_select([[t('list.passive'),'passive'],[t('list.active'),'active']],:selected => (values[0]['mode'] rescue nil)),:onChange => 'hidden_option(this)',:class=>'member_relations_opt' %>
|
||||
<% relates = values.blank? ? [nil] : values[0]['related'] %>
|
||||
<% relates = [nil] if relates.nil? %>
|
||||
<div class="member_related">
|
||||
<% Array(relates).each do |related|%>
|
||||
<%= select_tag "#{field_name}[0][related][]", options_for_select(Role.all.desc(:created_at).map{|v1| [v1.title,v1.attribute_fields.sort_by{|v| v.key.to_i}.select{|v| v.id.to_s != id}.map{|v| [" #{v.title}".html_safe,v.id]}]}.flatten(2),:disabled=>Role.all.map{|v| v.title},:selected=> related), :class => 'member-relations-related' %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<p class="add-btn"> <a href="#" class="member-relations-add trigger btn btn-mini btn-primary"><i class="icons-plus"></i> <%= t(:add) %></a> </p>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,25 @@
|
|||
<% privacy_settings = ["public","logged_in","locked","only_admin"]%>
|
||||
<% privacy_settings.each do |privacy_setting|%>
|
||||
<% case privacy_setting
|
||||
when "public"
|
||||
icon = "icons-earth"
|
||||
when "logged_in"
|
||||
icon = "icons-users"
|
||||
when "locked"
|
||||
icon = "icons-lock"
|
||||
when "only_admin"
|
||||
icon = "fa fa-user-secret"
|
||||
end
|
||||
%>
|
||||
<%= radio_button(field_key, "privacy_default", privacy_setting,:checked => (((attribute_field.privacy_default == privacy_setting) rescue false) ? true : false), :data=>{:type=>"radio"}) %><div class="<%=icon%>"></div><%= t("privacy_type.#{privacy_setting}").html_safe %>
|
||||
<% end %>
|
||||
<span style="margin-left: 2em;display: inline-flex;">
|
||||
<label style="margin: 0;font-size: 1em;display: inline-flex;">
|
||||
<%= hidden_field(field_key, "privacy_default_apply", :value=> "0") %>
|
||||
<%= check_box_tag("#{field_key}[privacy_default_apply]","1",attribute_field["privacy_default_apply"]) %>
|
||||
<%= t('apply_to_current_members.content') %>
|
||||
</label>
|
||||
<span style="margin-left: 3em;color: #E91E63;">
|
||||
<%= t('apply_to_current_members.warning') %>
|
||||
</span>
|
||||
</span>
|
|
@ -0,0 +1,36 @@
|
|||
forbidden_item_names:
|
||||
- admin
|
||||
- panel
|
||||
- appfront
|
||||
|
||||
#NO_MULTI_TAG = ["select","date","radio_button","checkbox","date_durnation"]
|
||||
|
||||
markups:
|
||||
text_field:
|
||||
muti_lang_input_supprt: true
|
||||
ext_support: true
|
||||
panel: typeA
|
||||
select:
|
||||
muti_lang_input_supprt: false
|
||||
ext_support: false
|
||||
panel: typeB
|
||||
date:
|
||||
muti_lang_input_supprt: false
|
||||
ext_support: false
|
||||
panel: typeC
|
||||
text_area:
|
||||
muti_lang_input_supprt: true
|
||||
ext_support: false
|
||||
panel: typeD
|
||||
radio_button:
|
||||
muti_lang_input_supprt: false
|
||||
ext_support: false
|
||||
panel: typeE
|
||||
checkbox:
|
||||
muti_lang_input_supprt: false
|
||||
ext_support: false
|
||||
panel: typeE
|
||||
hint_text:
|
||||
muti_lang_input_supprt: false
|
||||
ext_support: false
|
||||
panel: typeF
|
|
@ -1,5 +1,110 @@
|
|||
en:
|
||||
lists:
|
||||
markups:
|
||||
hint_text: Hint Text
|
||||
restful_actions:
|
||||
copy: Copy
|
||||
fields_display_order: "Fields display order"
|
||||
property_hire:
|
||||
copy: Copy
|
||||
unfilled: Unfilled
|
||||
hire_time: Reservation time
|
||||
back_to_hire_page: "Back to Reserve Page"
|
||||
apply_default_time_settings: Apply default time settings
|
||||
default_time_settings: Default time settings
|
||||
the_reservation_was_successfully_sent: "The reservation was successfully sent!Please see email to get more information"
|
||||
go_to_infos_page: Go to infos page
|
||||
display_in_reason_for_hire: "Display in reason for hire"
|
||||
need_hire_before: "How late does the user need to reserve?"
|
||||
_month: Month
|
||||
_week: Week
|
||||
_day: Day
|
||||
_hour: Hour
|
||||
_minute: Minute
|
||||
sort_number: Sort Number
|
||||
enable_fields_sort: Enable fields sort
|
||||
fields_display_order: "Fields display order"
|
||||
this_property_is_available: "<b>Hooray! </b>This property is available."
|
||||
recaptcha:
|
||||
recaptcha: Recaptcha
|
||||
errors:
|
||||
verification_failed: Verification Failed
|
||||
no_time_can_select: "No time can be selected!"
|
||||
custom_calendar_type:
|
||||
default: Default
|
||||
display: Display
|
||||
not_display: Not display
|
||||
page_setting: Page Setting
|
||||
display_calendar_default: "Display calendar in reserved page?(default)"
|
||||
display_calendar: "Display calendar in reservation page?"
|
||||
allow_no_logins_user: "Allow no logins user to reserve property."
|
||||
please_select_time: "Please select Time!"
|
||||
date: "Date"
|
||||
time: "Time"
|
||||
please_choose_date: "Please choose date"
|
||||
please_select: "Please select"
|
||||
reserve: Reserve
|
||||
files_links: "Files, Links"
|
||||
disable_content_page: Disable content page
|
||||
disable_view_calendar_page: 'Disable "Calendar" page'
|
||||
disable_no_logins_view_calendar: 'Disable Calendar page for no logins user'
|
||||
display_img: Display Cover Image in Content Page
|
||||
carousel_image: Carousel Image
|
||||
carousel_image_title: Carousel Image(display at the bottom of show page)
|
||||
custom_carousel_image_width_hint: "If blank, width will be default value."
|
||||
carousel_image_width: Carousel Image Width
|
||||
default_carousel_image_width: Default Carousel Image Width
|
||||
cover_image_display_setting: Cover Image display setting
|
||||
full_width: Full width
|
||||
up_left_corner: Up-left corner
|
||||
up_right_corner: Up-right corner
|
||||
name: Show Name
|
||||
placeholder: Placeholder
|
||||
disable: Disable
|
||||
time_title: Title
|
||||
reservation_limit: "Reservation limit(0 present no limit)"
|
||||
set_availability: Set Availability
|
||||
reservation_fields: Reservation Fields
|
||||
to_require: Should Be Filled?
|
||||
please_save: 'Please click "Save Order" button when you done.'
|
||||
position: Position
|
||||
save_order: Save Order
|
||||
order: Order
|
||||
custom_fields_setting: Custom fields Setting
|
||||
custom_fields: Custom fields
|
||||
please_hire_after_date: "Please reserve after %{date}!"
|
||||
property_is_unavailable_during_this_time: "Property is unavailable during this time."
|
||||
property_is_already_hired_during_this_time: "Property is already reserved during this time."
|
||||
starting_time_cannot_be_greater_than_ending_time: "Starting time cannot be greater than ending time."
|
||||
please_select_recurring_interval: "Please select recurring interval!"
|
||||
confirm: Confirm
|
||||
cancel: Cancel
|
||||
pick_from_calendar: Pick from calendar
|
||||
how_many_months_ago_can_be_hired: "Unavailable for reservation before how many months?"
|
||||
month: "%{month} month"
|
||||
no_limit: No limit
|
||||
none: None
|
||||
checkbox_hint: You Can Select Mulitple Places
|
||||
add_choice: Add choice
|
||||
radio: Radio
|
||||
checkbox: Checkbox
|
||||
field_name: Field name
|
||||
field_value: Field choices
|
||||
field_type: Field type
|
||||
notes_selector: Note field selector
|
||||
enable_notes_selector: Enable Note field selector
|
||||
editor: Editor
|
||||
email_p_hire_success: Reserve Success
|
||||
email_edit_success: 'Property Hire Module:Edit Success'
|
||||
email_delete_success: 'Property Hire Module:Delete Success'
|
||||
email_p_hire_content: Reserve Success
|
||||
email_edit_content: 'Property Hire Module:Edit Success'
|
||||
email_delete_content: 'Property Hire Module:Delete Success'
|
||||
edit: Edit
|
||||
delete: Delete
|
||||
auto_send_email_set: Auto Send Email Setting
|
||||
email_title: Email Title
|
||||
email_content: Email Content
|
||||
recurring: Recurring
|
||||
recurring_interval: Recurring Interval
|
||||
recurring_interval_types:
|
||||
|
@ -7,7 +112,7 @@ en:
|
|||
week: Week
|
||||
recurring_end_date: Recurring End Date
|
||||
save: Save
|
||||
property_hire: Property
|
||||
property_hire: Reservation
|
||||
my_bookings: My Bookings
|
||||
settings: Settings
|
||||
auto_approve: Auto approve
|
||||
|
@ -17,33 +122,42 @@ en:
|
|||
edit_location: Edit Location
|
||||
add_location: Add Location
|
||||
unavailability: Unavailability
|
||||
unavailable_time: Unavailability
|
||||
available_time: Time Period
|
||||
title: Property Title
|
||||
property_usage: Usage for property
|
||||
property_usage: Subtitle
|
||||
note: Note
|
||||
property_number: Property Number
|
||||
can_be_hired: Available for hire
|
||||
can_be_hired: Available for reservation
|
||||
purchase_date: Purchase Date
|
||||
owners: Owners
|
||||
other_owner: Other Owner
|
||||
owner_email: Owner Email
|
||||
owner_email_rule: Owner Email Rule
|
||||
owner_phone: Owner Phone
|
||||
price: Price
|
||||
set_unavailibility: Set Unavailability
|
||||
limit_start_time: Limit start time
|
||||
limit_end_time: Limit end time
|
||||
p_hire_start_time: Start Date
|
||||
p_hire_end_time: End Date
|
||||
p_open_start_time: Open Date
|
||||
p_open_end_time: Close Date
|
||||
start_time: Start Time
|
||||
end_time: End Time
|
||||
weekdays: Weekdays
|
||||
weekdays: Unavailable days in a week
|
||||
start_date: From Date
|
||||
end_date: To Date
|
||||
description: Unavailability Description
|
||||
unavailibility_note: Unavailability Note
|
||||
property_location: Property Location
|
||||
available_for_hire: Available for hire
|
||||
hire: Hire
|
||||
available_for_hire: Available for reservation
|
||||
hire: Reserve
|
||||
view_calendar: Calendar
|
||||
image: Property Image
|
||||
actions: Actions
|
||||
start_time: Hire Start Time
|
||||
end_time: Hire End Time
|
||||
start_time: Reserve Start Time
|
||||
end_time: Reserve End Time
|
||||
hiring_person_email: Hiring Person Email
|
||||
hiring_person_number: Hiring Person Number
|
||||
hiring_person_name: Hiring Person
|
||||
|
@ -51,3 +165,45 @@ en:
|
|||
note_for_hire: Note For Hire
|
||||
period: Period
|
||||
passed: Accepted
|
||||
'yes': 'Yes'
|
||||
'no': 'No'
|
||||
wait_for_permit: 'Wait for permit'
|
||||
select_interval: Select interval
|
||||
check_availibility: Check Availibility
|
||||
Unavailibility_Schedule: Unavailibility Schedule
|
||||
required: Required
|
||||
organization: Organization
|
||||
person_in_charge: Person in charge
|
||||
tel_of_person_in_charge: Tel. of person in charge
|
||||
department: Department
|
||||
contact_person: Contact person
|
||||
tel_of_contact_person: Tel. of contact person
|
||||
mobile_phone_of_contact_person: Mobile phone of contact person
|
||||
contact_person_Email: Contact person Email
|
||||
contact_person_department: Contact person department
|
||||
special_unavailable_date: Special Unavailable Date
|
||||
manage_booking: Manage Bookings
|
||||
recurring_enable: Enable Recurring
|
||||
owner_email_rules:
|
||||
'0': 'Only Owners'
|
||||
'1': 'Only Owner Email'
|
||||
'2': 'Owners and Owner Email'
|
||||
p_display_start_time: Display in front-page
|
||||
p_display_end_time: Remove from front-page
|
||||
hours_restriction: Limit reservation hours for single user
|
||||
hours_restriction_message: "This property can only be hired for %{no_of_hours} hours every %{duration}"
|
||||
time_period_note: Time period user can use reservation service
|
||||
available_time_note: Available time period
|
||||
calendar: Calendar
|
||||
table: Table
|
||||
view: View
|
||||
reject: Reject
|
||||
edit: Edit
|
||||
delete: Delete
|
||||
accept: Accept
|
||||
today: Today
|
||||
day: Day
|
||||
week: Week
|
||||
month: Month
|
||||
all_properties: All Properties
|
||||
export_reservation_data: Export data
|
||||
|
|
|
@ -1,53 +1,231 @@
|
|||
zh_tw:
|
||||
lists:
|
||||
markups:
|
||||
hint_text: 提示文字
|
||||
restful_actions:
|
||||
copy: 複製
|
||||
fields_display_order: "欄位顯示順序"
|
||||
property_hire:
|
||||
recurring: Recurring
|
||||
recurring_interval: Recurring Interval
|
||||
copy: 複製
|
||||
unfilled: 未填寫
|
||||
hire_time: 預約時間
|
||||
back_to_hire_page: "回到預約頁面"
|
||||
apply_default_time_settings: 套用預設時段設定
|
||||
default_time_settings: 預設時段設定
|
||||
the_reservation_was_successfully_sent: "預約成功送出,請查看Email確認預約資訊!"
|
||||
go_to_infos_page: 前往資訊頁面
|
||||
display_in_reason_for_hire: "顯示於使用用途"
|
||||
need_hire_before: "需提早多久預約"
|
||||
_month: 個月
|
||||
_week: 週
|
||||
_day: 天
|
||||
_hour: 個小時
|
||||
_minute: 分鐘
|
||||
sort_number: 排序數
|
||||
enable_fields_sort: 啟用欄位排序
|
||||
fields_display_order: "欄位顯示順序"
|
||||
this_property_is_available: "<b>可預約</b>"
|
||||
recaptcha:
|
||||
recaptcha: 驗證碼
|
||||
errors:
|
||||
verification_failed: 驗證碼錯誤
|
||||
no_time_can_select: "無時段可選擇!"
|
||||
custom_calendar_type:
|
||||
default: 預設
|
||||
display: 顯示
|
||||
not_display: 不顯示
|
||||
page_setting: 頁面設定
|
||||
display_calendar_default: "是否顯示行事曆在租借頁面(預設值)"
|
||||
display_calendar: "是否顯示行事曆在租借頁面"
|
||||
allow_no_logins_user: "允許未登入使用者預約"
|
||||
please_select_time: "請選擇時段!"
|
||||
date: "日期"
|
||||
time: "時段"
|
||||
please_choose_date: "請選擇日期"
|
||||
please_select: "請選擇"
|
||||
reserve: 預約本日
|
||||
files_links: "檔案與連結"
|
||||
disable_content_page: 關閉內容頁
|
||||
disable_view_calendar_page: '關閉"查詢目前預約狀況"頁面'
|
||||
disable_no_logins_view_calendar: '關閉未登入使用者"查詢目前預約狀況"頁面'
|
||||
display_img: 內容頁顯示封面圖片
|
||||
carousel_image: 輪播圖片
|
||||
carousel_image_title: 輪播圖片(在show頁面底部顯示)
|
||||
custom_carousel_image_width_hint: "未填寫,則使用預設寬度"
|
||||
carousel_image_width: 輪播圖片寬度
|
||||
default_carousel_image_width: 預設輪播圖片寬度
|
||||
cover_image_display_setting: 封面圖片顯示設定
|
||||
full_width: 滿版呈現
|
||||
up_left_corner: 左上角
|
||||
up_right_corner: 右上角
|
||||
name: 顯示名稱
|
||||
placeholder: 提示文字
|
||||
disable: 關閉
|
||||
time_title: 時段名稱
|
||||
reservation_limit: "預約數限制(0代表無限制)"
|
||||
set_availability: 設定開放時段
|
||||
reservation_fields: 預約欄位設定
|
||||
to_require: 是否必填
|
||||
please_save: '調整完後, 請點選"儲存順序"'
|
||||
position: 位置
|
||||
save_order: 儲存順序
|
||||
order: 排序
|
||||
custom_fields_setting: 客製化欄位設定
|
||||
custom_fields: 客製預約欄位
|
||||
recurring_end_date_must_exceed_time: "週期結束時間需超過預約結束時間%{time}!"
|
||||
1_week: "一週"
|
||||
1_month: "一個月"
|
||||
values_are_not_ok: "預約開始時間和結束時間不可為空"
|
||||
dot: " 、 "
|
||||
from: " 從 "
|
||||
to: " 到 "
|
||||
of: "的"
|
||||
at: "在"
|
||||
from_time: "從%{time}開始"
|
||||
from_now_on: "從現在起"
|
||||
every: 每個
|
||||
time1_to_time2: "%{time1}到%{time2}之間"
|
||||
unavailable_hint1: "此地點或設備%{str1}%{str2}%{week_str}%{str3}為不可預約。"
|
||||
unavailable_hint2: "此地點或設備在%{month}個月之前不可預約。"
|
||||
unavailable_hint3: "此地點或設備須提前%{month}%{unit}預約。"
|
||||
Sunday: 週日
|
||||
Monday: 週一
|
||||
Tuesday: 週二
|
||||
Wednesday: 週三
|
||||
Thursday: 週四
|
||||
Friday: 週五
|
||||
Saturday: 週六
|
||||
please_hire_after_date: "請在%{date}之後再預約!"
|
||||
property_is_unavailable_during_this_time: "該時段不可預約。"
|
||||
property_is_already_hired_during_this_time: "該時段已被預約,請再選擇其他時段!"
|
||||
starting_time_cannot_be_greater_than_ending_time: "預約開始時間不能超過預約結束時間!"
|
||||
please_select_recurring_interval: "請選擇預約週期!"
|
||||
please_select_recurring_interval_and_recurring_end_time: "請選擇預約週期和週期結束時間"
|
||||
confirm: 確認
|
||||
cancel: 取消
|
||||
pick_from_calendar: 從日曆上選擇
|
||||
how_many_months_ago_can_be_hired: 多少個月前不開放預約
|
||||
month: "%{month}月"
|
||||
no_limit: 無限制
|
||||
none: 無
|
||||
checkbox_hint: 可重複勾選
|
||||
add_choice: 新增選項
|
||||
radio: 單選
|
||||
checkbox: 多選
|
||||
field_name: 欄位名稱
|
||||
field_value: 欄位選項
|
||||
field_type: 欄位類型
|
||||
notes_selector: 備註選項
|
||||
enable_notes_selector: 啟用備註選項
|
||||
editor: 編輯者
|
||||
email_p_hire_success: 預約成功
|
||||
email_edit_success: '租借模組:編輯成功'
|
||||
email_delete_success: '租借模組:刪除成功'
|
||||
email_p_hire_content: 預約成功
|
||||
email_edit_content: '租借模組:編輯成功'
|
||||
email_delete_content: '租借模組:刪除成功'
|
||||
edit: 編輯
|
||||
delete: 刪除
|
||||
auto_send_email_set: 自動發信設定
|
||||
email_title: 主旨
|
||||
email_content: 內文
|
||||
recurring: 週期性預約
|
||||
recurring_interval: 預約週期
|
||||
recurring_interval_types:
|
||||
month: Month
|
||||
week: Week
|
||||
recurring_end_date: Recurring End Date
|
||||
save: Save
|
||||
my_bookings: My Bookings
|
||||
settings: Settings
|
||||
property_hire: Property
|
||||
manage_locations: Manage Locations
|
||||
location: Location
|
||||
month: 月
|
||||
week: 周
|
||||
recurring_end_date: 週期結束時間
|
||||
save: 送出
|
||||
my_bookings: 我的預約記錄
|
||||
settings: 設定
|
||||
property_hire: 預約
|
||||
manage_locations: 管理位置
|
||||
location: 位置
|
||||
auto_approve: Auto approve
|
||||
property_count: Property Count
|
||||
edit_location: Edit Location
|
||||
add_location: Add Location
|
||||
unavailability: Unavailability
|
||||
title: Property Title
|
||||
property_usage: Usage for property
|
||||
note: Note
|
||||
property_number: Property Number
|
||||
can_be_hired: Available for hire
|
||||
unavailability: 不可預約
|
||||
unavailable_time: 不開放時段
|
||||
available_time: 開放時段
|
||||
title: 名稱
|
||||
select_interval: 選擇週期
|
||||
check_availibility: 檢查是否可預約
|
||||
property_usage: 副標題
|
||||
note: 說明
|
||||
property_number: 編號
|
||||
can_be_hired: 可供預約
|
||||
purchase_date: Purchase Date
|
||||
owners: Owners
|
||||
other_owner: Other Owner
|
||||
owner_email: Owner Email
|
||||
owner_phone: Owner Phone
|
||||
owners: 管理人
|
||||
other_owner: 其他管理人
|
||||
owner_email: 管理人Email
|
||||
owner_email_rule: 管理人Email規則
|
||||
owner_phone: 管理人聯絡電話
|
||||
price: Price
|
||||
set_unavailibility: Set Unavailability
|
||||
start_time: Start Time
|
||||
end_time: End Time
|
||||
weekdays: Weekdays
|
||||
start_date: From Date
|
||||
end_date: To Date
|
||||
set_unavailibility: 設定不開放時段
|
||||
weekdays: 每週不開放預約日
|
||||
start_date: 套用限制開始日期
|
||||
end_date: 套用限制結束日期
|
||||
p_hire_start_time: 開始日期
|
||||
p_hire_end_time: 截止日期
|
||||
p_open_start_time: 開放日期
|
||||
p_open_end_time: 結束日期
|
||||
description: Unavailability Description
|
||||
unavailibility_note: Unavailability Note
|
||||
property_location: Property Location
|
||||
available_for_hire: Available for hire
|
||||
hire: Hire
|
||||
view_calendar: Calendar
|
||||
available_for_hire: 可供預約
|
||||
hire: 線上預約
|
||||
view_calendar: 查詢目前預約狀況
|
||||
image: Property Image
|
||||
actions: Actions
|
||||
start_time: Hire Start Time
|
||||
end_time: Hire End Time
|
||||
hiring_person_email: Hiring Person Email
|
||||
hiring_person_number: Hiring Person Number
|
||||
hiring_person_name: Hiring Person
|
||||
reason_for_hire: Reason For Hire
|
||||
note_for_hire: Note For Hire
|
||||
period: Period
|
||||
passed: Accepted
|
||||
actions: 動作
|
||||
limit_start_time: 限制開始時間
|
||||
limit_end_time: 限制結束時間
|
||||
start_time: 預約開始時間
|
||||
end_time: 預約結束時間
|
||||
hiring_person_email: 預約人電子信箱
|
||||
hiring_person_number: 預約人聯絡電話
|
||||
hiring_person_name: 預約人姓名
|
||||
reason_for_hire: 使用用途
|
||||
note_for_hire: 備註
|
||||
period: 預約時段
|
||||
passed: 允許預約
|
||||
'yes': 是
|
||||
'no': 否
|
||||
wait_for_permit: 等待授權
|
||||
Unavailibility_Schedule: 不提供預約時段
|
||||
required: 必填
|
||||
organization: 預約單位
|
||||
person_in_charge: 單位負責人
|
||||
tel_of_person_in_charge: 負責人聯絡電話
|
||||
department: 服務單位
|
||||
contact_person: 聯絡人
|
||||
tel_of_contact_person: 聯絡人聯絡電話
|
||||
mobile_phone_of_contact_person: 聯絡人行動電話
|
||||
contact_person_Email: 聯絡Email
|
||||
contact_person_department: 聯絡人服務單位
|
||||
special_unavailable_date: 特定不開放預約⽇
|
||||
manage_booking: 管理我的預約
|
||||
recurring_enable: 啟用週期性預約
|
||||
owner_email_rules:
|
||||
'0': '僅管理人'
|
||||
'1': '僅管理人Email'
|
||||
'2': '管理人+管理人Email'
|
||||
p_display_start_time: 呈現於網頁前台
|
||||
p_display_end_time: 於網頁前台下架
|
||||
hours_restriction: 限制單一使用者預約時數
|
||||
hours_restriction_message: "每 %{duration}限制僅能預約 %{no_of_hours}"
|
||||
time_period_note: 使用者可以進行預約
|
||||
available_time_note: 可供預約的日期區間
|
||||
calendar: 日曆
|
||||
table: 列表
|
||||
view: 查看
|
||||
reject: 拒絕
|
||||
edit: 編輯
|
||||
delete: 刪除
|
||||
accept: 同意
|
||||
today: 今天
|
||||
day: 日模式
|
||||
week: 週模式
|
||||
month: 月模式
|
||||
all_properties: All Properties
|
||||
export_reservation_data: Export data
|
|
@ -4,16 +4,26 @@ Rails.application.routes.draw do
|
|||
scope "(:locale)", locale: Regexp.new(locales.join("|")) do
|
||||
get "/xhr/property_hires/check_availability" => "property_hires#check_availability"
|
||||
post "/xhr/property_hires/make_booking" => "property_hires#make_booking"
|
||||
patch "/xhr/property_hires/make_booking" => "property_hires#make_booking"
|
||||
get "/xhr/property_hires/get_bookings" => "property_hires#get_bookings"
|
||||
namespace :admin do
|
||||
get "property_hires/checkforthread", to: "property_hires#checkforthread"
|
||||
resources :property_hires do
|
||||
member do
|
||||
get 'copy'
|
||||
get "edit_location"
|
||||
patch "update_location"
|
||||
delete "destroy_location"
|
||||
get "show_booking_details"
|
||||
get "pass_booking"
|
||||
delete "delete_booking_details"
|
||||
get "edit_hire"
|
||||
patch "update_hire"
|
||||
get "custom_fields"
|
||||
get "fields_display_order"
|
||||
get "export_reservation_data"
|
||||
post "update_fields_display_order"
|
||||
patch "update_fields_display_order"
|
||||
end
|
||||
collection do
|
||||
get "my_bookings"
|
||||
|
@ -22,6 +32,8 @@ Rails.application.routes.draw do
|
|||
get "manage_locations"
|
||||
get "add_location"
|
||||
post "create_location"
|
||||
get "order"
|
||||
post "updateorder"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,11 +11,29 @@ module PropertyHire
|
|||
authorizable
|
||||
frontend_enabled
|
||||
data_count 1..30
|
||||
require File.expand_path('../../../app/models/property_hire_setting', __FILE__)
|
||||
if defined?(PropertyHireSetting)
|
||||
settings_count = PropertyHireSetting.count
|
||||
if settings_count == 0
|
||||
PropertyHireSetting.create
|
||||
elsif settings_count > 1
|
||||
PropertyHireSetting.all[1..-1].each{|s| s.destroy}
|
||||
end
|
||||
end
|
||||
|
||||
if File.basename($0) != 'rake'
|
||||
begin
|
||||
avoid_page_cache HireEmailSet
|
||||
avoid_page_cache PHire
|
||||
rescue => e
|
||||
puts ["avoid_page_cache", e.to_s]
|
||||
end
|
||||
end
|
||||
side_bar do
|
||||
head_label_i18n 'property_hire.property_hire', icon_class: "icons-map"
|
||||
available_for "users"
|
||||
active_for_controllers (['admin/property_hires'])
|
||||
head_link_path "my_bookings_admin_property_hires_path"
|
||||
head_link_path "admin_property_hires_path"
|
||||
|
||||
context_link 'property_hire.my_bookings',
|
||||
:link_path=>"my_bookings_admin_property_hires_path" ,
|
||||
|
@ -28,7 +46,11 @@ module PropertyHire
|
|||
:priority=>2,
|
||||
:active_for_action=>{'admin/property_hires'=>"index"},
|
||||
:available_for => 'sub_managers'
|
||||
|
||||
context_link 'property_hire.order',
|
||||
:link_path=>"order_admin_property_hires_path" ,
|
||||
:priority=>2,
|
||||
:active_for_action=>{'admin/property_hires'=>"order"},
|
||||
:available_for => 'managers'
|
||||
context_link 'new_',
|
||||
:link_path=>"new_admin_property_hire_path" ,
|
||||
:priority=>3,
|
||||
|
|
|
@ -2,3 +2,26 @@
|
|||
# task :property_hire do
|
||||
# # Task goes here
|
||||
# end
|
||||
|
||||
namespace :property_hire_tasks do
|
||||
task :prepare_download,[:property_id, :url] => :environment do |task,args|
|
||||
id = args.property_id
|
||||
I18n.locale = :zh_tw
|
||||
property = Property.find(id)
|
||||
ac = ActionController::Base.new()
|
||||
host_url = Site.first.root_url
|
||||
if host_url == "http://"
|
||||
host_url = "http://#{args.url}"
|
||||
end
|
||||
xlsx = ac.render_to_string handlers: [:axlsx], formats: [:xlsx], template: "property_hire_export/export", locals: {property: property, site_in_use_locales: Site.first.in_use_locales, url: host_url}
|
||||
dirname = "public/uploads/reservation_export/#{id}"
|
||||
FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
|
||||
f = "#{dirname}/#{property.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')}.xlsx"
|
||||
if File.exist?(f)
|
||||
File.delete(f)
|
||||
end
|
||||
file = File.open(f, "w")
|
||||
xlsx.force_encoding("utf-8")
|
||||
file.write(xlsx)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr data-list="headers" data-level="0">
|
||||
<th>{{column}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-list="properties" data-level="0">
|
||||
<tr>
|
||||
<td><a href="{{url_to_show}}">{{title}}</a></td>
|
||||
<td>{{location}}</td>
|
||||
<td data-list="actions" data-level="1">
|
||||
<a href="{{link}}" class="btn {{btn-class}}">{{text}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{{pagination_goes_here}}
|
|
@ -0,0 +1,18 @@
|
|||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr data-list="headers" data-level="0">
|
||||
<th>{{column}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-list="properties" data-level="0">
|
||||
<tr>
|
||||
<td><a href="{{url_to_show}}">{{title}}</a></td>
|
||||
<td><img width="150" src="{{image-thumb}}" alt="property image"></td>
|
||||
<td>{{location}}</td>
|
||||
<td data-list="actions" data-level="1">
|
||||
<a href="{{link}}" class="btn {{btn-class}}">{{text}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{{pagination_goes_here}}
|
|
@ -0,0 +1,14 @@
|
|||
<div class="property_index_3_col" >
|
||||
<ul class="property_list" data-level="0" data-list="properties">
|
||||
<li class="property_item col-md-4 col-xl-3">
|
||||
<div class="property_img_wrap">
|
||||
<a href="{{url_to_show}}" title="{{title}}"><img src="{{image-thumb}}" alt="{{title}}"></a>
|
||||
</div>
|
||||
<div class="property_content_wrap">
|
||||
<h4><a href="{{url_to_show}}" title="{{title}}">{{title}}</a></h4>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
{{pagination_goes_here}}
|
|
@ -0,0 +1,14 @@
|
|||
<div class="property_index_3_col" >
|
||||
<ul class="property_list" data-level="0" data-list="properties">
|
||||
<li class="property_item col-sm-4 col-md-3">
|
||||
<div class="property_img_wrap">
|
||||
<a href="{{url_to_show}}" title="{{title}}"><img src="{{image-thumb}}" alt="{{title}}"></a>
|
||||
</div>
|
||||
<div class="property_content_wrap">
|
||||
<h4><a href="{{url_to_show}}" title="{{title}}">{{title}}</a></h4>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
{{pagination_goes_here}}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"frontend": [
|
||||
{
|
||||
"filename" : "index",
|
||||
"name" : {
|
||||
"zh_tw" : "1. 列表",
|
||||
"en" : "1. List"
|
||||
},
|
||||
"thumbnail" : "thumb.png"
|
||||
},
|
||||
{
|
||||
"filename" : "index_3_col",
|
||||
"name" : {
|
||||
"zh_tw" : "2. 三欄式圖文",
|
||||
"en" : "2. 3-Column Standard Image + Text Lite"
|
||||
},
|
||||
"thumbnail" : "event_news_thumb1.png"
|
||||
},
|
||||
{
|
||||
"filename" : "index_4_col",
|
||||
"name" : {
|
||||
"zh_tw" : "3. 四欄式圖文",
|
||||
"en" : "3. 4-Column Standard Image + Text Lite"
|
||||
},
|
||||
"thumbnail" : "event_news_thumb2.png"
|
||||
}
|
||||
],
|
||||
"widgets" : [
|
||||
{
|
||||
"filename" : "widget1",
|
||||
"name" : {
|
||||
"zh_tw" : "1. 列表",
|
||||
"en" : "1. List"
|
||||
},
|
||||
"thumbnail" : "thumb.png"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr style="text-align: center;">
|
||||
<td colspan="2"><img width="600" src="{{image}}"></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-list="data" data-level="0">
|
||||
<tr>
|
||||
<td>{{header}}</td>
|
||||
<td>{{value}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div>
|
||||
<a href="{{back_url}}" class="btn btn-warning">Back</a>
|
||||
<span data-list="actions" data-level="0">
|
||||
<a href="{{link}}" class="btn {{btn-class}}">{{text}}</a>
|
||||
</span>
|
||||
</div>
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
|
@ -2,7 +2,30 @@ $:.push File.expand_path("../lib", __FILE__)
|
|||
|
||||
# Maintain your gem's version:
|
||||
require "property_hire/version"
|
||||
|
||||
begin
|
||||
require "yaml"
|
||||
require "erb"
|
||||
data = File.open(File.join(File.dirname(__FILE__), 'config', 'list.yml')).read
|
||||
$property_list = YAML.safe_load(ERB.new(data).result(binding)).map{|k,v| [k.to_sym,v]}.to_h
|
||||
rescue => e
|
||||
puts [e.to_s,e.backtrace]
|
||||
end
|
||||
bundle_update_flag = ARGV[0]=='update' || ARGV[0]=='install'
|
||||
if bundle_update_flag
|
||||
app_path = File.expand_path(__dir__)
|
||||
template_path = ENV['PWD'] + '/app/templates'
|
||||
all_template = Dir.glob(template_path+'/*/')
|
||||
puts 'copying module'
|
||||
all_template.each do |folder|
|
||||
if folder.split('/')[-1] != 'mobile'
|
||||
begin
|
||||
system ('cp -r '+ app_path + '/modules/ ' + folder)
|
||||
rescue
|
||||
puts 'error copy'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# Describe your gem and declare its dependencies:
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "property_hire"
|
||||
|
|
Loading…
Reference in New Issue