diff --git a/db/easy_appointments.sql b/db/easy_appointments.sql
index 5dd8ad07..2383909d 100644
--- a/db/easy_appointments.sql
+++ b/db/easy_appointments.sql
@@ -3,7 +3,7 @@
-- http://www.phpmyadmin.net
--
-- Φιλοξενητής: localhost
--- Χρόνος δημιουργίας: 19 Ιουν 2013 στις 22:27:32
+-- Χρόνος δημιουργίας: 26 Ιουν 2013 στις 12:29:46
-- Έκδοση διακομιστή: 5.5.24-log
-- Έκδοση PHP: 5.4.3
@@ -41,7 +41,7 @@ CREATE TABLE IF NOT EXISTS `ea_appointments` (
KEY `id_users_customer` (`id_users_customer`),
KEY `id_services` (`id_services`),
KEY `id_users_provider` (`id_users_provider`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=88 ;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=25 ;
-- --------------------------------------------------------
@@ -184,17 +184,17 @@ CREATE TABLE IF NOT EXISTS `ea_users` (
`id_roles` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `id_roles` (`id_roles`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=154 ;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
--
-- Άδειασμα δεδομένων του πίνακα `ea_users`
--
INSERT INTO `ea_users` (`id`, `first_name`, `last_name`, `email`, `mobile_number`, `phone_number`, `address`, `city`, `state`, `zip_code`, `notes`, `id_roles`) VALUES
-(1, '', '1', 'alextselegidis@gmail.com', '123456789', '1', '', '', NULL, '', 'This is me making Easy!Appointments', 1),
-(2, 'Γεώργιος', 'Παπαδόπουλος', 'alextselegidis@gmail.com', '1212121212', '1', '', '', NULL, '', 'This is a test provider', 2),
-(3, 'Νίκος', 'Αναστασίου', 'prov2@test.gr', '1313133113131', '32132165146', 'Some Street 3', NULL, NULL, NULL, NULL, 2),
-(4, 'Ηρώ', 'Καριοφύλη', 'prov3@test.gr', '239203490', '029340923', 'John Doe 3 ', NULL, NULL, NULL, NULL, 2);
+(1, 'Alex', 'Tselegidis', 'alextselegidis@gmail.com', '123456789', '123456789', 'Some Str', 'Some City', 'Some State', '12345', 'This is me making Easy!Appointments :P', 1),
+(2, 'Γεώργιος', 'Παπαδόπουλος', 'alextselegidis@gmail.com', '1111111111111', '1111111111111', '', '', NULL, '', 'This is a test provider (with my email for google syncing).', 2),
+(3, 'Νίκος', 'Αναστασίου', 'prov2@test.gr', '2222222222222', '2222222222222', 'Some Street 3', NULL, NULL, NULL, NULL, 2),
+(4, 'Ηρώ', 'Καριοφύλη', 'prov3@test.gr', '3333333333333', '3333333333333', 'John Doe 3 ', NULL, NULL, NULL, NULL, 2);
-- --------------------------------------------------------
@@ -218,9 +218,9 @@ CREATE TABLE IF NOT EXISTS `ea_user_settings` (
--
INSERT INTO `ea_user_settings` (`id_users`, `username`, `password`, `working_plan`, `notifications`, `google_sync`, `google_token`) VALUES
-(2, 'provider_1', 'provider_1', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', NULL, 1, '{"access_token":"ya29.AHES6ZRsDBInIFSW1vdMEUt9N_teDoKPk6IVLS-mM41J7P0","token_type":"Bearer","expires_in":3600,"refresh_token":"1\\/9KusWyDci21Fv-PpgeZr3Yik56WnNQ7LDTcmeUhNTN8","created":1371639646}'),
+(2, 'provider_1', 'provider_1', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', NULL, 1, NULL),
(3, 'provider_2', 'provider_2', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', NULL, 0, NULL),
-(4, 'provider_3', 'provider_3', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', NULL, 1, '{"access_token":"ya29.AHES6ZQLXwNinpRgyZ30VP4aNy2MctNkj3fc6oJid8-Gc-TEifJ6WA","token_type":"Bearer","expires_in":3600,"refresh_token":"1\\/bBPokd195S2UX2so9-jclC3E3gpzxgyDjGhJkJxmkHU","created":1371639504}');
+(4, 'provider_3', 'provider_3', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', NULL, 1, NULL);
--
-- Περιορισμοί για άχρηστους πίνακες
diff --git a/src/application/controllers/appointments.php b/src/application/controllers/appointments.php
index 25a1df9d..f177ae2a 100644
--- a/src/application/controllers/appointments.php
+++ b/src/application/controllers/appointments.php
@@ -12,28 +12,42 @@ class Appointments extends CI_Controller {
* record.
*/
public function index($appointment_hash = '') {
+ $this->load->model('Appointments_Model');
+ $this->load->model('Providers_Model');
+ $this->load->model('Services_Model');
+ $this->load->model('Customers_Model');
+ $this->load->model('Settings_Model');
+
if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') {
- $this->load->model('Settings_Model');
- $this->load->model('Services_Model');
- $this->load->model('Providers_Model');
-
- $company_name = $this->Settings_Model->get_setting('company_name');
$available_services = $this->Services_Model->get_available_services();
$available_providers = $this->Providers_Model->get_available_providers();
+ $company_name = $this->Settings_Model->get_setting('company_name');
// If an appointment hash is provided then it means that the customer
// is trying to edit a registered record.
if ($appointment_hash !== ''){
// Load the appointments data and set the manage mode of the page.
- $this->load->model('Appointments_Model');
- $this->load->model('Customers_Model');
-
$manage_mode = TRUE;
$results = $this->Appointments_Model
->get_batch(array('hash' => $appointment_hash));
- $appointment_data = $results[0]; // Php 5.3 does not support treating a function as an array.
+ if (count($results) === 0) {
+ // The requested appointment doesn't exist in the database. Display
+ // a message to the customer.
+ $view_data = array(
+ 'message_title' => 'Appointment Not Found!',
+ 'message_text' => 'The appointment you requested does not exist in the '
+ . 'database anymore.',
+ 'message_icon' => $this->config->item('base_url') . 'assets/images/error.png'
+ );
+
+ $this->load->view('appointments/message', $view_data);
+ return;
+ }
+
+ // Php 5.3 does not support treating a function result as an array.
+ $appointment_data = $results[0];
$provider_data = $this->Providers_Model
->get_row($appointment_data['id_users_provider']);
@@ -58,87 +72,111 @@ class Appointments extends CI_Controller {
'provider_data' => $provider_data,
'customer_data' => $customer_data
);
+
$this->load->view('appointments/book', $view_data);
+
} else {
- // The page is a post-back. Register the appointment and send
- // notification emails to the provider and the customer that are
- // related to the appointment.
- $post_data = json_decode($_POST['post_data'], true);
- $appointment_data = $post_data['appointment'];
- $customer_data = $post_data['customer'];
-
- $this->load->model('Customers_Model');
- $this->load->model('Appointments_Model');
- $this->load->model('Services_Model');
- $this->load->model('Providers_Model');
- $this->load->model('Settings_Model');
-
- $customer_id = $this->Customers_Model->add($customer_data);
- $appointment_data['id_users_customer'] = $customer_id;
- $appointment_data['id'] = $this->Appointments_Model->add($appointment_data);
- $appointment_data['hash'] = $this->Appointments_Model
- ->get_value('hash', $appointment_data['id']);
-
- // Send an email to the customer with the appointment info.
- $this->load->library('Notifications');
+ // The page is a post-back. Register the appointment and send notification emails
+ // to the provider and the customer that are related to the appointment. If google
+ // sync is enabled then add the appointment to the provider's account.
try {
+ $post_data = json_decode($_POST['post_data'], true);
+ $appointment_data = $post_data['appointment'];
+ $customer_data = $post_data['customer'];
+
+ $customer_id = $this->Customers_Model->add($customer_data);
+ $appointment_data['id_users_customer'] = $customer_id;
+
+ $appointment_data['id'] = $this->Appointments_Model->add($appointment_data);
+ $appointment_data['hash'] = $this->Appointments_Model
+ ->get_value('hash', $appointment_data['id']);
+
+ // :: SEND NOTIFICATION EMAILS TO BOTH CUSTOMER AND PROVIDER
+ $this->load->library('Notifications');
+
+ $provider_data = $this->Providers_Model
+ ->get_row($appointment_data['id_users_provider']);
+ $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')
+ );
+
if (!$post_data['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 Saved Successfully!';
- $provider_title = 'Appointment Details Have Changed';
+ $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_book_success(
- $customer_data, $appointment_data, $customer_title);
- $this->notifications->send_new_appointment(
- $customer_data, $appointment_data, $provider_title);
-
- } catch (NotificationException $not_exc) {
- $view_data['notification_error'] = '
'
- . '
An unexpected error occured while sending you an '
- . 'email. Please backup the appointment details so that '
- . 'you can restore them later.
Error: '
- . $not_exc->getMessage() . '
';
+
+ $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']);
+
+ // :: SYNCHRONIZE APPOINTMENT WITH PROVIDER'S GOOGLE CALENDAR
+ // The provider must have previously granted access to his google calendar account
+ // in order to sync the appointment.
+ $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']));
+
+ $this->load->library('google_sync');
+ $this->google_sync->refresh_token($google_token->refresh_token);
+
+ if ($post_data['manage_mode'] === FALSE) {
+ // Add appointment to Google Calendar.
+ $this->google_sync->add_appointment($appointment_data['id']);
+ } else {
+ // Update appointment to Google Calendar.
+ $appointment_data['id_google_calendar'] = $this->Appointments_Model
+ ->get_value('id_google_calendar', $appointment_data['id']);
+ $this->google_sync->update_appointment($appointment_data, $provider_data,
+ $service_data, $customer_data, $company_settings);
+ }
+ }
+
+ // :: LOAD THE BOOK SUCCESS VIEW
+ $view_data = array(
+ 'appointment_data' => $appointment_data,
+ 'provider_data' => $provider_data,
+ 'service_data' => $service_data,
+ 'company_name' => $company_settings['company_name']
+ );
+
+ } catch(Exception $exc) {
+ $view_data['error'] = array(
+ 'message' => $exc->getMessage(),
+ 'technical' => $exc->getTraceAsString()
+ );
}
-
- // Synchronize the appointment with the providers plan, if the
- // google sync option is enabled.
- $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']));
-
- // Authenticate the token. If it isn't valid, the sync operation cannot
- // be completed.
- $this->load->library('google_sync');
- $this->google_sync->refresh_token($google_token->refresh_token);
-
- if ($post_data['manage_mode'] === FALSE) {
- // Add appointment to Google Calendar.
- $this->google_sync->add_appointment($appointment_data['id']);
- } else {
- // Update appointment to Google Calendar.
- $this->google_sync->update_appointment($appointment_data['id']);
- }
-
- }
-
- // Load the book success view.
- $service_data = $this->Services_Model->get_row($appointment_data['id_services']);
- $provider_data = $this->Providers_Model->get_row($appointment_data['id_users_provider']);
- $company_name = $this->Settings_Model->get_setting('company_name');
-
- $view_data = array(
- 'appointment_data' => $appointment_data,
- 'service_data' => $service_data,
- 'provider_data' => $provider_data,
- 'company_name' => $company_name
- );
-
$this->load->view('appointments/book_success', $view_data);
}
}
@@ -169,13 +207,13 @@ class Appointments extends CI_Controller {
}
$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')
+ $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')
);
// :: DELETE APPOINTMENT RECORD FROM THE DATABASE.
@@ -200,9 +238,9 @@ class Appointments extends CI_Controller {
// :: SEND NOTIFICATION EMAILS TO CUSTOMER AND PROVIDER
$this->load->library('Notifications');
- $this->notifications->send_remove_appointment($appointment_data, $provider_data,
+ $this->notifications->send_delete_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings, $provider_data['email']);
- $this->notifications->send_remove_appointment($appointment_data, $provider_data,
+ $this->notifications->send_delete_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings, $customer_data['email']);
} catch(Exception $exc) {
@@ -216,12 +254,11 @@ class Appointments extends CI_Controller {
/**
* [AJAX] Get the available appointment hours for the given date.
*
- * This method answers to an AJAX request. It calculates the
- * available hours for the given service, provider and date.
+ * This method answers to an AJAX request. It calculates the available hours for the
+ * given service, provider and date.
*
- * @param array $_POST['post_data'] An associative array that
- * contains the user selected 'service_id', 'provider_id',
- * 'selected_date' and 'service_duration' in minutes.
+ * @param array $_POST['post_data'] An associative array that contains the user selected
+ * 'service_id', 'provider_id', 'selected_date' and 'service_duration' in minutes.
* @return Returns a json object with the available hours.
*/
public function ajax_get_available_hours() {
@@ -236,8 +273,7 @@ class Appointments extends CI_Controller {
$where_clause = array(
'DATE(start_datetime)' => date('Y-m-d', strtotime($_POST['selected_date'])),
'id_users_provider' => $_POST['provider_id']
- );
-
+ );
$reserved_appointments = $this->Appointments_Model->get_batch($where_clause);
if ($_POST['manage_mode'] === 'true') {
@@ -283,7 +319,7 @@ class Appointments extends CI_Controller {
'end' => $sel_date_working_plan['end']
);
}
- // PROBLEM
+
// Break the empty spaces with the reserved appointments.
$empty_spaces_with_appointments = array();
if (count($reserved_appointments) > 0) {
@@ -295,22 +331,49 @@ class Appointments extends CI_Controller {
$space_end = date('H:i', strtotime($space['end']));
if ($space_start < $appointment_start && $space_end > $appointment_end) {
+ // We need to check whether another appointment fits in the current
+ // space. If this happens, then we need to consider the whole appointment
+ // time as one, because the provider will not be available.
+ foreach ($reserved_appointments as $appt) {
+ $appt_start = date('H:i', strtotime($appt['start_datetime']));
+ $appt_end = date('H:i', strtotime($appt['end_datetime']));
+
+ if ($space_start < $appt_start && $space_end > $appt_end) {
+ if ($appointment_start > $appt_start) {
+ $appointment_start = $appt_start;
+ }
+
+ if ($appointment_end < $appt_end) {
+ $appointment_end = $appt_end;
+ }
+ }
+ }
+
// Current appointment is within the current empty space. So
// we need to break the empty space into two other spaces that
// don't include the appointment.
- $empty_spaces_with_appointments[] = array(
- 'start' => $space_start,
- 'end' => $appointment_start
- );
- $empty_spaces_with_appointments[] = array(
- 'start' => $appointment_end,
- 'end' => $space_end
- );
+ $new_space = array(
+ 'start' => $space_start,
+ 'end' => $appointment_start
+ );
+
+ if (!in_array($new_space, $empty_spaces_with_appointments)) {
+ $empty_spaces_with_appointments[] = $new_space;
+ }
+
+ $new_space = array(
+ 'start' => $appointment_end,
+ 'end' => $space_end
+ );
+ if (!in_array($new_space, $empty_spaces_with_appointments)) {
+ $empty_spaces_with_appointments[] = $new_space;
+ }
+
} else {
// Check if there are any other appointments between this
// time space. If not, it is going to be added as it is.
$found = FALSE;
- foreach($reserved_appointments as $appt) {
+ foreach ($reserved_appointments as $appt) {
$appt_start = date('H:i', strtotime($appt['start_datetime']));
$appt_end = date('H:i', strtotime($appt['end_datetime']));
if ($space_start < $appt_start && $space_end > $appt_end) {
diff --git a/src/application/controllers/backend.php b/src/application/controllers/backend.php
index 63c0b940..0d1fac70 100644
--- a/src/application/controllers/backend.php
+++ b/src/application/controllers/backend.php
@@ -95,10 +95,6 @@ class Backend extends CI_Controller {
* appointment data.
* @param array $_POST['customer_data'] (OPTIONAL) Array with the customer
* data.
- *
- * @task Send email notifications to both provider and customer that changes
- * have been made to the appointment.
- * @task Sync changes with google calendar.
*/
public function ajax_save_appointment_changes() {
try {
@@ -215,9 +211,9 @@ class Backend extends CI_Controller {
// :: SEND NOTIFICATION EMAILS TO PROVIDER AND CUSTOMER.
$this->load->library('Notifications');
- $this->notifications->send_remove_appointment($appointment_data, $provider_data,
+ $this->notifications->send_delete_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings, $provider_data['email']);
- $this->notifications->send_remove_appointment($appointment_data, $provider_data,
+ $this->notifications->send_delete_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings, $customer_data['email']);
echo json_encode('SUCCESS');
diff --git a/src/application/helpers/custom_exceptions_helper.php b/src/application/helpers/custom_exceptions_helper.php
index d0de816d..c1a01c25 100644
--- a/src/application/helpers/custom_exceptions_helper.php
+++ b/src/application/helpers/custom_exceptions_helper.php
@@ -15,5 +15,10 @@ class ValidationException extends Exception {}
*/
class NotificationException extends Exception {}
+/**
+ * Sync Exception Class
+ */
+class SyncException extends Exception {}
+
/* End of file exception_types_helper.php */
/* Location: ./application/helpers/exception_types_helper.php */
\ No newline at end of file
diff --git a/src/application/libraries/Unit_tests/Unit_tests.php b/src/application/libraries/Unit_tests/Unit_tests.php
index 67342736..7f5870d9 100644
--- a/src/application/libraries/Unit_tests/Unit_tests.php
+++ b/src/application/libraries/Unit_tests/Unit_tests.php
@@ -69,7 +69,6 @@ class Unit_tests extends CI_Driver_Library {
*/
public function run_library_tests($output_report = true) {
// @task Implement unit tests for the libraries.
-
if ($output_report) {
$this->CI->output->append_output($this->CI->unit->report());
}
diff --git a/src/application/libraries/google_sync.php b/src/application/libraries/google_sync.php
index 68d75140..d1413337 100644
--- a/src/application/libraries/google_sync.php
+++ b/src/application/libraries/google_sync.php
@@ -94,36 +94,23 @@ class Google_Sync {
* If yes, the selected appointment record is going to be added to the Google
* Calendar account.
*
- * IMPORTANT! If the access token is not valid anymore the
- * appointment cannot be added to the Google Calendar. A notification warning
- * must be sent to the provider in order to authorize the E!A again, and store
- * the new access token to the database.
- *
- * @param int $appointment_id The record id of the appointment that is going to
- * be added to the database.
+ * @param array $appointment_data Contains the appointment record data.
+ * @param array $provider_data Contains the provider record data.
+ * @param array $service_data Contains the service record data.
+ * @param array $customer_data Contains the customer recod data.
+ * @parma array $company_settings Contains some company settings that are used
+ * by this method. By the time the following values must be in the array:
+ * 'company_name'.
* @return Google_Event Returns the Google_Event class object.
- *
- * @task This library should not use the models. The data must be provided from
- * the controllers (same for notification library).
*/
- public function add_appointment($appointment_id) {
- $this->CI->load->model('Appointments_Model');
- $this->CI->load->model('Providers_Model');
- $this->CI->load->model('Services_Model');
- $this->CI->load->model('Customers_Model');
- $this->CI->load->model('Settings_Model');
-
- $appointment_data = $this->CI->Appointments_Model->get_row($appointment_id);
- $provider_data = $this->CI->Providers_Model->get_row($appointment_data['id_users_provider']);
- $customer_data = $this->CI->Customers_Model->get_row($appointment_data['id_users_customer']);
- $service_data = $this->CI->Services_Model->get_row($appointment_data['id_services']);
- $company_name = $this->CI->Settings_Model->get_setting('company_name');
+ public function add_appointment($appointment_data, $provider_data, $service_data,
+ $customer_data, $company_settings) {
$this->CI->load->helper('general');
$event = new Google_Event();
$event->setSummary($service_data['name']);
- $event->setLocation($company_name);
+ $event->setLocation($company_settings['company_name']);
$start = new Google_EventDateTime();
$start->setDateTime(date3339(strtotime($appointment_data['start_datetime'])));
@@ -152,7 +139,7 @@ class Google_Sync {
$created_event = $this->service->events->insert('primary', $event);
// Set the Google Calendar event id to the E!A database record.
- $appointment_data['id_google_calendar'] = $created_event['id'];
+ $appointment_data['id_google_calendar'] = $created_event->id;
$this->CI->Appointments_Model->add($appointment_data);
return $created_event;
@@ -171,7 +158,6 @@ class Google_Sync {
* @parma array $company_settings Contains some company settings that are used
* by this method. By the time the following values must be in the array:
* 'company_name'.
- *
* @return Google_Event Returns the Google_Event class object.
*/
public function update_appointment($appointment_data, $provider_data,
diff --git a/src/application/libraries/notifications.php b/src/application/libraries/notifications.php
index 2b91f460..72160cca 100644
--- a/src/application/libraries/notifications.php
+++ b/src/application/libraries/notifications.php
@@ -41,94 +41,43 @@ class Notifications {
}
/**
- * Send a success email to the customer that booked
- * a new appointment.
+ * Send an email with the appointment details.
*
- * @expectedException NotificationException Raises when an unexpected
- * error has occured when the email is send.
+ * This email template also needs an email title and an email text in order to complete
+ * the appointment details.
*
- * @param array $customer_data Associative array with the customer's
- * data. Each key has the same name as the corresponding field in db.
- * @param array $appointment_data Associative array with the appointment's
- * data. Each key has the same name as the corresponding field in db.
- * @param string $email_title The email title is going to inform the customer
- * for the action that was taken.
+ * @expectedException NotificationException Raises when an unexpected error occures.
+ *
+ * @param array $appointment_data Contains the appointment data.
+ * @param array $provider_data Contains the provider data.
+ * @param array $service_data Contains the service data.
+ * @param array $company_settings Contains settings of the company. By the time the
+ * "company_name", "company_link" and "company_email" values are required in the array.
+ * @param string $title The email title may vary depending the receiver.
+ * @param string $message The email message may vary depending the receiver.
+ * @param string $appointment_link This link is going to enable the receiver to make changes
+ * to the appointment record.
+ * @param string $receiver_address The receiver email address.
* @return bool Returns the operation result.
*/
- public function send_book_success($customer_data, $appointment_data, $email_title) {
- $this->CI->load->model('Providers_Model');
- $this->CI->load->model('Services_Model');
- $this->CI->load->model('Settings_Model');
-
- $provider_data = $this->CI->Providers_Model
- ->get_row($appointment_data['id_users_provider']);
- $service_data = $this->CI->Services_Model
- ->get_row($appointment_data['id_services']);
+ public function send_appointment_details($appointment_data, $provider_data, $service_data,
+ $customer_data, $company_settings, $title, $message, $appointment_link,
+ $receiver_address) {
+ // :: PREPARE THE EMAIL TEMPLATE REPLACE ARRAY
$replace_array = array(
- '$email_title' => $email_title,
+ '$email_title' => $title,
+ '$email_message' => $message,
+
'$appointment_service' => $service_data['name'],
'$appointment_provider' => $provider_data['first_name'] . ' ' . $provider_data['last_name'],
- '$appointment_date' => date('d/m/Y H:i', strtotime($appointment_data['start_datetime'])),
- '$appointment_duration' => $service_data['duration'] . ' minutes',
- '$appointment_link' => $this->CI->config->item('base_url') . 'appointments/index/' . $appointment_data['hash'],
- '$company_link' => $this->CI->Settings_Model->get_setting('company_link'),
- '$company_name' => $this->CI->Settings_Model->get_setting('company_name'),
- '$customer_name' => $customer_data['first_name'] . ' ' . $customer_data['last_name']
- );
-
- $email_html = file_get_contents(dirname(dirname(__FILE__)) . '/views/emails/book_success.php');
- $email_html = $this->replace_template_variables($replace_array, $email_html);
-
- $mail = new PHPMailer();
- $mail->From = $this->CI->Settings_Model->get_setting('company_email');
- $mail->FromName = $this->CI->Settings_Model->get_setting('company_name');
- $mail->AddAddress($customer_data['email']); // Do not use the name argument, phpmailer crushes.
- $mail->IsHTML(true);
- $mail->CharSet = 'UTF-8';
- $mail->Subject = $email_title;
- $mail->Body = $email_html;
-
- if(!$mail->Send()) {
- throw new NotificationException('Email could not been sent. '
- . 'Mailer Error (' . __LINE__ . '): ' . $mail->ErrorInfo);
- }
-
- return TRUE;
- }
-
- /**
- * Send an email notification to a provider that
- * a new appointment has been added to his plan.
- *
- * @expectedException NotificationException Raises when an unexpected
- * error has occured when the email is send.
- *
- * @param array $customer_data Associative array with the customer's
- * data. Each key has the same name as the corresponding field in db.
- * @param array $appointment_data Associative array with the appointment's
- * data. Each key has the same name as the corresponding field in db.
- * @param string $email_title The email title is going to inform the provider
- * for the action that was taken.
- * @return bool Returns the operation result.
- */
- public function send_new_appointment($customer_data, $appointment_data, $email_title) {
- $this->CI->load->model('Providers_Model');
- $this->CI->load->model('Services_Model');
- $this->CI->load->model('Settings_Model');
-
- $provider_data = $this->CI->Providers_Model->get_row($appointment_data['id_users_provider']);
- $service_data = $this->CI->Services_Model->get_row($appointment_data['id_services']);
-
- $replace_array = array(
- '$email_title' => $email_title,
- '$appointment_service' => $service_data['name'],
- '$appointment_provider' => $provider_data['first_name'] . ' ' . $provider_data['last_name'],
- '$appointment_date' => date('d/m/Y H:i', strtotime($appointment_data['start_datetime'])),
- '$appointment_duration' => $service_data['duration'] . ' minutes',
- '$appointment_link' => $this->CI->config->item('base_url') . 'appointments/admin/' . $appointment_data['hash'],
- '$company_link' => $this->CI->Settings_Model->get_setting('company_link'),
- '$company_name' => $this->CI->Settings_Model->get_setting('company_name'),
+ '$appointment_start_date' => date('d/m/Y H:i', strtotime($appointment_data['start_datetime'])),
+ '$appointment_end_date' => date('d/m/Y H:i', strtotime($appointment_data['end_datetime'])),
+ '$appointment_link' => $appointment_link,
+
+ '$company_link' => $company_settings['company_link'],
+ '$company_name' => $company_settings['company_name'],
+
'$customer_name' => $customer_data['first_name'] . ' ' . $customer_data['last_name'],
'$customer_email' => $customer_data['email'],
'$customer_phone' => $customer_data['phone_number'],
@@ -136,16 +85,17 @@ class Notifications {
);
$email_html = file_get_contents(dirname(dirname(__FILE__))
- . '/views/emails/new_appointment.php');
+ . '/views/emails/appointment_details.php');
$email_html = $this->replace_template_variables($replace_array, $email_html);
+ // :: INSTANTIATE EMAIL OBJECT AND SEND EMAIL
$mail = new PHPMailer();
- $mail->From = $this->CI->Settings_Model->get_setting('company_email');
- $mail->FromName = $this->CI->Settings_Model->get_setting('company_name');
- $mail->AddAddress($provider_data['email']); // "Name" argument crushes the phpmailer class.
+ $mail->From = $company_settings['company_email'];
+ $mail->FromName = $company_settings['company_name'];
+ $mail->AddAddress($receiver_address); // "Name" argument crushes the phpmailer class.
$mail->IsHTML(true);
$mail->CharSet = 'UTF-8';
- $mail->Subject = $email_title;
+ $mail->Subject = $title;
$mail->Body = $email_html;
if (!$mail->Send()) {
@@ -174,7 +124,7 @@ class Notifications {
* "company_name", "company_email".
* @param string $to_address The email address of the email receiver.
*/
- public function send_remove_appointment($appointment_data, $provider_data,
+ public function send_delete_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings, $to_address) {
// :: PREPARE EMAIL REPLACE ARRAY
$replace_array = array(
@@ -184,11 +134,15 @@ class Notifications {
'$appointment_date' => date('d/m/Y H:i', strtotime($appointment_data['start_datetime'])),
'$appointment_duration' => $service_data['duration'] . ' minutes',
'$company_link' => $company_settings['company_link'],
- '$company_name' => $company_settings['company_name']
+ '$company_name' => $company_settings['company_name'],
+ '$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']
);
$email_html = file_get_contents(dirname(dirname(__FILE__))
- . '/views/emails/remove_appointment.php');
+ . '/views/emails/delete_appointment.php');
$email_html = $this->replace_template_variables($replace_array, $email_html);
// :: SETUP EMAIL OBJECT AND SEND NOTIFICATION
diff --git a/src/application/views/appointments/book_success.php b/src/application/views/appointments/book_success.php
index 4c7c6fee..b5d92bca 100644
--- a/src/application/views/appointments/book_success.php
+++ b/src/application/views/appointments/book_success.php
@@ -190,12 +190,28 @@
Add to Google Calendar
-
+
+
+
+
\ No newline at end of file
diff --git a/src/application/views/emails/new_appointment.php b/src/application/views/emails/appointment_details.php
similarity index 81%
rename from src/application/views/emails/new_appointment.php
rename to src/application/views/emails/appointment_details.php
index 5df07bf5..dc6e3f06 100644
--- a/src/application/views/emails/new_appointment.php
+++ b/src/application/views/emails/appointment_details.php
@@ -1,18 +1,19 @@
- New Appointment
+ Appointment Details
-
- Thank you $customer_name for arranging an appointment with us.
- Below you can see the appointment details. Click on the edit
- link to make changes to your appointment.
-
-
-
Appointment Details
-
-
-
Service
-
$appointment_service
-
-
-
Provider
-
$appointment_provider
-
-
-
Date
-
$appointment_date
-
-
-
Duration
-
$appointment_duration
-
-
-
-
Edit Link
-
- Press the following link to make changes to your appointment reservation.
- You are able to change the appointment details three hours before
- the appointment.
-
-
-
\ No newline at end of file
diff --git a/src/application/views/emails/remove_appointment.php b/src/application/views/emails/delete_appointment.php
similarity index 100%
rename from src/application/views/emails/remove_appointment.php
rename to src/application/views/emails/delete_appointment.php