Ολοκλήρωση λειτουργιών για την έκδοση 0.3
This commit is contained in:
parent
36718c87f9
commit
3062dbc001
12 changed files with 333 additions and 308 deletions
|
@ -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);
|
||||
|
||||
--
|
||||
-- Περιορισμοί για άχρηστους πίνακες
|
||||
|
|
|
@ -12,28 +12,42 @@ class Appointments extends CI_Controller {
|
|||
* record.
|
||||
*/
|
||||
public function index($appointment_hash = '') {
|
||||
if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') {
|
||||
$this->load->model('Settings_Model');
|
||||
$this->load->model('Services_Model');
|
||||
$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');
|
||||
|
||||
$company_name = $this->Settings_Model->get_setting('company_name');
|
||||
if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') {
|
||||
$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,62 +72,82 @@ 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.
|
||||
// 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'];
|
||||
|
||||
$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.
|
||||
// :: SEND NOTIFICATION EMAILS TO BOTH CUSTOMER AND PROVIDER
|
||||
$this->load->library('Notifications');
|
||||
try {
|
||||
|
||||
$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);
|
||||
$this->notifications->send_appointment_details(
|
||||
$appointment_data, $provider_data, $service_data, $customer_data,
|
||||
$company_settings, $customer_title, $customer_message, $customer_link,
|
||||
$customer_data['email']);
|
||||
|
||||
} catch (NotificationException $not_exc) {
|
||||
$view_data['notification_error'] = '<br><br>'
|
||||
. '<pre>An unexpected error occured while sending you an '
|
||||
. 'email. Please backup the appointment details so that '
|
||||
. 'you can restore them later. <br><br>Error: <br>'
|
||||
. $not_exc->getMessage() . '</pre>';
|
||||
}
|
||||
$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 the appointment with the providers plan, if the
|
||||
// google sync option is enabled.
|
||||
// :: 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']));
|
||||
$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);
|
||||
|
||||
|
@ -122,23 +156,27 @@ class Appointments extends CI_Controller {
|
|||
$this->google_sync->add_appointment($appointment_data['id']);
|
||||
} else {
|
||||
// Update appointment to Google Calendar.
|
||||
$this->google_sync->update_appointment($appointment_data['id']);
|
||||
$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.
|
||||
$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');
|
||||
|
||||
// :: LOAD THE BOOK SUCCESS VIEW
|
||||
$view_data = array(
|
||||
'appointment_data' => $appointment_data,
|
||||
'service_data' => $service_data,
|
||||
'provider_data' => $provider_data,
|
||||
'company_name' => $company_name
|
||||
'service_data' => $service_data,
|
||||
'company_name' => $company_settings['company_name']
|
||||
);
|
||||
|
||||
} catch(Exception $exc) {
|
||||
$view_data['error'] = array(
|
||||
'message' => $exc->getMessage(),
|
||||
'technical' => $exc->getTraceAsString()
|
||||
);
|
||||
}
|
||||
$this->load->view('appointments/book_success', $view_data);
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -237,7 +274,6 @@ class Appointments extends CI_Controller {
|
|||
'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(
|
||||
$new_space = array(
|
||||
'start' => $space_start,
|
||||
'end' => $appointment_start
|
||||
);
|
||||
$empty_spaces_with_appointments[] = array(
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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 */
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -94,36 +94,23 @@ class Google_Sync {
|
|||
* If yes, the selected appointment record is going to be added to the Google
|
||||
* Calendar account.
|
||||
*
|
||||
* <strong>IMPORTANT!</strong> 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,
|
||||
|
|
|
@ -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']
|
||||
);
|
||||
'$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,
|
||||
|
||||
$email_html = file_get_contents(dirname(dirname(__FILE__)) . '/views/emails/book_success.php');
|
||||
$email_html = $this->replace_template_variables($replace_array, $email_html);
|
||||
'$company_link' => $company_settings['company_link'],
|
||||
'$company_name' => $company_settings['company_name'],
|
||||
|
||||
$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'),
|
||||
'$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
|
||||
|
|
|
@ -192,10 +192,26 @@
|
|||
</button>
|
||||
|
||||
<?php
|
||||
// Display exception message (if any).
|
||||
// @task Special display of exceptions within the app.
|
||||
if (isset($notification_error)) {
|
||||
echo $notification_error;
|
||||
// Display error message (if any).
|
||||
if (isset($error)) {
|
||||
echo '
|
||||
<hr>
|
||||
<h4>An Unexpected Error Occured</h4>
|
||||
<div class="accordion" id="error-accordion">
|
||||
<div class="accordion-group">
|
||||
<div class="accordion-heading">
|
||||
<a class="accordion-toggle" data-toggle="collapse"
|
||||
data-parent="#error-accordion" href="#error-technical">' .
|
||||
$error['message'] . '
|
||||
</a>
|
||||
</div>
|
||||
<div id="error-technical" class="accordion-body collapse">
|
||||
<div class="accordion-inner">
|
||||
<pre>' . $error['technical'] . '</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
|
62
src/application/views/appointments/message.php
Normal file
62
src/application/views/appointments/message.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
|
||||
<?php // INCLUDE JS FILES ?>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.min.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/bootstrap/bootstrap.min.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/date.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/general_functions.js"></script>
|
||||
|
||||
<?php // INCLUDE CSS FILES ?>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="<?php echo $this->config->base_url(); ?>assets/css/libs/bootstrap/bootstrap.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="<?php echo $this->config->base_url(); ?>assets/css/libs/bootstrap/bootstrap-responsive.css">
|
||||
|
||||
<?php // SET FAVICON FOR PAGE ?>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="<?php echo $this->config->base_url(); ?>assets/images/favicon.ico">
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #CAEDF3;
|
||||
}
|
||||
|
||||
#message-frame {
|
||||
width: 630px;
|
||||
margin: 150px auto 0 auto;
|
||||
background: #FFF;
|
||||
border: 1px solid #DDDADA;
|
||||
padding: 70px;
|
||||
}
|
||||
|
||||
#message-icon {
|
||||
float: right;
|
||||
margin-top: 17px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="message-frame" class="frame-container">
|
||||
<img id="message-icon" src="<?php echo $message_icon; ?>" />
|
||||
<h3><?php echo $message_title; ?></h3>
|
||||
<p><?php echo $message_text; ?></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,18 +1,19 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>New Appointment</title>
|
||||
<title>Appointment Details</title>
|
||||
</head>
|
||||
|
||||
<body style="font: 13px arial, helvetica, tahoma;">
|
||||
<div class="email-container" style="width: 650px;border: 1px solid #eee;">
|
||||
<div id="header" style="background-color: #3DD481; border-bottom: 4px solid #1A865F;
|
||||
height: 40px; padding: 10px 15px;">
|
||||
height: 40px;padding: 10px 15px;">
|
||||
<strong id="logo" style="color: white; font-size: 31px;
|
||||
text-shadow: 1px 1px 1px #8F8888;">$company_name</strong>
|
||||
</div>
|
||||
|
||||
<div id="content" style="padding: 10px 15px;">
|
||||
<h2>$email_title</h2>
|
||||
<p>$email_message</p>
|
||||
|
||||
<h2>Appointment Details</h2>
|
||||
<table id="appointment-details">
|
||||
<tr>
|
||||
|
@ -24,17 +25,17 @@
|
|||
<td style="padding: 3px;">$appointment_provider</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Date</td>
|
||||
<td style="padding: 3px;">$appointment_date</td>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Start</td>
|
||||
<td style="padding: 3px;">$appointment_start_date</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Duration</td>
|
||||
<td style="padding: 3px;">$appointment_duration</td>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">End</td>
|
||||
<td style="padding: 3px;">$appointment_end_date</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Customer Details</h2>
|
||||
<table id="appointment-details">
|
||||
<table id="customer-details">
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Name</td>
|
||||
<td style="padding: 3px;">$customer_name</td>
|
||||
|
@ -54,12 +55,11 @@
|
|||
</table>
|
||||
|
||||
<h2>Appointment Link</h2>
|
||||
<p>You can make more actions by pressing the following link.</p>
|
||||
<a href="$appointment_link" style="width: 600px;">$appointment_link</a>
|
||||
</div>
|
||||
|
||||
<div id="footer" style="padding: 10px; text-align: center;
|
||||
border-top: 1px solid #EEE; background: #FAFAFA;">
|
||||
border-top: 1px solid #EEE;background: #FAFAFA;">
|
||||
<a href="$company_link">$company_name</a> | Powered by Easy!Appointments
|
||||
</div>
|
||||
</div>
|
|
@ -1,56 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Appointment Book Success</title>
|
||||
</head>
|
||||
<body style="font: 13px arial, helvetica, tahoma;">
|
||||
<div class="email-container" style="width: 650px;border: 1px solid #eee;">
|
||||
<div id="header" style="background-color: #3DD481; border-bottom: 4px solid #1A865F;
|
||||
height: 40px;padding: 10px 15px;">
|
||||
<strong id="logo" style="color: white; font-size: 31px;
|
||||
text-shadow: 1px 1px 1px #8F8888;">$company_name</strong>
|
||||
</div>
|
||||
|
||||
<div id="content" style="padding: 10px 15px;">
|
||||
<h2>$email_title</h2>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h2>Appointment Details</h2>
|
||||
<table id="appointment-details">
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Service</td>
|
||||
<td style="padding: 3px;">$appointment_service</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Provider</td>
|
||||
<td style="padding: 3px;">$appointment_provider</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Date</td>
|
||||
<td style="padding: 3px;">$appointment_date</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Duration</td>
|
||||
<td style="padding: 3px;">$appointment_duration</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Edit Link</h2>
|
||||
<p>
|
||||
Press the following link to make changes to your appointment reservation.
|
||||
You are able to change the appointment details three hours before
|
||||
the appointment.
|
||||
</p>
|
||||
<a href="$appointment_link" style="width: 600px;">$appointment_link</a>
|
||||
</div>
|
||||
|
||||
<div id="footer" style="padding: 10px; text-align: center;
|
||||
border-top: 1px solid #EEE;background: #FAFAFA;">
|
||||
<a href="$company_link">$company_name</a> | Powered by Easy!Appointments
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue