diff --git a/src/application/controllers/appointments.php b/src/application/controllers/appointments.php index 6689de37..55111d1e 100644 --- a/src/application/controllers/appointments.php +++ b/src/application/controllers/appointments.php @@ -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 @@ -143,28 +143,28 @@ class Appointments extends CI_Controller { $this->load->library('Notifications'); if (!$post_data['manage_mode']) { - $customer_title = 'Your appointment has been successfully booked!'; + $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']; + . '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 = 'A new appointment has been added to your plan.'; + $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']; + . 'link below'; + $provider_link = $this->config->item('base_url') . 'backend/' + . $appointment_data['hash']; } else { - $customer_title = 'Appointment changes have been successfully saved!'; + $customer_title = 'Appointment changes have been successfully saved!'; $customer_message = ''; - $customer_link = $this->config->item('base_url') . 'appointments/index/' - . $appointment_data['hash']; + $customer_link = $this->config->item('base_url') . 'appointments/index/' + . $appointment_data['hash']; - $provider_title = 'Appointment details have changed.'; + $provider_title = 'Appointment details have changed.'; $provider_message = ''; - $provider_link = $this->config->item('base_url') . 'backend/' - . $appointment_data['hash']; + $provider_link = $this->config->item('base_url') . 'backend/' + . $appointment_data['hash']; } $this->notifications->send_appointment_details($appointment_data, $provider_data, @@ -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 { @@ -219,15 +221,15 @@ class Appointments extends CI_Controller { throw new Exception('No record matches the provided hash.'); } - $appointment_data = $records[0]; - $provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']); - $customer_data = $this->Customers_Model->get_row($appointment_data['id_users_customer']); - $service_data = $this->Services_Model->get_row($appointment_data['id_services']); + $appointment_data = $records[0]; + $provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']); + $customer_data = $this->Customers_Model->get_row($appointment_data['id_users_customer']); + $service_data = $this->Services_Model->get_row($appointment_data['id_services']); $company_settings = array( - 'company_name' => $this->Settings_Model->get_setting('company_name'), - 'company_email' => $this->Settings_Model->get_setting('company_email'), - 'company_link' => $this->Settings_Model->get_setting('company_link') + 'company_name' => $this->Settings_Model->get_setting('company_name'), + 'company_email' => $this->Settings_Model->get_setting('company_email'), + 'company_link' => $this->Settings_Model->get_setting('company_link') ); // :: DELETE APPOINTMENT RECORD FROM THE DATABASE. @@ -237,29 +239,41 @@ class Appointments extends CI_Controller { // :: SYNC APPOINTMENT REMOVAL WITH GOOGLE CALENDAR if ($appointment_data['id_google_calendar'] != NULL) { - $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']); + 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 - $this->load->library('Notifications'); - $this->notifications->send_delete_appointment($appointment_data, $provider_data, - $service_data, $customer_data, $company_settings, $provider_data['email']); - $this->notifications->send_delete_appointment($appointment_data, $provider_data, - $service_data, $customer_data, $company_settings, $customer_data['email']); - + try { + $this->load->library('Notifications'); + $this->notifications->send_delete_appointment($appointment_data, $provider_data, + $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'], + $_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); @@ -395,14 +409,14 @@ class Appointments extends CI_Controller { $appt_start = new DateTime($_POST['start_datetime']); $appt_start = $appt_start->format('H:i'); - $appt_end = new DateTime($_POST['start_datetime']); + $appt_end = new DateTime($_POST['start_datetime']); $appt_end->add(new DateInterval('PT' . $service_duration . 'M')); - $appt_end = $appt_end->format('H:i'); + $appt_end = $appt_end->format('H:i'); $period_start = date('H:i', strtotime($period['start'])); - $period_end = date('H:i', strtotime($period['end'])); + $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)) )); } } @@ -528,7 +542,7 @@ class Appointments extends CI_Controller { // don't include the appointment. $new_period = array( 'start' => $period_start, - 'end' => $appointment_start + 'end' => $appointment_start ); if (!in_array($new_period, $available_periods_with_appointments)) { @@ -537,7 +551,7 @@ class Appointments extends CI_Controller { $new_period = array( 'start' => $appointment_end, - 'end' => $period_end + 'end' => $period_end ); if (!in_array($new_period, $available_periods_with_appointments)) { @@ -550,8 +564,8 @@ class Appointments extends CI_Controller { $found = FALSE; foreach ($reserved_appointments as $tmp_appointment) { - $appt_start = date('H:i', strtotime($tmp_appointment['start_datetime'])); - $appt_end = date('H:i', strtotime($tmp_appointment['end_datetime'])); + $appt_start = date('H:i', strtotime($tmp_appointment['start_datetime'])); + $appt_end = date('H:i', strtotime($tmp_appointment['end_datetime'])); if ($period_start < $appt_start && $period_end > $appt_end) { $found = TRUE; @@ -562,7 +576,7 @@ class Appointments extends CI_Controller { // already exist in the "$empty_spaces_with_appointments" array. $empty_period = array( 'start' => $period_start, - 'end' => $period_end + 'end' => $period_end ); $already_exist = in_array($empty_period, $available_periods_with_appointments); diff --git a/src/application/controllers/backend.php b/src/application/controllers/backend.php index 84e2a192..0fbe1d90 100644 --- a/src/application/controllers/backend.php +++ b/src/application/controllers/backend.php @@ -62,30 +62,34 @@ class Backend extends CI_Controller { $this->load->model('Services_Model'); $this->load->model('Customers_Model'); - if ($_POST['filter_type'] == FILTER_TYPE_PROVIDER) { - $where_id = 'id_users_provider'; - } else { - $where_id = 'id_services'; + try { + if ($_POST['filter_type'] == FILTER_TYPE_PROVIDER) { + $where_id = 'id_users_provider'; + } else { + $where_id = 'id_services'; + } + + $where_clause = array( + $where_id => $_POST['record_id'], + 'start_datetime >=' => $_POST['start_date'], + 'end_datetime <=' => $_POST['end_date'] + ); + + $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']); + } + + echo json_encode($appointments); + + } catch(Exception $exc) { + echo json_encode(array( + 'exceptions' => array(exceptionToJavascript($exc)) + )); } - - $where_clause = array( - $where_id => $_POST['record_id'], - 'start_datetime >=' => $_POST['start_date'], - 'end_datetime <=' => $_POST['end_date'] - ); - - $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']); - } - - echo json_encode($appointments); } /** @@ -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'])) { @@ -125,64 +129,91 @@ class Backend extends CI_Controller { } $appointment_data = $this->Appointments_Model->get_row($appointment_data['id']); - $provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']); - $customer_data = $this->Customers_Model->get_row($appointment_data['id_users_customer']); - $service_data = $this->Services_Model->get_row($appointment_data['id_services']); + $provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']); + $customer_data = $this->Customers_Model->get_row($appointment_data['id_users_customer']); + $service_data = $this->Services_Model->get_row($appointment_data['id_services']); $company_settings = array( - 'company_name' => $this->Settings_Model->get_setting('company_name'), - 'company_link' => $this->Settings_Model->get_setting('company_link'), - 'company_email' => $this->Settings_Model->get_setting('company_email') + 'company_name' => $this->Settings_Model->get_setting('company_name'), + 'company_link' => $this->Settings_Model->get_setting('company_link'), + 'company_email' => $this->Settings_Model->get_setting('company_email') ); // :: 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'])); + if ($google_sync == TRUE) { + $google_token = json_decode($this->Providers_Model->get_setting('google_token', + $appointment_data['id_users_provider'])); - $this->load->library('Google_Sync'); + $this->load->library('Google_Sync'); + $this->google_sync->refresh_token($google_token->refresh_token); - $this->google_sync->refresh_token($google_token->refresh_token); - - if ($appointment_data['id_google_calendar'] == NULL) { - $this->google_sync->add_appointment($appointment_data, $provider_data, - $service_data, $customer_data, $company_settings); - } else { - $this->google_sync->update_appointment($appointment_data, $provider_data, - $service_data, $customer_data, $company_settings); + if ($appointment_data['id_google_calendar'] == NULL) { + $this->google_sync->add_appointment($appointment_data, $provider_data, + $service_data, $customer_data, $company_settings); + } else { + $this->google_sync->update_appointment($appointment_data, $provider_data, + $service_data, $customer_data, $company_settings); + } } + } catch(Exception $exc) { + $warnings[] = exceptionToJavascript($exc); } // :: SEND EMAIL NOTIFICATIONS TO PROVIDER AND CUSTOMER - $this->load->library('Notifications'); + try { + $this->load->library('Notifications'); + + 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 = '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']; + } - $customer_title = 'Appointment Changes Saved Successfully!'; - $customer_message = 'Your appointment details have changed. The new details are ' - . 'listed below'; - $customer_link = $this->config->item('base_url') . 'appointments/index/' - . $appointment_data['hash']; + $this->notifications->send_appointment_details($appointment_data, $provider_data, + $service_data, $customer_data, $company_settings, $customer_title, + $customer_message, $customer_link, $customer_data['email']); + + $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(Exception $exc) { + $warnings[] = exceptionToJavascript($exc); + } - $provider_title = 'Appointment Details Have Changed'; - $provider_message = 'The new appointment details are listed below:'; - $provider_link = $this->config->item('base_url') . 'backend/index/' - . $appointment_data['hash']; - - $this->notifications->send_appointment_details($appointment_data, $provider_data, - $service_data, $customer_data, $company_settings, $customer_title, - $customer_message, $customer_link, $customer_data['email']); - - $this->notifications->send_appointment_details($appointment_data, $provider_data, - $service_data, $customer_data, $company_settings, $provider_title, - $provider_message, $provider_link, $provider_data['email']); - - echo json_encode('SUCCESS'); - + 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)) )); } } @@ -197,7 +228,7 @@ class Backend extends CI_Controller { * * @param int $_POST['appointment_id'] The appointment id to be deleted. */ - public function ajax_delete_appointment() { + public function ajax_delete_appointment() { try { if (!isset($_POST['appointment_id'])) { throw new Exception('No appointment id provided.'); @@ -209,48 +240,62 @@ class Backend extends CI_Controller { $this->load->model('Customers_Model'); $this->load->model('Services_Model'); $this->load->model('Settings_Model'); - + $appointment_data = $this->Appointments_Model->get_row($_POST['appointment_id']); - $provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']); - $customer_data = $this->Customers_Model->get_row($appointment_data['id_users_customer']); - $service_data = $this->Services_Model->get_row($appointment_data['id_services']); - + $provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']); + $customer_data = $this->Customers_Model->get_row($appointment_data['id_users_customer']); + $service_data = $this->Services_Model->get_row($appointment_data['id_services']); + $company_settings = array( - 'company_name' => $this->Settings_Model->get_setting('company_name'), - 'company_email' => $this->Settings_Model->get_setting('company_email'), - 'company_link' => $this->Settings_Model->get_setting('company_link') + 'company_name' => $this->Settings_Model->get_setting('company_name'), + 'company_email' => $this->Settings_Model->get_setting('company_email'), + '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'])); - - $this->load->library('Google_Sync'); - $this->google_sync->refresh_token($google_token->refresh_token); - $this->google_sync->delete_appointment($appointment_data['id_google_calendar']); + 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) { + $warnings[] = exceptionToJavascript($exc); } } - // :: SEND NOTIFICATION EMAILS TO PROVIDER AND CUSTOMER. - $this->load->library('Notifications'); - $this->notifications->send_delete_appointment($appointment_data, $provider_data, - $service_data, $customer_data, $company_settings, $provider_data['email']); - $this->notifications->send_delete_appointment($appointment_data, $provider_data, - $service_data, $customer_data, $company_settings, $customer_data['email']); - - echo json_encode('SUCCESS'); + // :: 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'], + $_POST['delete_reason']); + $this->notifications->send_delete_appointment($appointment_data, $provider_data, + $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)) )); } } diff --git a/src/application/libraries/notifications.php b/src/application/libraries/notifications.php index 004c83e6..57b3291a 100644 --- a/src/application/libraries/notifications.php +++ b/src/application/libraries/notifications.php @@ -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); } diff --git a/src/application/views/appointments/book.php b/src/application/views/appointments/book.php index 02fd266b..317b2d14 100644 --- a/src/application/views/appointments/book.php +++ b/src/application/views/appointments/book.php @@ -126,9 +126,10 @@ Press the "Cancel" button to remove the appointment from the company schedule.
- diff --git a/src/application/views/appointments/cancel.php b/src/application/views/appointments/cancel.php index 75f2324a..3a013c23 100644 --- a/src/application/views/appointments/cancel.php +++ b/src/application/views/appointments/cancel.php @@ -51,9 +51,14 @@