Added second category of exceptions (warnings) that are not very important to each operation.
Added appointment cancellation reason field to emails.
This commit is contained in:
parent
2bd31f54b6
commit
4b52ccfd40
11 changed files with 537 additions and 389 deletions
|
@ -134,8 +134,8 @@ class Appointments extends CI_Controller {
|
|||
$service_data, $customer_data, $company_settings);
|
||||
}
|
||||
}
|
||||
} catch(SyncException $syn_exc) {
|
||||
$view_data['exceptions'][] = $syn_exc;
|
||||
} catch(Exception $exc) {
|
||||
$view_data['exceptions'][] = $exc;
|
||||
}
|
||||
|
||||
// :: SEND NOTIFICATION EMAILS TO BOTH CUSTOMER AND PROVIDER
|
||||
|
@ -174,8 +174,8 @@ class Appointments extends CI_Controller {
|
|||
$this->notifications->send_appointment_details($appointment_data, $provider_data,
|
||||
$service_data, $customer_data, $company_settings, $provider_title,
|
||||
$provider_message, $provider_link, $provider_data['email']);
|
||||
} catch(NotificationException $not_exc) {
|
||||
$view_data['exceptions'][] = $not_exc;
|
||||
} catch(Exception $exc) {
|
||||
$view_data['exceptions'][] = $exc;
|
||||
}
|
||||
|
||||
// :: LOAD THE BOOK SUCCESS VIEW
|
||||
|
@ -204,6 +204,8 @@ class Appointments extends CI_Controller {
|
|||
*
|
||||
* @param string $appointment_hash This is used to distinguish the
|
||||
* appointment record.
|
||||
* @param string $_POST['cancel_reason'] The text that describes why
|
||||
* the customer cancelled the appointment.
|
||||
*/
|
||||
public function cancel($appointment_hash) {
|
||||
try {
|
||||
|
@ -237,29 +239,41 @@ class Appointments extends CI_Controller {
|
|||
|
||||
// :: SYNC APPOINTMENT REMOVAL WITH GOOGLE CALENDAR
|
||||
if ($appointment_data['id_google_calendar'] != NULL) {
|
||||
try {
|
||||
$google_sync = $this->Providers_Model->get_setting('google_sync',
|
||||
$appointment_data['id_users_provider']);
|
||||
|
||||
if ($google_sync == TRUE) {
|
||||
$google_token = json_decode($this->Providers_Model
|
||||
->get_setting('google_token', $provider_data['id']));
|
||||
|
||||
$this->load->library('Google_Sync');
|
||||
$this->google_sync->refresh_token($google_token->refresh_token);
|
||||
$this->google_sync->delete_appointment($appointment_data['id_google_calendar']);
|
||||
}
|
||||
} catch(Exception $exc) {
|
||||
$exceptions[] = $exc;
|
||||
}
|
||||
}
|
||||
|
||||
// :: SEND NOTIFICATION EMAILS TO CUSTOMER AND PROVIDER
|
||||
try {
|
||||
$this->load->library('Notifications');
|
||||
$this->notifications->send_delete_appointment($appointment_data, $provider_data,
|
||||
$service_data, $customer_data, $company_settings, $provider_data['email']);
|
||||
$service_data, $customer_data, $company_settings, $provider_data['email'],
|
||||
$_POST['cancel_reason']);
|
||||
$this->notifications->send_delete_appointment($appointment_data, $provider_data,
|
||||
$service_data, $customer_data, $company_settings, $customer_data['email']);
|
||||
|
||||
$service_data, $customer_data, $company_settings, $customer_data['email'],
|
||||
$_POST['cancel_reason']);
|
||||
} catch(Exception $exc) {
|
||||
$exceptions[] = $exc;
|
||||
}
|
||||
} catch(Exception $exc) {
|
||||
// Display the error message to the customer.
|
||||
$view_data['error'] = $exc->getMessage();
|
||||
$exceptions[] = $exc;
|
||||
}
|
||||
|
||||
if (isset($exceptions)) {
|
||||
$view_data['exceptions'] = $exceptions;
|
||||
}
|
||||
|
||||
$this->load->view('appointments/cancel', $view_data);
|
||||
|
@ -402,7 +416,7 @@ class Appointments extends CI_Controller {
|
|||
$period_start = date('H:i', strtotime($period['start']));
|
||||
$period_end = date('H:i', strtotime($period['end']));
|
||||
|
||||
if ($period_start < $appt_start && $period_end > $appt_end) {
|
||||
if ($period_start <= $appt_start && $period_end >= $appt_end) {
|
||||
$is_still_available = TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -412,7 +426,7 @@ class Appointments extends CI_Controller {
|
|||
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array( exceptionToJavascript($exc) )
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ class Backend extends CI_Controller {
|
|||
$this->load->model('Services_Model');
|
||||
$this->load->model('Customers_Model');
|
||||
|
||||
try {
|
||||
if ($_POST['filter_type'] == FILTER_TYPE_PROVIDER) {
|
||||
$where_id = 'id_users_provider';
|
||||
} else {
|
||||
|
@ -77,15 +78,18 @@ class Backend extends CI_Controller {
|
|||
$appointments = $this->Appointments_Model->get_batch($where_clause);
|
||||
|
||||
foreach($appointments as &$appointment) {
|
||||
$appointment['provider'] = $this->Providers_Model
|
||||
->get_row($appointment['id_users_provider']);
|
||||
$appointment['service'] = $this->Services_Model
|
||||
->get_row($appointment['id_services']);
|
||||
$appointment['customer'] = $this->Customers_Model
|
||||
->get_row($appointment['id_users_customer']);
|
||||
$appointment['provider'] = $this->Providers_Model->get_row($appointment['id_users_provider']);
|
||||
$appointment['service'] = $this->Services_Model->get_row($appointment['id_services']);
|
||||
$appointment['customer'] = $this->Customers_Model->get_row($appointment['id_users_customer']);
|
||||
}
|
||||
|
||||
echo json_encode($appointments);
|
||||
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,7 +118,7 @@ class Backend extends CI_Controller {
|
|||
// :: SAVE APPOINTMENT CHANGES TO DATABASE
|
||||
if (isset($_POST['appointment_data'])) {
|
||||
$appointment_data = json_decode(stripcslashes($_POST['appointment_data']), true);
|
||||
|
||||
$manage_mode = isset($appointment_data['id']);
|
||||
// If the appointment does not contain the customer record id, then it
|
||||
// means that is is going to be inserted. Get the customer's record id.
|
||||
if (!isset($appointment_data['id_users_customer'])) {
|
||||
|
@ -136,15 +140,15 @@ class Backend extends CI_Controller {
|
|||
);
|
||||
|
||||
// :: SYNC APPOINTMENT CHANGES WITH GOOGLE CALENDAR
|
||||
$google_sync = $this->Providers_Model
|
||||
->get_setting('google_sync', $appointment_data['id_users_provider']);
|
||||
try {
|
||||
$google_sync = $this->Providers_Model->get_setting('google_sync',
|
||||
$appointment_data['id_users_provider']);
|
||||
|
||||
if ($google_sync == TRUE) {
|
||||
$google_token = json_decode($this->Providers_Model
|
||||
->get_setting('google_token', $appointment_data['id_users_provider']));
|
||||
$google_token = json_decode($this->Providers_Model->get_setting('google_token',
|
||||
$appointment_data['id_users_provider']));
|
||||
|
||||
$this->load->library('Google_Sync');
|
||||
|
||||
$this->google_sync->refresh_token($google_token->refresh_token);
|
||||
|
||||
if ($appointment_data['id_google_calendar'] == NULL) {
|
||||
|
@ -155,20 +159,38 @@ class Backend extends CI_Controller {
|
|||
$service_data, $customer_data, $company_settings);
|
||||
}
|
||||
}
|
||||
} catch(Exception $exc) {
|
||||
$warnings[] = exceptionToJavascript($exc);
|
||||
}
|
||||
|
||||
// :: SEND EMAIL NOTIFICATIONS TO PROVIDER AND CUSTOMER
|
||||
try {
|
||||
$this->load->library('Notifications');
|
||||
|
||||
$customer_title = 'Appointment Changes Saved Successfully!';
|
||||
$customer_message = 'Your appointment details have changed. The new details are '
|
||||
. 'listed below';
|
||||
if (!$manage_mode) {
|
||||
$customer_title = 'Your appointment has been successfully booked!';
|
||||
$customer_message = 'Thank you for arranging an appointment with us. '
|
||||
. 'Below you can see the appointment details. Make changes '
|
||||
. 'by clicking the appointment link.';
|
||||
$customer_link = $this->config->item('base_url') . 'appointments/index/'
|
||||
. $appointment_data['hash'];
|
||||
|
||||
$provider_title = 'Appointment Details Have Changed';
|
||||
$provider_message = 'The new appointment details are listed below:';
|
||||
$provider_link = $this->config->item('base_url') . 'backend/index/'
|
||||
$provider_title = 'A new appointment has been added to your plan.';
|
||||
$provider_message = 'You can make changes by clicking the appointment '
|
||||
. 'link below';
|
||||
$provider_link = $this->config->item('base_url') . 'backend/'
|
||||
. $appointment_data['hash'];
|
||||
} else {
|
||||
$customer_title = 'Appointment changes have been successfully saved!';
|
||||
$customer_message = '';
|
||||
$customer_link = $this->config->item('base_url') . 'appointments/index/'
|
||||
. $appointment_data['hash'];
|
||||
|
||||
$provider_title = 'Appointment details have changed.';
|
||||
$provider_message = '';
|
||||
$provider_link = $this->config->item('base_url') . 'backend/'
|
||||
. $appointment_data['hash'];
|
||||
}
|
||||
|
||||
$this->notifications->send_appointment_details($appointment_data, $provider_data,
|
||||
$service_data, $customer_data, $company_settings, $customer_title,
|
||||
|
@ -178,11 +200,20 @@ class Backend extends CI_Controller {
|
|||
$service_data, $customer_data, $company_settings, $provider_title,
|
||||
$provider_message, $provider_link, $provider_data['email']);
|
||||
|
||||
echo json_encode('SUCCESS');
|
||||
} catch(Exception $exc) {
|
||||
$warnings[] = exceptionToJavascript($exc);
|
||||
}
|
||||
|
||||
if (!isset($warnings)) {
|
||||
echo json_encode('SUCCESS');
|
||||
} else {
|
||||
echo json_encode(array(
|
||||
'warnings' => $warnings
|
||||
));
|
||||
}
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'error' => $exc->getMessage()
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -221,36 +252,50 @@ class Backend extends CI_Controller {
|
|||
'company_link' => $this->Settings_Model->get_setting('company_link')
|
||||
);
|
||||
|
||||
// :: DELETE APPOINTMENT RECORD FROM DATABASE.
|
||||
// :: DELETE APPOINTMENT RECORD FROM DATABASE
|
||||
$this->Appointments_Model->delete($_POST['appointment_id']);
|
||||
|
||||
// :: SYNC DELETE WITH GOOGLE CALENDAR
|
||||
if ($appointment_data['id_google_calendar'] != NULL) {
|
||||
$google_sync = $this->Providers_Model->get_setting('google_sync',
|
||||
$provider_data['id']);
|
||||
try {
|
||||
$google_sync = $this->Providers_Model->get_setting('google_sync', $provider_data['id']);
|
||||
|
||||
if ($google_sync == TRUE) {
|
||||
$google_token = json_decode($this->Providers_Model->get_setting('google_token',
|
||||
$provider_data['id']));
|
||||
|
||||
$google_token = json_decode($this->Providers_Model
|
||||
->get_setting('google_token', $provider_data['id']));
|
||||
$this->load->library('Google_Sync');
|
||||
$this->google_sync->refresh_token($google_token->refresh_token);
|
||||
$this->google_sync->delete_appointment($appointment_data['id_google_calendar']);
|
||||
}
|
||||
} catch(Exception $exc) {
|
||||
$warnings[] = exceptionToJavascript($exc);
|
||||
}
|
||||
}
|
||||
|
||||
// :: SEND NOTIFICATION EMAILS TO PROVIDER AND CUSTOMER.
|
||||
// :: SEND NOTIFICATION EMAILS TO PROVIDER AND CUSTOMER
|
||||
try {
|
||||
$this->load->library('Notifications');
|
||||
$this->notifications->send_delete_appointment($appointment_data, $provider_data,
|
||||
$service_data, $customer_data, $company_settings, $provider_data['email']);
|
||||
$service_data, $customer_data, $company_settings, $provider_data['email'],
|
||||
$_POST['delete_reason']);
|
||||
$this->notifications->send_delete_appointment($appointment_data, $provider_data,
|
||||
$service_data, $customer_data, $company_settings, $customer_data['email']);
|
||||
|
||||
echo json_encode('SUCCESS');
|
||||
$service_data, $customer_data, $company_settings, $customer_data['email'],
|
||||
$_POST['delete_reason']);
|
||||
} catch(Exception $exc) {
|
||||
$warnings[] = exceptionToJavascript($exc);
|
||||
}
|
||||
|
||||
// :: SEND RESPONSE TO CLIENT BROWSER
|
||||
if (!isset($warnings)) {
|
||||
echo json_encode('SUCCESS'); // Everything executed successfully.
|
||||
} else {
|
||||
echo json_encode(array(
|
||||
'warnings' => $warnings // There were warnings during the operation.
|
||||
));
|
||||
}
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'error' => $exc->getMessage()
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -271,17 +316,14 @@ class Backend extends CI_Controller {
|
|||
}
|
||||
|
||||
$this->load->model('Providers_Model');
|
||||
|
||||
$this->Providers_Model->set_setting('google_sync', FALSE,
|
||||
$_POST['provider_id']);
|
||||
$this->Providers_Model->set_setting('google_token', NULL,
|
||||
$_POST['provider_id']);
|
||||
$this->Providers_Model->set_setting('google_sync', FALSE, $_POST['provider_id']);
|
||||
$this->Providers_Model->set_setting('google_token', NULL, $_POST['provider_id']);
|
||||
|
||||
echo json_encode('SUCCESS');
|
||||
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'error' => $exc->getMessage()
|
||||
'exceptions' => array(exceptionToJavascript($exc))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class Notifications {
|
|||
* This email template also needs an email title and an email text in order to complete
|
||||
* the appointment details.
|
||||
*
|
||||
* @expectedException NotificationException Raises when an unexpected error occures.
|
||||
* @expectedException Exception Raises when an unexpected error occures.
|
||||
*
|
||||
* @param array $appointment_data Contains the appointment data.
|
||||
* @param array $provider_data Contains the provider data.
|
||||
|
@ -99,8 +99,8 @@ class Notifications {
|
|||
$mail->Body = $email_html;
|
||||
|
||||
if (!$mail->Send()) {
|
||||
throw new NotificationException('Email could not been sent. '
|
||||
. 'Mailer Error (Line ' . __LINE__ . '): ' . $mail->ErrorInfo);
|
||||
throw new Exception('Email could not been sent. ' . 'Mailer Error (Line '
|
||||
. __LINE__ . '): ' . $mail->ErrorInfo);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -123,9 +123,10 @@ class Notifications {
|
|||
* By now this array must contain the following values: "company_link",
|
||||
* "company_name", "company_email".
|
||||
* @param string $to_address The email address of the email receiver.
|
||||
* @param string $reason The reason why the appointment is deleted.
|
||||
*/
|
||||
public function send_delete_appointment($appointment_data, $provider_data,
|
||||
$service_data, $customer_data, $company_settings, $to_address) {
|
||||
$service_data, $customer_data, $company_settings, $to_address, $reason) {
|
||||
// :: PREPARE EMAIL REPLACE ARRAY
|
||||
$replace_array = array(
|
||||
'$email_title' => 'Appointment Cancelled',
|
||||
|
@ -138,7 +139,8 @@ class Notifications {
|
|||
'$customer_name' => $customer_data['first_name'] . ' ' . $customer_data['last_name'],
|
||||
'$customer_email' => $customer_data['email'],
|
||||
'$customer_phone' => $customer_data['phone_number'],
|
||||
'$customer_address' => $customer_data['address']
|
||||
'$customer_address' => $customer_data['address'],
|
||||
'$reason' => $reason
|
||||
);
|
||||
|
||||
$email_html = file_get_contents(dirname(dirname(__FILE__))
|
||||
|
@ -156,7 +158,7 @@ class Notifications {
|
|||
$mail->Body = $email_html;
|
||||
|
||||
if (!$mail->Send()) {
|
||||
throw new NotificationException('Email could not been sent. '
|
||||
throw new Exception('Email could not been sent. '
|
||||
. 'Mailer Error (Line ' . __LINE__ . '): ' . $mail->ErrorInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -126,9 +126,10 @@
|
|||
Press the "Cancel" button to remove the appointment
|
||||
from the company schedule.
|
||||
</p>
|
||||
<form id="cancel-appointment-form" method="get"
|
||||
<form id="cancel-appointment-form" method="post"
|
||||
action="' . $this->config->item('base_url')
|
||||
. 'appointments/cancel/' . $appointment_data['hash'] . '">
|
||||
<textarea name="cancel_reason" style="display:none;"></textarea>
|
||||
<button id="cancel-appointment" class="btn btn-inverse">
|
||||
Cancel</button>
|
||||
</form>
|
||||
|
|
|
@ -51,9 +51,14 @@
|
|||
<h3>Your appointment has been successfully canceled!</h3>
|
||||
|
||||
<?php
|
||||
// Display exception message (if any).
|
||||
if (isset($error)) {
|
||||
echo $error;
|
||||
// Display exceptions (if any).
|
||||
if (isset($exceptions)) {
|
||||
echo '<div style="margin: 10px">';
|
||||
echo '<h4>Unexpected Errors</h4>';
|
||||
foreach($exceptions as $exception) {
|
||||
echo exceptionToHtml($exception);
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
|
|
@ -57,6 +57,17 @@
|
|||
<img id="message-icon" src="<?php echo $message_icon; ?>" />
|
||||
<h3><?php echo $message_title; ?></h3>
|
||||
<p><?php echo $message_text; ?></p>
|
||||
<?php
|
||||
// Display exceptions (if any).
|
||||
if (isset($exceptions)) {
|
||||
echo '<div style="margin: 10px">';
|
||||
echo '<h4>Unexpected Errors</h4>';
|
||||
foreach($exceptions as $exception) {
|
||||
echo exceptionToHtml($exception);
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,8 +1,8 @@
|
|||
<div id="footer">
|
||||
<div id="footer-content">
|
||||
Powered by <a href="">Easy!Appointments</a> |
|
||||
Powered by <a href="http://easyappointments.org">Easy!Appointments</a> |
|
||||
Copyright © <?php echo date('Y'); ?>
|
||||
<a href="http://www.alextselegidis.com">Alex Tselegidis</a> |
|
||||
<a href="http://alextselegidis.com">Alex Tselegidis</a> |
|
||||
Licensed Under GPLv3
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -35,6 +35,29 @@
|
|||
<td style="padding: 3px;">$appointment_duration</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Customer Details</h2>
|
||||
<table id="customer-details">
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Name</td>
|
||||
<td style="padding: 3px;">$customer_name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Email</td>
|
||||
<td style="padding: 3px;">$customer_email</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Phone</td>
|
||||
<td style="padding: 3px;">$customer_phone</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Address</td>
|
||||
<td style="padding: 3px;">$customer_address</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Reason</h2>
|
||||
<p>$reason</p>
|
||||
</div>
|
||||
|
||||
<div id="footer" style="padding: 10px; text-align: center;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Main javascript code for the backend section of Easy!Appointments.
|
||||
* Main javascript code for the backend of Easy!Appointments.
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
$(window).resize(function() {
|
||||
|
@ -30,13 +30,13 @@ var Backend = {
|
|||
|
||||
if (window.innerHeight > $('body').height()) {
|
||||
footerHandle.css({
|
||||
'position' : 'absolute',
|
||||
'width' : '100%',
|
||||
'bottom' : '0px'
|
||||
'position': 'absolute',
|
||||
'width': '100%',
|
||||
'bottom': '0px'
|
||||
});
|
||||
} else {
|
||||
footerHandle.css({
|
||||
'position' : 'static'
|
||||
'position': 'static'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
*/
|
||||
var BackendCalendar = {
|
||||
// :: NAMESPACE CONSTANTS
|
||||
FILTER_TYPE_PROVIDER : 'provider',
|
||||
FILTER_TYPE_SERVICE : 'service',
|
||||
FILTER_TYPE_PROVIDER: 'provider',
|
||||
FILTER_TYPE_SERVICE: 'service',
|
||||
|
||||
// :: NAMESPACE VALIABLES
|
||||
lastFocusedEventData : undefined, // Contain event data for later use.
|
||||
lastFocusedEventData: undefined, // Contain event data for later use.
|
||||
|
||||
/**
|
||||
* This function makes the necessary initialization for the default backend
|
||||
|
@ -19,38 +19,37 @@ var BackendCalendar = {
|
|||
* @param {bool} defaultEventHandlers (OPTIONAL = TRUE) Determines whether the
|
||||
* default event handlers will be set for the current page.
|
||||
*/
|
||||
initialize : function(defaultEventHandlers) {
|
||||
initialize: function(defaultEventHandlers) {
|
||||
if (defaultEventHandlers === undefined) defaultEventHandlers = true;
|
||||
|
||||
// :: INITIALIZE THE DOM ELEMENTS OF THE PAGE
|
||||
$('#calendar').fullCalendar({
|
||||
defaultView : 'agendaWeek',
|
||||
height : BackendCalendar.getCalendarHeight(),
|
||||
editable : true,
|
||||
slotMinutes : 30,
|
||||
columnFormat : {
|
||||
month : 'ddd',
|
||||
week : 'ddd d/M',
|
||||
day : 'dddd d/M'
|
||||
'defaultView': 'agendaWeek',
|
||||
'height': BackendCalendar.getCalendarHeight(),
|
||||
'editable': true,
|
||||
'slotMinutes': 30,
|
||||
'columnFormat': {
|
||||
'month': 'ddd',
|
||||
'week': 'ddd d/M',
|
||||
'day': 'dddd d/M'
|
||||
},
|
||||
titleFormat : {
|
||||
month : 'MMMM yyyy',
|
||||
week : "MMMM d[ yyyy]{ '—'[ MMM] d, yyyy}",
|
||||
day : 'dddd, MMM d, yyyy'
|
||||
'titleFormat': {
|
||||
'month': 'MMMM yyyy',
|
||||
'week': "MMMM d[ yyyy]{ '—'[ MMM] d, yyyy}",
|
||||
'day': 'dddd, MMM d, yyyy'
|
||||
},
|
||||
header : {
|
||||
left : 'prev,next today',
|
||||
center : 'title',
|
||||
right : 'agendaDay,agendaWeek,month'
|
||||
'header': {
|
||||
'left': 'prev,next today',
|
||||
'center': 'title',
|
||||
'right': 'agendaDay,agendaWeek,month'
|
||||
},
|
||||
|
||||
// Calendar events need to be declared on initialization.
|
||||
windowResize : BackendCalendar.calendarWindowResize,
|
||||
viewDisplay : BackendCalendar.calendarViewDisplay,
|
||||
dayClick : BackendCalendar.calendarDayClick,
|
||||
eventClick : BackendCalendar.calendarEventClick,
|
||||
eventResize : BackendCalendar.calendarEventResize,
|
||||
eventDrop : BackendCalendar.calendarEventDrop
|
||||
'windowResize': BackendCalendar.calendarWindowResize,
|
||||
'viewDisplay': BackendCalendar.calendarViewDisplay,
|
||||
'dayClick': BackendCalendar.calendarDayClick,
|
||||
'eventClick': BackendCalendar.calendarEventClick,
|
||||
'eventResize': BackendCalendar.calendarEventResize,
|
||||
'eventDrop': BackendCalendar.calendarEventDrop
|
||||
});
|
||||
|
||||
// Trigger once to set the proper footer position after calendar
|
||||
|
@ -63,10 +62,11 @@ var BackendCalendar = {
|
|||
var hasGoogleSync = (provider['settings']['google_sync'] === '1')
|
||||
? 'true' : 'false';
|
||||
|
||||
optgroupHtml += '<option value="' + provider['id'] + '" ' +
|
||||
'type="' + BackendCalendar.FILTER_TYPE_PROVIDER + '" ' +
|
||||
'google-sync="' + hasGoogleSync + '">' +
|
||||
provider['first_name'] + ' ' + provider['last_name'] + '</option>';
|
||||
optgroupHtml += '<option value="' + provider['id'] + '" '
|
||||
+ 'type="' + BackendCalendar.FILTER_TYPE_PROVIDER + '" '
|
||||
+ 'google-sync="' + hasGoogleSync + '">'
|
||||
+ provider['first_name'] + ' ' + provider['last_name']
|
||||
+ '</option>';
|
||||
});
|
||||
optgroupHtml += '</optgroup>';
|
||||
$('#select-filter-item').append(optgroupHtml);
|
||||
|
@ -92,7 +92,7 @@ var BackendCalendar = {
|
|||
* page. If you do not need the default handlers then initialize the page
|
||||
* by setting the "defaultEventHandlers" argument to "false".
|
||||
*/
|
||||
bindEventHandlers : function() {
|
||||
bindEventHandlers: function() {
|
||||
/**
|
||||
* Event: Calendar Filter Item "Change"
|
||||
*
|
||||
|
@ -111,11 +111,9 @@ var BackendCalendar = {
|
|||
// disabled.
|
||||
if ($('#select-filter-item option:selected').attr('type')
|
||||
=== BackendCalendar.FILTER_TYPE_SERVICE) {
|
||||
$('#google-sync, #enable-sync, #insert-unavailable-period')
|
||||
.prop('disabled', true);
|
||||
$('#calendar-actions').hide();
|
||||
} else {
|
||||
$('#google-sync, #enable-sync, #insert-unavailable-period')
|
||||
.prop('disabled', false);
|
||||
$('#calendar-actions').show();
|
||||
// If the user has already the sync enabled then apply the proper
|
||||
// style changes.
|
||||
if ($('#select-filter-item option:selected').attr('google-sync')
|
||||
|
@ -161,38 +159,38 @@ var BackendCalendar = {
|
|||
$(this).parents().eq(2).remove(); // Hide the popover
|
||||
|
||||
var appointmentData = BackendCalendar.lastFocusedEventData.data;
|
||||
var dialogHandle = $('#manage-appointment');
|
||||
var dialog = $('#manage-appointment');
|
||||
|
||||
BackendCalendar.resetAppointmentDialog();
|
||||
|
||||
// :: APPLY APPOINTMENT DATA AND SHOW TO MODAL DIALOG
|
||||
dialogHandle.find('.modal-header h3').text('Edit Appointment');
|
||||
dialogHandle.find('#appointment-id').val(appointmentData['id']);
|
||||
dialogHandle.find('#select-service').val(appointmentData['id_services']);
|
||||
dialogHandle.find('#select-provider').val(appointmentData['id_users_provider']);
|
||||
dialog.find('.modal-header h3').text('Edit Appointment');
|
||||
dialog.find('#appointment-id').val(appointmentData['id']);
|
||||
dialog.find('#select-service').val(appointmentData['id_services']);
|
||||
dialog.find('#select-provider').val(appointmentData['id_users_provider']);
|
||||
|
||||
// Set the start and end datetime of the appointment.\
|
||||
var startDatetime = Date.parseExact(appointmentData['start_datetime'],
|
||||
'yyyy-MM-dd HH:mm:ss').toString('dd/MM/yyyy HH:mm');
|
||||
dialogHandle.find('#start-datetime').val(startDatetime);
|
||||
dialog.find('#start-datetime').val(startDatetime);
|
||||
|
||||
var endDatetime = Date.parseExact(appointmentData['end_datetime'],
|
||||
'yyyy-MM-dd HH:mm:ss').toString('dd/MM/yyyy HH:mm');
|
||||
dialogHandle.find('#end-datetime').val(endDatetime);
|
||||
dialog.find('#end-datetime').val(endDatetime);
|
||||
|
||||
var customerData = appointmentData['customer'];
|
||||
dialogHandle.find('#customer-id').val(appointmentData['id_users_customer']);
|
||||
dialogHandle.find('#first-name').val(customerData['first_name']);
|
||||
dialogHandle.find('#last-name').val(customerData['last_name']);
|
||||
dialogHandle.find('#email').val(customerData['email']);
|
||||
dialogHandle.find('#phone-number').val(customerData['phone_number']);
|
||||
dialogHandle.find('#address').val(customerData['address']);
|
||||
dialogHandle.find('#city').val(customerData['city']);
|
||||
dialogHandle.find('#zip-code').val(customerData['zip_code']);
|
||||
dialogHandle.find('#notes').val(appointmentData['notes']);
|
||||
dialog.find('#customer-id').val(appointmentData['id_users_customer']);
|
||||
dialog.find('#first-name').val(customerData['first_name']);
|
||||
dialog.find('#last-name').val(customerData['last_name']);
|
||||
dialog.find('#email').val(customerData['email']);
|
||||
dialog.find('#phone-number').val(customerData['phone_number']);
|
||||
dialog.find('#address').val(customerData['address']);
|
||||
dialog.find('#city').val(customerData['city']);
|
||||
dialog.find('#zip-code').val(customerData['zip_code']);
|
||||
dialog.find('#notes').val(appointmentData['notes']);
|
||||
|
||||
// :: DISPLAY THE MANAGE APPOINTMENTS MODAL DIALOG
|
||||
dialogHandle.modal('show');
|
||||
dialog.modal('show');
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -206,11 +204,12 @@ var BackendCalendar = {
|
|||
$(this).parents().eq(2).remove(); // Hide the popover
|
||||
|
||||
var messageButtons = {
|
||||
'Delete' : function() {
|
||||
'OK': function() {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend/ajax_delete_appointment';
|
||||
|
||||
var postData = {
|
||||
'appointment_id' : BackendCalendar.lastFocusedEventData.data['id']
|
||||
'appointment_id' : BackendCalendar.lastFocusedEventData.data['id'],
|
||||
'delete_reason': $('#delete-reason').val()
|
||||
};
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
|
@ -220,26 +219,35 @@ var BackendCalendar = {
|
|||
|
||||
$('#message_box').dialog('close');
|
||||
|
||||
if (response.error) {
|
||||
GeneralFunctions.displayMessageBox('Delete Appointment Error',
|
||||
'An unexpected error occured during the deletion of the ' +
|
||||
'appointment. Please try again.');
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
|
||||
+ 'the operation could not complete successfully. The following '
|
||||
+ 'issues occured:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.warnings) {
|
||||
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Warnings', 'The operation '
|
||||
+ 'was completed but the following warnings appeared:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||
}
|
||||
|
||||
// Refresh calendar event items.
|
||||
$('#select-filter-item').trigger('change');
|
||||
|
||||
}, 'json');
|
||||
},
|
||||
'Cancel' : function() {
|
||||
'Cancel': function() {
|
||||
$('#message_box').dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
GeneralFunctions.displayMessageBox('Delete Appointment', 'Are you sure '
|
||||
+ 'that you want to delete this appointment? This action cannot '
|
||||
+ 'be undone.', messageButtons);
|
||||
GeneralFunctions.displayMessageBox('Delete Appointment', 'Please take a minute '
|
||||
+ 'to write the reason you are deleting the appointment:', messageButtons);
|
||||
$('#message_box').append('<textarea id="delete-reason"></textarea>');
|
||||
$('#delete-reason').css('width', '320px');
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -275,11 +283,11 @@ var BackendCalendar = {
|
|||
'dd/MM/yyyy HH:mm').toString('yyyy-MM-dd HH:mm:ss');
|
||||
|
||||
var appointmentData = {
|
||||
'id_services' : modalHandle.find('#select-service').val(),
|
||||
'id_users_provider' : modalHandle.find('#select-provider').val(),
|
||||
'start_datetime' : startDatetime,
|
||||
'end_datetime' : endDatetime,
|
||||
'notes' : modalHandle.find('#notes').val()
|
||||
'id_services': modalHandle.find('#select-service').val(),
|
||||
'id_users_provider': modalHandle.find('#select-provider').val(),
|
||||
'start_datetime': startDatetime,
|
||||
'end_datetime': endDatetime,
|
||||
'notes': modalHandle.find('#notes').val()
|
||||
};
|
||||
|
||||
if (modalHandle.find('#appointment-id').val() !== '') {
|
||||
|
@ -287,16 +295,14 @@ var BackendCalendar = {
|
|||
appointmentData['id'] = modalHandle.find('#appointment-id').val();
|
||||
}
|
||||
|
||||
|
||||
|
||||
var customerData = {
|
||||
'first_name' : modalHandle.find('#first-name').val(),
|
||||
'last_name' : modalHandle.find('#last-name').val(),
|
||||
'email' : modalHandle.find('#email').val(),
|
||||
'phone_number' : modalHandle.find('#phone-number').val(),
|
||||
'address' : modalHandle.find('#address').val(),
|
||||
'city' : modalHandle.find('#city').val(),
|
||||
'zip_code' : modalHandle.find('#zip-code').val()
|
||||
'first_name': modalHandle.find('#first-name').val(),
|
||||
'last_name': modalHandle.find('#last-name').val(),
|
||||
'email': modalHandle.find('#email').val(),
|
||||
'phone_number': modalHandle.find('#phone-number').val(),
|
||||
'address': modalHandle.find('#address').val(),
|
||||
'city': modalHandle.find('#city').val(),
|
||||
'zip_code': modalHandle.find('#zip-code').val()
|
||||
};
|
||||
|
||||
if (modalHandle.find('#customer-id').val() !== '') {
|
||||
|
@ -307,12 +313,18 @@ var BackendCalendar = {
|
|||
|
||||
// :: DEFINE SUCCESS EVENT CALLBACK
|
||||
var successCallback = function(response) {
|
||||
if (response.error) {
|
||||
// There was something wrong within the ajax function.
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
|
||||
+ 'the operation could not complete successfully. The following '
|
||||
+ 'issues occured:');
|
||||
$('#messsage_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
|
||||
modalHandle.find('.modal-header').append(
|
||||
'<br><div class="alert alert-error">' +
|
||||
response.error +
|
||||
'Unexpected issues occured!' +
|
||||
'</div>');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -331,9 +343,8 @@ var BackendCalendar = {
|
|||
}, 2000);
|
||||
};
|
||||
|
||||
// :: DEFINE ERROR EVENT CALLBACK
|
||||
// :: DEFINE AJAX ERROR EVENT CALLBACK
|
||||
var errorCallback = function() {
|
||||
// Display error message to the user.
|
||||
modalHandle.find('.modal-header').append(
|
||||
'<br><div class="alert alert-error">' +
|
||||
'A server communication error occured, please try again.' +
|
||||
|
@ -403,20 +414,16 @@ var BackendCalendar = {
|
|||
});
|
||||
|
||||
/**
|
||||
* Event : Insert Appointment Button "Click"
|
||||
* Event: Insert Appointment Button "Click"
|
||||
*
|
||||
* When the user presses this button, the manage appointment dialog opens and lets
|
||||
* the user to create a new appointment.
|
||||
*/
|
||||
$('#insert-appointment').click(function() {
|
||||
var dialogHandle = $('#manage-appointment');
|
||||
BackendCalendar.resetAppointmentDialog();
|
||||
|
||||
// :: PREPARE THE MANAGE APPOINTMENT DIALOG FOR INSERTION
|
||||
dialogHandle.find('.modal-header h3').text('New Appointment');
|
||||
|
||||
// :: DISPLAY THE MANAGE APPOINTMENT MODAL DIALOG
|
||||
dialogHandle.modal('show');
|
||||
var dialog = $('#manage-appointment');
|
||||
dialog.find('.modal-header h3').text('New Appointment');
|
||||
dialog.modal('show');
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -436,7 +443,7 @@ var BackendCalendar = {
|
|||
*
|
||||
* @return {int} Returns the calendar element height in pixels.
|
||||
*/
|
||||
getCalendarHeight : function () {
|
||||
getCalendarHeight: function () {
|
||||
var result = window.innerHeight - $('#footer').height() - $('#header').height()
|
||||
- $('#calendar-toolbar').height() - 80; // 80 for fine tuning
|
||||
return (result > 500) ? result : 500; // Minimum height is 500px
|
||||
|
@ -453,15 +460,15 @@ var BackendCalendar = {
|
|||
* @param {date} startDate Visible start date of the calendar.
|
||||
* @param {type} endDate Visible end date of the calendar.
|
||||
*/
|
||||
refreshCalendarAppointments : function(calendarHandle, recordId, filterType,
|
||||
refreshCalendarAppointments: function(calendarHandle, recordId, filterType,
|
||||
startDate, endDate) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend/ajax_get_calendar_appointments';
|
||||
|
||||
var postData = {
|
||||
record_id : recordId,
|
||||
start_date : startDate.toString('yyyy-MM-dd'),
|
||||
end_date : endDate.toString('yyyy-MM-dd'),
|
||||
filter_type : filterType
|
||||
'record_id': recordId,
|
||||
'start_date': startDate.toString('yyyy-MM-dd'),
|
||||
'end_date': endDate.toString('yyyy-MM-dd'),
|
||||
'filter_type': filterType
|
||||
};
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
|
@ -469,17 +476,28 @@ var BackendCalendar = {
|
|||
//console.log('Refresh Calendar Appointments Response :', response);
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
|
||||
+ 'the operation could not complete successfully. The following '
|
||||
+ 'issues occured:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the appointments to the calendar.
|
||||
var calendarEvents = new Array();
|
||||
|
||||
$.each(response, function(index, appointment){
|
||||
var event = {
|
||||
id : appointment['id'],
|
||||
title : appointment['service']['name'],
|
||||
start : appointment['start_datetime'],
|
||||
end : appointment['end_datetime'],
|
||||
allDay : false,
|
||||
data : appointment // For later use
|
||||
'id': appointment['id'],
|
||||
'title': appointment['service']['name'] + ' - '
|
||||
+ appointment['customer']['first_name'] + ' '
|
||||
+ appointment['customer']['last_name'],
|
||||
'start': appointment['start_datetime'],
|
||||
'end': appointment['end_datetime'],
|
||||
'allDay': false,
|
||||
'data': appointment // Store appointment data for later use.
|
||||
};
|
||||
|
||||
calendarEvents.push(event);
|
||||
|
@ -487,7 +505,6 @@ var BackendCalendar = {
|
|||
|
||||
calendarHandle.fullCalendar('removeEvents');
|
||||
calendarHandle.fullCalendar('addEventSource', calendarEvents);
|
||||
|
||||
}, 'json');
|
||||
},
|
||||
|
||||
|
@ -510,6 +527,7 @@ var BackendCalendar = {
|
|||
var postUrl = GlobalVariables.baseUrl + 'backend/ajax_save_appointment';
|
||||
|
||||
var postData = {};
|
||||
|
||||
postData['appointment_data'] = JSON.stringify(appointmentData);
|
||||
|
||||
if (customerData !== undefined) {
|
||||
|
@ -517,11 +535,11 @@ var BackendCalendar = {
|
|||
}
|
||||
|
||||
$.ajax({
|
||||
type : 'POST',
|
||||
url : postUrl,
|
||||
data : postData,
|
||||
dataType : 'json',
|
||||
success : function(response) {
|
||||
'type': 'POST',
|
||||
'url': postUrl,
|
||||
'data': postData,
|
||||
'dataType': 'json',
|
||||
'success': function(response) {
|
||||
/////////////////////////////////////////////////////////////
|
||||
console.log('Save Appointment Data Response:', response);
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
@ -530,7 +548,7 @@ var BackendCalendar = {
|
|||
successCallback(response);
|
||||
}
|
||||
},
|
||||
error : function(jqXHR, textStatus, errorThrown) {
|
||||
'error': function(jqXHR, textStatus, errorThrown) {
|
||||
//////////////////////////////////////////////////////////////////
|
||||
console.log('Save Appointment Data Error:', jqXHR, textStatus,
|
||||
errorThrown);
|
||||
|
@ -552,7 +570,7 @@ var BackendCalendar = {
|
|||
*
|
||||
* @see updateAppointmentData()
|
||||
*/
|
||||
calendarEventResize : function(event, dayDelta, minuteDelta, revertFunc,
|
||||
calendarEventResize: function(event, dayDelta, minuteDelta, revertFunc,
|
||||
jsEvent, ui, view) {
|
||||
if ($('#notification').is(':visible')) {
|
||||
$('#notification').hide('bind');
|
||||
|
@ -574,12 +592,23 @@ var BackendCalendar = {
|
|||
|
||||
// :: DEFINE THE SUCCESS CALLBACK FUNCTION
|
||||
var successCallback = function(response) {
|
||||
if (response.error) {
|
||||
// Display error message to the user.
|
||||
Backend.displayNotification(response.error);
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
|
||||
+ 'the operation could not complete successfully. The following '
|
||||
+ 'issues occured:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.warnings) {
|
||||
// Display warning information to the user.
|
||||
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||
GeneralFunctions.displayMessageBox('Warnings', 'The operation completed but '
|
||||
+ 'there were some warnings:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||
}
|
||||
|
||||
// Display success notification to user.
|
||||
var undoFunction = function() {
|
||||
appointmentData['end_datetime'] = Date.parseExact(
|
||||
|
@ -587,11 +616,10 @@ var BackendCalendar = {
|
|||
.add({ minutes: -minuteDelta })
|
||||
.toString('yyyy-MM-dd HH:mm:ss');
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl
|
||||
+ 'backend/ajax_save_appointment';
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend/ajax_save_appointment';
|
||||
|
||||
var postData = {
|
||||
'appointment_data' : JSON.stringify(appointmentData)
|
||||
'appointment_data': JSON.stringify(appointmentData)
|
||||
};
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
|
@ -602,8 +630,8 @@ var BackendCalendar = {
|
|||
|
||||
Backend.displayNotification('Appointment updated successfully!', [
|
||||
{
|
||||
'label' : 'Undo',
|
||||
'function' : undoFunction
|
||||
'label': 'Undo',
|
||||
'function': undoFunction
|
||||
}
|
||||
]);
|
||||
$('#footer').css('position', 'static'); // Footer position fix.
|
||||
|
@ -623,7 +651,7 @@ var BackendCalendar = {
|
|||
*
|
||||
* @see getCalendarHeight()
|
||||
*/
|
||||
calendarWindowResize : function(view) {
|
||||
calendarWindowResize: function(view) {
|
||||
$('#calendar').fullCalendar('option', 'height',
|
||||
BackendCalendar.getCalendarHeight());
|
||||
},
|
||||
|
@ -634,7 +662,7 @@ var BackendCalendar = {
|
|||
* When the user clicks on a day square on the calendar, then he will
|
||||
* automatically be transfered to that day view calendar.
|
||||
*/
|
||||
calendarDayClick : function(date, allDay, jsEvent, view) {
|
||||
calendarDayClick: function(date, allDay, jsEvent, view) {
|
||||
if (allDay) {
|
||||
// Switch to day view
|
||||
$('#calendar').fullCalendar('gotoDate', date);
|
||||
|
@ -648,7 +676,9 @@ var BackendCalendar = {
|
|||
* When the user clicks on an appointment object on the calendar, then
|
||||
* a data preview popover is display above the calendar item.
|
||||
*/
|
||||
calendarEventClick : function(event, jsEvent, view) {
|
||||
calendarEventClick: function(event, jsEvent, view) {
|
||||
$('.popover').remove(); // Close all open popovers.
|
||||
|
||||
// Display a popover with the event details.
|
||||
var html =
|
||||
'<style type="text/css">'
|
||||
|
@ -662,7 +692,7 @@ var BackendCalendar = {
|
|||
+ event.end.toString('dd/MM/yyyy HH:mm')
|
||||
+ '<br>' +
|
||||
'<strong>Service</strong> '
|
||||
+ event.title
|
||||
+ event.data['service']['name']
|
||||
+ '<br>' +
|
||||
'<strong>Provider</strong> '
|
||||
+ event.data['provider']['first_name'] + ' '
|
||||
|
@ -679,12 +709,12 @@ var BackendCalendar = {
|
|||
'</center>';
|
||||
|
||||
$(jsEvent.target).popover({
|
||||
placement : 'top',
|
||||
title : event.title,
|
||||
content : html,
|
||||
html : true,
|
||||
container : 'body',
|
||||
trigger : 'manual'
|
||||
'placement': 'top',
|
||||
'title': event.title,
|
||||
'content': html,
|
||||
'html': true,
|
||||
'container': 'body',
|
||||
'trigger': 'manual'
|
||||
});
|
||||
|
||||
BackendCalendar.lastFocusedEventData = event;
|
||||
|
@ -729,13 +759,24 @@ var BackendCalendar = {
|
|||
|
||||
// :: DEFINE THE SUCCESS CALLBACK FUNCTION
|
||||
var successCallback = function(response) {
|
||||
if (response.error) {
|
||||
// Display error message to the user.
|
||||
Backend.displayNotification(reponse.error);
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
|
||||
+ 'the operation could not complete successfully. The following '
|
||||
+ 'issues occured:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
|
||||
// Display success notification to user.
|
||||
if (response.warnings) {
|
||||
// Display warning information to the user.
|
||||
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||
GeneralFunctions.displayMessageBox('Warnings', 'The operation completed but '
|
||||
+ 'there were some warnings:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||
}
|
||||
|
||||
// Define the undo function, if the user needs to reset the last change.
|
||||
var undoFunction = function() {
|
||||
appointmentData['start_datetime'] = Date.parseExact(
|
||||
appointmentData['start_datetime'], 'yyyy-MM-dd HH:mm:ss')
|
||||
|
@ -750,10 +791,10 @@ var BackendCalendar = {
|
|||
event.data['start_datetime'] = appointmentData['start_datetime'];
|
||||
event.data['end_datetime'] = appointmentData['end_datetime'];
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl
|
||||
+ 'backend/ajax_save_appointment';
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend/ajax_save_appointment';
|
||||
|
||||
var postData = {
|
||||
'appointment_data' : JSON.stringify(appointmentData)
|
||||
'appointment_data': JSON.stringify(appointmentData)
|
||||
};
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
|
@ -764,8 +805,8 @@ var BackendCalendar = {
|
|||
|
||||
Backend.displayNotification('Appointment updated successfully!', [
|
||||
{
|
||||
'label' : 'Undo',
|
||||
'function' : undoFunction
|
||||
'label': 'Undo',
|
||||
'function': undoFunction
|
||||
}
|
||||
]);
|
||||
|
||||
|
@ -818,12 +859,14 @@ var BackendCalendar = {
|
|||
//console.log('Disable Provider Sync Response :', response);
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
if (response.error) {
|
||||
GeneralFunctions.displayMessageBox('Disable Sync Error', 'An unexpected ' +
|
||||
'error occured during the disable provider sync operation : ' +
|
||||
response.error);
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
|
||||
+ 'the operation could not complete successfully. The following '
|
||||
+ 'issues occured:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
|
||||
}, 'json');
|
||||
},
|
||||
|
||||
|
@ -833,20 +876,20 @@ var BackendCalendar = {
|
|||
* order to bring the dialog to the desired state.
|
||||
*/
|
||||
resetAppointmentDialog: function() {
|
||||
var dialogHandle = $('#manage-appointment');
|
||||
var dialog = $('#manage-appointment');
|
||||
|
||||
// :: EMPTY FORM FIELDS
|
||||
dialogHandle.find('input, textarea').val('');
|
||||
dialogHandle.find('#modal-message').hide();
|
||||
dialogHandle.find('#select-service, #select-provider').empty();
|
||||
dialog.find('input, textarea').val('');
|
||||
dialog.find('#modal-message').hide();
|
||||
dialog.find('#select-service, #select-provider').empty();
|
||||
|
||||
// :: PREPARE SERVICE AND PROVIDER LISTBOXES
|
||||
$.each(GlobalVariables.availableServices, function(index, service) {
|
||||
var option = new Option(service['name'], service['id']);
|
||||
dialogHandle.find('#select-service').append(option);
|
||||
dialog.find('#select-service').append(option);
|
||||
});
|
||||
dialogHandle.find('#select-service').val(
|
||||
dialogHandle.find('#select-service').eq(0).attr('value'));
|
||||
dialog.find('#select-service').val(
|
||||
dialog.find('#select-service').eq(0).attr('value'));
|
||||
|
||||
// Fill the providers listbox with providers that can serve the appointment's
|
||||
// service and then select the user's provider.
|
||||
|
@ -854,7 +897,7 @@ var BackendCalendar = {
|
|||
var canProvideService = false;
|
||||
|
||||
$.each(provider['services'], function(index, service) {
|
||||
if (service == dialogHandle.find('#select-service').val()) {
|
||||
if (service == dialog.find('#select-service').val()) {
|
||||
canProvideService = true;
|
||||
return;
|
||||
}
|
||||
|
@ -863,7 +906,7 @@ var BackendCalendar = {
|
|||
if (canProvideService) { // Add the provider to the listbox.
|
||||
var option = new Option(provider['first_name']
|
||||
+ ' ' + provider['last_name'], provider['id']);
|
||||
dialogHandle.find('#select-provider').append(option);
|
||||
dialog.find('#select-provider').append(option);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -872,7 +915,7 @@ var BackendCalendar = {
|
|||
// the appointment end datetime.
|
||||
var serviceDuration = 0;
|
||||
$.each(GlobalVariables.availableServices, function(index, service) {
|
||||
if (service['id'] == dialogHandle.find('#select-service').val()) {
|
||||
if (service['id'] == dialog.find('#select-service').val()) {
|
||||
serviceDuration = service['duration'];
|
||||
return;
|
||||
}
|
||||
|
@ -883,17 +926,17 @@ var BackendCalendar = {
|
|||
var endDatetime = new Date().addMinutes(GlobalVariables.bookAdvanceTimeout)
|
||||
.addMinutes(serviceDuration).toString('dd/MM/yyyy HH:mm');
|
||||
|
||||
dialogHandle.find('#start-datetime').datetimepicker({
|
||||
dateFormat : 'dd/mm/yy',
|
||||
minDate : 0
|
||||
dialog.find('#start-datetime').datetimepicker({
|
||||
'dateFormat': 'dd/mm/yy',
|
||||
'minDate': 0
|
||||
});
|
||||
dialogHandle.find('#start-datetime').val(startDatetime);
|
||||
dialog.find('#start-datetime').val(startDatetime);
|
||||
|
||||
dialogHandle.find('#end-datetime').datetimepicker({
|
||||
dateFormat : 'dd/mm/yy',
|
||||
minDate : 0
|
||||
dialog.find('#end-datetime').datetimepicker({
|
||||
'dateFormat': 'dd/mm/yy',
|
||||
'minDate': 0
|
||||
});
|
||||
dialogHandle.find('#end-datetime').val(endDatetime);
|
||||
dialog.find('#end-datetime').val(endDatetime);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -903,16 +946,16 @@ var BackendCalendar = {
|
|||
* @returns {bool} Returns the validation result.
|
||||
*/
|
||||
validateAppointmentForm: function() {
|
||||
var dialogHandle = $('#manage-appointment');
|
||||
var dialog = $('#manage-appointment');
|
||||
|
||||
// Reset previous validation css formating.
|
||||
dialogHandle.find('.control-group').removeClass('error');
|
||||
dialogHandle.find('#modal-message').hide();
|
||||
dialog.find('.control-group').removeClass('error');
|
||||
dialog.find('#modal-message').hide();
|
||||
|
||||
try {
|
||||
// :: CHECK REQUIRED FIELDS
|
||||
var missingRequiredField = false;
|
||||
dialogHandle.find('.required').each(function() {
|
||||
dialog.find('.required').each(function() {
|
||||
if ($(this).val() === '') {
|
||||
$(this).parents().eq(1).addClass('error');
|
||||
missingRequiredField = true;
|
||||
|
@ -923,18 +966,15 @@ var BackendCalendar = {
|
|||
}
|
||||
|
||||
// :: CHECK EMAIL ADDRESS
|
||||
if (!GeneralFunctions.validateEmail(dialogHandle.find('#email').val())) {
|
||||
dialogHandle.find('#email').parents().eq(1).addClass('error');
|
||||
if (!GeneralFunctions.validateEmail(dialog.find('#email').val())) {
|
||||
dialog.find('#email').parents().eq(1).addClass('error');
|
||||
throw 'Invalid email address!';
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch(exc) {
|
||||
dialogHandle.find('#modal-message')
|
||||
.addClass('alert-error')
|
||||
.text(exc)
|
||||
.show('fade');
|
||||
dialog.find('#modal-message').addClass('alert-error').text(exc).show('fade');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,17 +195,25 @@ var FrontendBook = {
|
|||
event.preventDefault();
|
||||
|
||||
var dialogButtons = {
|
||||
'Yes': function() {
|
||||
'OK': function() {
|
||||
if ($('#cancel-reason').val() === '') {
|
||||
$('#cancel-reason').css('border', '2px solid red');
|
||||
return;
|
||||
}
|
||||
$('#cancel-appointment-form textarea').val($('#cancel-reason').val());
|
||||
$('#cancel-appointment-form').submit();
|
||||
},
|
||||
'No': function() {
|
||||
'Cancel': function() {
|
||||
$('#message_box').dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
GeneralFunctions.displayMessageBox('Cancel Appointment', 'Are you sure '
|
||||
+ 'that you want to cancel this appointment? This action can\'t '
|
||||
+ 'be undone.', dialogButtons);
|
||||
GeneralFunctions.displayMessageBox('Cancel Appointment', 'Please take a '
|
||||
+ 'minute to write the reason you are cancelling the appointment:',
|
||||
dialogButtons);
|
||||
|
||||
$('#message_box').append('<textarea id="cancel-reason"></textarea>');
|
||||
$('#cancel-reason').css('width', '300px');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -215,41 +223,43 @@ var FrontendBook = {
|
|||
* Before the form is submitted to the server we need to make sure that
|
||||
* in the meantime the selected appointment date/time wasn't reserved by
|
||||
* another customer or event.
|
||||
*
|
||||
* @task Fix the problem with this event handler. Book does not work anymore.
|
||||
*/
|
||||
$('#book-appointment-form').submit(function() {
|
||||
// event.preventDefault();
|
||||
//
|
||||
// var formData = jQuery.parseJSON($('input[name="post_data"]').val());
|
||||
//
|
||||
// var postData = {
|
||||
// 'id_users_provider' : formData['appointment']['id_users_provider'],
|
||||
// 'id_services' : formData['appointment']['id_services'],
|
||||
// 'start_datetime' : formData['appointment']['start_datetime']
|
||||
// };
|
||||
//
|
||||
// var postUrl = GlobalVariables.baseUrl + 'appointments/ajax_check_datetime_availability';
|
||||
//
|
||||
// $.post(postUrl, postData, function(response) {
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// console.log('Check Date/Time Availability Post Response :', response);
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// if (response.error) {
|
||||
// GeneralFunctions.displayMessageBox('An Unexpected Error Occured',
|
||||
// response.error);
|
||||
// }
|
||||
//
|
||||
// if (response === true) {
|
||||
// $('#book-appointment-form').submit();
|
||||
// } else {
|
||||
// GeneralFunctions.displayMessageBox('Appointment Hour Taken', 'Unfortunately '
|
||||
// + 'the selected appointment hour is not available anymore. Please select '
|
||||
// + 'another hour.');
|
||||
// FrontendBook.getAvailableHours($('#select-date').val());
|
||||
// }
|
||||
// }, 'json');
|
||||
event.preventDefault();
|
||||
|
||||
var formData = jQuery.parseJSON($('input[name="post_data"]').val());
|
||||
|
||||
var postData = {
|
||||
'id_users_provider': formData['appointment']['id_users_provider'],
|
||||
'id_services': formData['appointment']['id_services'],
|
||||
'start_datetime': formData['appointment']['start_datetime']
|
||||
};
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'appointments/ajax_check_datetime_availability';
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
console.log('Check Date/Time Availability Post Response :', response);
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
|
||||
+ 'the check appointment time availability could not be completed. '
|
||||
+ 'The following issues occured:');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response === true) {
|
||||
$('#book-appointment-form').submit();
|
||||
} else {
|
||||
GeneralFunctions.displayMessageBox('Appointment Hour Taken', 'Unfortunately '
|
||||
+ 'the selected appointment hour is not available anymore. Please select '
|
||||
+ 'another hour.');
|
||||
FrontendBook.getAvailableHours($('#select-date').val());
|
||||
}
|
||||
}, 'json');
|
||||
});
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in a new issue