(function ($){
window.booklyStaffAppointments=function (Options){
let $container=$('.bookly-staff-cabinet-appointments.' + Options.wrapper);
if(!$container.length){
return;
}
let $list=$('.bookly-js-appointments-list', $container),
$customerFilter=$('#bookly-filter-customer', $container),
$idFilter=$('#bookly-filter-id', $container),
$appointmentDateFilter=$('#bookly-filter-date', $container),
$creationDateFilter=$('#bookly-filter-creation-date', $container),
$statusFilter=$('#bookly-filter-status', $container),
$serviceFilter=$('#bookly-filter-service', $container),
$locationFilter=$('#bookly-filter-location', $container),
$newAppointmentBtn=$('#bookly-new-appointment', $container),
isMobile=false,
columns=[],
order=[],
pickers={
dateFormat: 'YYYY-MM-DD',
appointmentDate: {
startDate: moment().startOf('month'),
endDate: moment().endOf('month'),
},
creationDate: {
startDate: moment(),
endDate: moment().add(100, 'years'),
},
}
;
try {
document.createEvent('TouchEvent');
isMobile=true;
} catch (e){}
function onChangeFilter(){
dt.ajax.reload();
}
$statusFilter.booklyDropdown({onChange: onChangeFilter});
$('.bookly-js-select', $container).val(null);
$.each(BooklySCAppointmentsL10n.datatables.appointments.settings.filter, function (field, value){
if(field!=='status'){
if(value!=''){
$('#bookly-filter-' + field, $container).val(value);
}
if($('#bookly-filter-' + field, $container).prop('type')=='select-one'){
if($('#bookly-filter-' + field + ' option[value="' + value + '"]', $container).length==0){
$('#bookly-filter-' + field, $container).val(null);
}}
}});
if(BooklySCAppointmentsL10n.datatables.appointments.settings.filter.hasOwnProperty('status')){
$statusFilter.booklyDropdown('setSelected', BooklySCAppointmentsL10n.datatables.appointments.settings.filter.status);
}else{
$statusFilter.booklyDropdown('selectAll');
}
let
pickerRanges1={},
pickerRanges2={}
;
pickerRanges1[BooklySCAppointmentsL10n.dateRange.anyTime]=[moment().subtract(100, 'years'), moment().add(100, 'years')];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.yesterday]=[moment().subtract(1, 'days'), moment().subtract(1, 'days')];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.today]=[moment(), moment()];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.tomorrow]=[moment().add(1, 'days'), moment().add(1, 'days')];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.last_7]=[moment().subtract(7, 'days'), moment()];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.last_30]=[moment().subtract(30, 'days'), moment()];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.next_7]=[moment(), moment().add(7, 'days')];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.next_30]=[moment(), moment().add(30, 'days')];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.thisMonth]=[moment().startOf('month'), moment().endOf('month')];
pickerRanges1[BooklySCAppointmentsL10n.dateRange.nextMonth]=[moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')];
pickerRanges2[BooklySCAppointmentsL10n.dateRange.anyTime]=pickerRanges1[BooklySCAppointmentsL10n.dateRange.anyTime];
pickerRanges2[BooklySCAppointmentsL10n.dateRange.yesterday]=pickerRanges1[BooklySCAppointmentsL10n.dateRange.yesterday];
pickerRanges2[BooklySCAppointmentsL10n.dateRange.today]=pickerRanges1[BooklySCAppointmentsL10n.dateRange.today];
pickerRanges2[BooklySCAppointmentsL10n.dateRange.last_7]=pickerRanges1[BooklySCAppointmentsL10n.dateRange.last_7];
pickerRanges2[BooklySCAppointmentsL10n.dateRange.last_30]=pickerRanges1[BooklySCAppointmentsL10n.dateRange.last_30];
pickerRanges2[BooklySCAppointmentsL10n.dateRange.thisMonth]=pickerRanges1[BooklySCAppointmentsL10n.dateRange.thisMonth];
if(BooklySCAppointmentsL10n.tasks.enabled){
pickerRanges1[BooklySCAppointmentsL10n.tasks.title]=[moment(), moment().add(1, 'days')];
}
$appointmentDateFilter.daterangepicker({
parentEl: $appointmentDateFilter.parent(),
startDate: pickers.appointmentDate.startDate,
endDate: pickers.appointmentDate.endDate,
ranges: pickerRanges1,
showDropdowns: true,
linkedCalendars: false,
autoUpdateInput: false,
locale: $.extend({}, BooklySCAppointmentsL10n.dateRange, BooklySCAppointmentsL10n.datePicker)
},
function (start, end, label){
switch (label){
case BooklySCAppointmentsL10n.tasks.title:
$appointmentDateFilter
.data('date', 'null')
.find('span')
.html(BooklySCAppointmentsL10n.tasks.title);
break;
case BooklySCAppointmentsL10n.dateRange.anyTime:
$appointmentDateFilter
.data('date', 'any')
.find('span')
.html(BooklySCAppointmentsL10n.dateRange.anyTime);
break;
default:
$appointmentDateFilter
.data('date', start.format(pickers.dateFormat) + ' - ' + end.format(pickers.dateFormat))
.find('span')
.html(start.format(BooklySCAppointmentsL10n.dateRange.format) + ' - ' + end.format(BooklySCAppointmentsL10n.dateRange.format));
}}
);
$creationDateFilter.daterangepicker({
parentEl: $creationDateFilter.parent(),
startDate: pickers.creationDate.startDate,
endDate: pickers.creationDate.endDate,
ranges: pickerRanges2,
showDropdowns: true,
linkedCalendars: false,
autoUpdateInput: false,
locale: $.extend(BooklySCAppointmentsL10n.dateRange, BooklySCAppointmentsL10n.datePicker)
},
function (start, end, label){
switch (label){
case BooklySCAppointmentsL10n.tasks.title:
$creationDateFilter
.data('date', 'null')
.find('span')
.html(BooklySCAppointmentsL10n.tasks.title);
break;
case BooklySCAppointmentsL10n.dateRange.anyTime:
$creationDateFilter
.data('date', 'any')
.find('span')
.html(BooklySCAppointmentsL10n.dateRange.createdAtAnyTime);
break;
default:
$creationDateFilter
.data('date', start.format(pickers.dateFormat) + ' - ' + end.format(pickers.dateFormat))
.find('span')
.html(start.format(BooklySCAppointmentsL10n.dateRange.format) + ' - ' + end.format(BooklySCAppointmentsL10n.dateRange.format));
}}
);
$.each(BooklySCAppointmentsL10n.datatables.appointments.settings.columns, function (column, show){
if(show){
switch (column){
case 'customer_full_name':
columns.push({data: 'customer.full_name', render: $.fn.dataTable.render.text()});
break;
case 'customer_phone':
columns.push({
data: 'customer.phone',
render: function (data, type, row, meta){
if(isMobile){
return '<a href="tel:' + window.booklyIntlTelInput.utils.formatNumber($.fn.dataTable.render.text().display(data), null, window.booklyIntlTelInput.utils.numberFormat.INTERNATIONAL) + '">' + $.fn.dataTable.render.text().display(data) + '</a>';
}else{
return data ? '<span style="white-space: nowrap;">' + window.booklyIntlTelInput.utils.formatNumber($.fn.dataTable.render.text().display(data), null, window.booklyIntlTelInput.utils.numberFormat.INTERNATIONAL) + '</span>':'';
}}
});
break;
case 'customer_email':
columns.push({data: 'customer.email', render: $.fn.dataTable.render.text()});
break;
case 'customer_address':
columns.push({data: 'customer.address', render: $.fn.dataTable.render.text(), orderable: false});
break;
case 'customer_birthday':
columns.push({data: 'customer.birthday', render: $.fn.dataTable.render.text()});
break;
case 'staff_name':
columns.push({data: 'staff.name', render: $.fn.dataTable.render.text()});
break;
case 'service_title':
columns.push({
data: 'service.title',
render: function (data, type, row, meta){
data=$.fn.dataTable.render.text().display(data);
if(row.service.extras.length){
var extras='<ul class="bookly-list list-dots">';
$.each(row.service.extras, function (key, item){
extras +='<li><nobr>' + item.title + '</nobr></li>';
});
extras +='</ul>';
return data + extras;
}else{
return data;
}}
});
break;
case 'payment':
columns.push({
data: 'payment',
render: function (data, type, row, meta){
if(row.payment_id){
if(Options.read_only){
return data;
}
return '<a type="button" data-action="show-payment" class="text-primary" data-payment_id="' + row.payment_id + '">' + data + '</a>';
}
return '';
}});
break;
case 'service_duration':
columns.push({data: 'service.duration'});
break;
case 'attachments':
columns.push({
data: 'attachment',
render: function (data, type, row, meta){
if(data=='1'){
if(Options.read_only){
return '<i class="fas fa-fw fa-paperclip"></i>';
}
return '<button type="button" class="btn btn-link" data-action="show-attachments" title="' + BooklySCAppointmentsL10n.attachments + '"><i class="fas fa-fw fa-paperclip"></i></button>';
}
return '';
}});
break;
case 'rating':
columns.push({
data: 'rating',
render: function (data, type, row, meta){
if(row.rating_comment==null){
return row.rating;
}else{
return '<a href="#" data-toggle="bookly-popover" data-trigger="hover" data-placement="bottom" data-content="' + $.fn.dataTable.render.text().display(row.rating_comment) + '" data-container="#bookly-appointments-list">' + $.fn.dataTable.render.text().display(row.rating) + '</a>';
}},
});
break;
case 'internal_note':
case 'locations':
case 'notes':
case 'number_of_persons':
columns.push({data: column, render: $.fn.dataTable.render.text()});
break;
case 'online_meeting':
columns.push({
data: 'online_meeting_provider',
render: function (data, type, row, meta){
switch (data){
case 'zoom':
return '<a class="badge badge-primary" href="https://zoom.us/j/' + $.fn.dataTable.render.text().display(row.online_meeting_start_url) + '" target="_blank"><i class="fas fa-video fa-fw"></i> Zoom <i class="fas fa-external-link-alt fa-fw"></i></a>';
case 'google_meet':
return '<a class="badge badge-primary" href="' + $.fn.dataTable.render.text().display(row.online_meeting_start_url) + '" target="_blank"><i class="fas fa-video fa-fw"></i> Google Meet <i class="fas fa-external-link-alt fa-fw"></i></a>';
case 'jitsi':
return '<a class="badge badge-primary" href="' + $.fn.dataTable.render.text().display(row.online_meeting_start_url) + '" target="_blank"><i class="fas fa-video fa-fw"></i> Jitsi Meet <i class="fas fa-external-link-alt fa-fw"></i></a>';
case 'bbb':
return '<a class="badge badge-primary" href="' + $.fn.dataTable.render.text().display(row.online_meeting_start_url) + '" target="_blank"><i class="fas fa-video fa-fw"></i> BigBlueButton <i class="fas fa-external-link-alt fa-fw"></i></a>';
default:
return '';
}},
});
break;
default:
if(column.startsWith('custom_fields_')){
columns.push({
data: column.replace(/_([^_]*)$/, '.$1'),
render: $.fn.dataTable.render.text(),
orderable: false
});
}else{
columns.push({data: column, render: $.fn.dataTable.render.text()});
}
break;
}}
});
if(!Options.read_only){
columns.push({
data: null,
responsivePriority: 1,
orderable: false,
width: 120,
render: function(data, type, row, meta){
return '<button type="button" class="btn btn-default" data-action="edit"><i class="far fa-fw fa-edit mr-lg-1"></i><span class="d-none d-lg-inline">' + BooklySCAppointmentsL10n.edit + '…</span></button>';
}});
}
columns[0].responsivePriority=0;
$.each(BooklySCAppointmentsL10n.datatables.appointments.settings.order, function (_, value){
const index=columns.findIndex(function (c){ return c.data===value.column; });
if(index!==-1){
order.push([index, value.order]);
}});
var dt=$list.DataTable({
order: order,
info: false,
searching: false,
lengthChange: false,
processing: true,
responsive: true,
pageLength: 25,
pagingType: 'numbers',
serverSide: true,
drawCallback: function (settings){
$('[data-toggle="bookly-popover"]', $list).on('click', function (e){
e.preventDefault();
}).booklyPopover();
dt.responsive.recalc();
},
ajax: {
url: ajaxurl,
type: 'POST',
data: function (d){
return $.extend({action: 'bookly_staff_cabinet_get_appointments', csrf_token: BooklyL10nGlobal.csrf_token}, {
filter: {
id: $idFilter.val(),
date: $appointmentDateFilter.data('date'),
created_date: $creationDateFilter.data('date'),
customer: $customerFilter.val(),
service: $serviceFilter.val(),
status: $statusFilter.booklyDropdown('getSelected'),
location: $locationFilter.val()
}}, d);
}},
columns: columns,
language: {
zeroRecords: BooklySCAppointmentsL10n.zeroRecords,
processing: BooklySCAppointmentsL10n.processing,
emptyTable: BooklySCAppointmentsL10n.emptyTable,
loadingRecords: BooklySCAppointmentsL10n.loadingRecords
},
layout: {
bottomStart: 'paging',
bottomEnd: null
}});
dt.on('responsive-display', function (e, datatable, row, showHide, update){
if(showHide){
$('[data-toggle="bookly-popover"]', row.child()).on('click', function (e){
e.preventDefault();
}).booklyPopover();
}});
if(!Options.read_only){
$list
.on('click', '[data-action=show-payment]', function(){
BooklyPaymentDetailsDialog.showDialog({
payment_id: getDTRowData(this).payment_id,
done: function(event){
dt.ajax.reload(null, false);
}});
})
.on('click', '[data-action=edit]', function(e){
e.preventDefault();
BooklyAppointmentDialog.showDialog(getDTRowData(this).id,
null,
null,
function(event){
dt.ajax.reload(null, false);
}
)
});
$newAppointmentBtn.on('click', function(){
BooklyAppointmentDialog.showDialog(null,
null,
moment(),
function(event){
dt.ajax.reload(null, false);
}
)
});
}
$('.bookly-js-select')
.booklySelect2({
width: '100%',
theme: 'bootstrap4',
dropdownParent: $container,
allowClear: true,
placeholder: '',
language: {
noResults: function (){
return BooklySCAppointmentsL10n.no_result_found;
}},
matcher: function (params, data){
const term=$.trim(params.term).toLowerCase();
if(term===''||data.text.toLowerCase().indexOf(term)!==-1){
return data;
}
let result=null;
const search=$(data.element).data('search');
search &&
search.find(function (text){
if(result===null&&text.toLowerCase().indexOf(term)!==-1){
result=data;
}});
return result;
}});
$('.bookly-js-select-ajax')
.booklySelect2({
width: '100%',
theme: 'bootstrap4',
dropdownParent: $container,
allowClear: true,
placeholder: '',
language: {
noResults: function (){
return BooklySCAppointmentsL10n.no_result_found;
},
searching: function (){
return BooklySCAppointmentsL10n.searching;
}},
ajax: {
url: ajaxurl,
dataType: 'json',
delay: 250,
data: function (params){
params.page=params.page||1;
return {
action: this.action===undefined ? $(this).data('ajax--action'):this.action,
filter: params.term,
page: params.page,
csrf_token: BooklyL10nGlobal.csrf_token
};}},
});
function getDTRowData(element){
let $el=$(element).closest('td');
if($el.hasClass('child')){
$el=$el.closest('tr').prev();
}
return dt.row($el).data();
}
$idFilter.on('keyup', onChangeFilter);
$appointmentDateFilter.on('apply.daterangepicker', onChangeFilter);
$creationDateFilter.on('apply.daterangepicker', onChangeFilter);
$customerFilter.on('change', onChangeFilter);
$serviceFilter.on('change', onChangeFilter);
$locationFilter.on('change', onChangeFilter);
}})(jQuery);