* Insert custom unavailable time period on a provider's calendar.

* Fixed and refactored existing code.
* Updated database structure (appointment foreign keys need to be null, when the record is a unavailable time period).
This commit is contained in:
alextselegidis@gmail.com 2013-07-09 14:46:48 +00:00
parent 3bda1dc159
commit f5250e5581
10 changed files with 521 additions and 223 deletions

View file

@ -3,7 +3,7 @@
-- http://www.phpmyadmin.net
--
-- Φιλοξενητής: localhost
-- Χρόνος δημιουργίας: 26 Ιουν 2013 στις 12:29:46
-- Χρόνος δημιουργίας: 09 Ιουλ 2013 στις 15:16:49
-- Έκδοση διακομιστή: 5.5.24-log
-- Έκδοση PHP: 5.4.3
@ -33,9 +33,10 @@ CREATE TABLE IF NOT EXISTS `ea_appointments` (
`end_datetime` datetime DEFAULT NULL,
`notes` text,
`hash` text,
`id_users_provider` bigint(20) unsigned NOT NULL,
`id_users_customer` bigint(20) unsigned NOT NULL,
`id_services` bigint(20) unsigned NOT NULL,
`is_unavailable` tinyint(4) DEFAULT '0',
`id_users_provider` bigint(20) unsigned DEFAULT NULL,
`id_users_customer` bigint(20) unsigned DEFAULT NULL,
`id_services` bigint(20) unsigned DEFAULT NULL,
`id_google_calendar` text,
PRIMARY KEY (`id`),
KEY `id_users_customer` (`id_users_customer`),
@ -43,6 +44,22 @@ CREATE TABLE IF NOT EXISTS `ea_appointments` (
KEY `id_users_provider` (`id_users_provider`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=25 ;
--
-- Άδειασμα δεδομένων του πίνακα `ea_appointments`
--
INSERT INTO `ea_appointments` (`id`, `book_datetime`, `start_datetime`, `end_datetime`, `notes`, `hash`, `is_unavailable`, `id_users_provider`, `id_users_customer`, `id_services`, `id_google_calendar`) VALUES
(2, '2013-06-28 13:41:37', '2013-06-28 10:00:00', '2013-06-28 15:50:00', '', 'df05e96357b1f7eb9717524d40400b92', 0, 2, 5, 1, NULL),
(3, '2013-06-28 17:03:04', '2013-06-29 09:00:00', '2013-06-29 12:50:00', '', '0493a6fef5215cd83b9eca4de63cb9e9', 0, 2, 5, 1, 'vhd5nlv9pt32caanvtu8c9c8r0'),
(7, '2013-06-29 00:48:15', '2013-06-29 12:15:00', '2013-06-29 12:35:00', '', '5774937851046f65b87617eb14c6ee97', 0, 2, 5, 1, NULL),
(15, '2013-07-03 13:34:54', '2013-07-03 15:15:00', '2013-07-03 15:35:00', '', '98c777b9ee21be6091e15c4af35f6752', 0, 2, 5, 1, 'ibcgjhj1fu484s1c4bquroqtm0'),
(16, '2013-07-03 13:45:12', '2013-07-03 15:45:00', '2013-07-03 16:05:00', '', 'b828b3bb5dbc4e50f05b05cb239bfcd4', 0, 2, 5, 1, 'c48fcvqak1pulu78is971cmutg'),
(17, '2013-07-03 13:45:46', '2013-07-03 16:15:00', '2013-07-03 16:35:00', '', '1edb1f698d8c3606d8ac3c3371604782', 0, 2, 5, 1, 'cgqaavskrvp8048hvba8i9qa28'),
(18, '2013-07-03 13:46:08', '2013-07-03 16:45:00', '2013-07-03 17:05:00', '', 'a4dacd561468e89a74267dc148690a74', 0, 2, 5, 1, 'rrtfqiok2c7i7vbuuh4hjtcp4c'),
(20, '2013-07-03 17:51:49', '2013-07-04 09:00:00', '2013-07-04 09:20:00', '', '9e9814cf15a156d8d795d1e363463c65', 0, 2, 5, 1, 'i3v1unm6miuu1ran9idbivl130'),
(23, '2013-07-03 18:35:25', '2013-07-04 13:00:00', '2013-07-04 13:20:00', '', '64d9143d6004a03d2887d4f9909fd59e', 0, 2, 5, 1, 'fquo0ibainofdpbs26j8ae3r0c'),
(24, '2013-07-05 14:00:38', '2013-07-05 10:00:00', '2013-07-05 10:20:00', '', '13db3ecb2fe7b3e8a9131a21183db62c', 0, 2, 5, 1, 'jno45dehlqh8qufilgvnvj1dl0');
-- --------------------------------------------------------
--
@ -194,7 +211,8 @@ INSERT INTO `ea_users` (`id`, `first_name`, `last_name`, `email`, `mobile_number
(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);
(4, 'Ηρώ', 'Καριοφύλη', 'prov3@test.gr', '3333333333333', '3333333333333', 'John Doe 3 ', NULL, NULL, NULL, NULL, 2),
(5, '', 'a', 'alextselegidis@yahoo.gr', NULL, 'a', '', '', NULL, '', NULL, 3);
-- --------------------------------------------------------
@ -218,9 +236,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, NULL),
(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.AHES6ZRq0T7vB1k0nueWwvYM8gQw7QapJm8_EyHaRwljzXo","token_type":"Bearer","expires_in":3600,"refresh_token":"1\\/o4GiIEXKTxm3HkWHAPGplqW2CcmGLQm7CV3iv19DrTw","created":1372844816}'),
(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, 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, 0, NULL);
--
-- Περιορισμοί για άχρηστους πίνακες

View file

@ -47,20 +47,20 @@ class Appointments extends CI_Controller {
return;
}
$appointment_data = $appointments_results[0];
$appointment = $appointments_results[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']);
$provider = $this->providers_model
->get_row($appointment['id_users_provider']);
$customer = $this->customers_model
->get_row($appointment['id_users_customer']);
} else {
// The customer is going to book a new appointment so there is no
// need for the manage functionality to be initialized.
$manage_mode = FALSE;
$appointment_data = array();
$provider_data = array();
$customer_data = array();
$appointment = array();
$provider = array();
$customer = array();
}
// Load the book appointment view.
@ -69,9 +69,9 @@ class Appointments extends CI_Controller {
'available_providers' => $available_providers,
'company_name' => $company_name,
'manage_mode' => $manage_mode,
'appointment_data' => $appointment_data,
'provider_data' => $provider_data,
'customer_data' => $customer_data
'appointment_data' => $appointment,
'provider_data' => $provider,
'customer_data' => $customer
);
} catch(Exception $exc) {
@ -86,20 +86,18 @@ class Appointments extends CI_Controller {
// 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'];
$post_data = json_decode($_POST['post_data'], true);
$appointment = $post_data['appointment'];
$customer = $post_data['customer'];
$customer_id = $this->customers_model->add($customer_data);
$appointment_data['id_users_customer'] = $customer_id;
$customer_id = $this->customers_model->add($customer);
$appointment['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']);
$appointment['id'] = $this->appointments_model->add($appointment);
$appointment['hash'] = $this->appointments_model->get_value('hash', $appointment['id']);
$provider_data = $this->providers_model
->get_row($appointment_data['id_users_provider']);
$service_data = $this->services_model->get_row($appointment_data['id_services']);
$provider = $this->providers_model->get_row($appointment['id_users_provider']);
$service = $this->services_model->get_row($appointment['id_services']);
$company_settings = array(
'company_name' => $this->settings_model->get_setting('company_name'),
@ -112,26 +110,28 @@ class Appointments extends CI_Controller {
// in order to sync the appointment.
try {
$google_sync = $this->providers_model->get_setting('google_sync',
$appointment_data['id_users_provider']);
$appointment['id_users_provider']);
if ($google_sync == TRUE) {
$google_token = json_decode($this->providers_model
->get_setting('google_token', $appointment_data['id_users_provider']));
->get_setting('google_token', $appointment['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, $provider_data,
$service_data, $customer_data, $company_settings);
$google_event = $this->google_sync->add_appointment($appointment, $provider,
$service, $customer, $company_settings);
$appointment['id_google_calendar'] = $google_event->id;
$this->appointments_model->add($appointment);
} else {
// Update appointment to Google Calendar.
$appointment_data['id_google_calendar'] = $this->appointments_model
->get_value('id_google_calendar', $appointment_data['id']);
$appointment['id_google_calendar'] = $this->appointments_model
->get_value('id_google_calendar', $appointment['id']);
$this->google_sync->update_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings);
$this->google_sync->update_appointment($appointment, $provider,
$service, $customer, $company_settings);
}
}
} catch(Exception $exc) {
@ -148,41 +148,41 @@ class Appointments extends CI_Controller {
. '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'];
. $appointment['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'];
. $appointment['hash'];
} else {
$customer_title = 'Appointment changes have been successfully saved!';
$customer_message = '';
$customer_link = $this->config->item('base_url') . 'appointments/index/'
. $appointment_data['hash'];
. $appointment['hash'];
$provider_title = 'Appointment details have changed.';
$provider_message = '';
$provider_link = $this->config->item('base_url') . 'backend/'
. $appointment_data['hash'];
. $appointment['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, $provider,
$service, $customer,$company_settings, $customer_title,
$customer_message, $customer_link, $customer['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']);
$this->notifications->send_appointment_details($appointment, $provider,
$service, $customer, $company_settings, $provider_title,
$provider_message, $provider_link, $provider['email']);
} catch(Exception $exc) {
$view_data['exceptions'][] = $exc;
}
// :: LOAD THE BOOK SUCCESS VIEW
$view_data = array(
'appointment_data' => $appointment_data,
'provider_data' => $provider_data,
'service_data' => $service_data,
'appointment_data' => $appointment,
'provider_data' => $provider,
'service_data' => $service,
'company_name' => $company_settings['company_name']
);
@ -221,10 +221,10 @@ 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 = $records[0];
$provider = $this->providers_model->get_row($appointment['id_users_provider']);
$customer = $this->customers_model->get_row($appointment['id_users_customer']);
$service = $this->services_model->get_row($appointment['id_services']);
$company_settings = array(
'company_name' => $this->settings_model->get_setting('company_name'),
@ -233,22 +233,22 @@ class Appointments extends CI_Controller {
);
// :: DELETE APPOINTMENT RECORD FROM THE DATABASE.
if (!$this->appointments_model->delete($appointment_data['id'])) {
if (!$this->appointments_model->delete($appointment['id'])) {
throw new Exception('Appointment could not be deleted from the database.');
}
// :: SYNC APPOINTMENT REMOVAL WITH GOOGLE CALENDAR
if ($appointment_data['id_google_calendar'] != NULL) {
if ($appointment['id_google_calendar'] != NULL) {
try {
$google_sync = $this->providers_model->get_setting('google_sync',
$appointment_data['id_users_provider']);
$appointment['id_users_provider']);
if ($google_sync == TRUE) {
$google_token = json_decode($this->providers_model
->get_setting('google_token', $provider_data['id']));
->get_setting('google_token', $provider['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']);
$this->google_sync->delete_appointment($appointment['id_google_calendar']);
}
} catch(Exception $exc) {
$exceptions[] = $exc;
@ -258,11 +258,11 @@ class Appointments extends CI_Controller {
// :: SEND NOTIFICATION EMAILS TO CUSTOMER AND PROVIDER
try {
$this->load->library('Notifications');
$this->notifications->send_delete_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings, $provider_data['email'],
$this->notifications->send_delete_appointment($appointment, $provider,
$service, $customer, $company_settings, $provider['email'],
$_POST['cancel_reason']);
$this->notifications->send_delete_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings, $customer_data['email'],
$this->notifications->send_delete_appointment($appointment, $provider,
$service, $customer, $company_settings, $customer['email'],
$_POST['cancel_reason']);
} catch(Exception $exc) {
$exceptions[] = $exc;

View file

@ -38,9 +38,11 @@ class Backend_api extends CI_Controller {
$appointments = $this->appointments_model->get_batch($where_clause);
foreach($appointments as &$appointment) {
$appointment['provider'] = $this->providers_model->get_row($appointment['id_users_provider']);
$appointment['service'] = $this->services_model->get_row($appointment['id_services']);
$appointment['customer'] = $this->customers_model->get_row($appointment['id_users_customer']);
if ($appointment['is_unavailable'] == FALSE) {
$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);
@ -71,27 +73,27 @@ class Backend_api extends CI_Controller {
// :: SAVE CUSTOMER CHANGES TO DATABASE
if (isset($_POST['customer_data'])) {
$customer_data = json_decode(stripcslashes($_POST['customer_data']), true);
$customer_data['id'] = $this->customers_model->add($customer_data);
$customer = json_decode(stripcslashes($_POST['customer_data']), true);
$customer['id'] = $this->customers_model->add($customer);
}
// :: 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']);
$appointment = json_decode(stripcslashes($_POST['appointment_data']), true);
$manage_mode = isset($appointment['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'])) {
$appointment_data['id_users_customer'] = $customer_data['id'];
if (!isset($appointment['id_users_customer'])) {
$appointment['id_users_customer'] = $customer['id'];
}
$appointment_data['id'] = $this->appointments_model->add($appointment_data);
$appointment['id'] = $this->appointments_model->add($appointment);
}
$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']);
$appointment = $this->appointments_model->get_row($appointment['id']);
$provider = $this->providers_model->get_row($appointment['id_users_provider']);
$customer = $this->customers_model->get_row($appointment['id_users_customer']);
$service = $this->services_model->get_row($appointment['id_services']);
$company_settings = array(
'company_name' => $this->settings_model->get_setting('company_name'),
@ -102,21 +104,23 @@ class Backend_api extends CI_Controller {
// :: SYNC APPOINTMENT CHANGES WITH GOOGLE CALENDAR
try {
$google_sync = $this->providers_model->get_setting('google_sync',
$appointment_data['id_users_provider']);
$appointment['id_users_provider']);
if ($google_sync == TRUE) {
$google_token = json_decode($this->providers_model->get_setting('google_token',
$appointment_data['id_users_provider']));
$appointment['id_users_provider']));
$this->load->library('Google_Sync');
$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);
if ($appointment['id_google_calendar'] == NULL) {
$google_event = $this->google_sync->add_appointment($appointment, $provider,
$service, $customer, $company_settings);
$appointment['id_google_calendar'] = $google_event->id;
$this->appointments_model->add($appointment); // Store google calendar id.
} else {
$this->google_sync->update_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings);
$this->google_sync->update_appointment($appointment, $provider,
$service, $customer, $company_settings);
}
}
} catch(Exception $exc) {
@ -133,32 +137,32 @@ class Backend_api extends CI_Controller {
. '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'];
. $appointment['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'];
. $appointment['hash'];
} else {
$customer_title = 'Appointment changes have been successfully saved!';
$customer_message = '';
$customer_link = $this->config->item('base_url') . 'appointments/index/'
. $appointment_data['hash'];
. $appointment['hash'];
$provider_title = 'Appointment details have changed.';
$provider_message = '';
$provider_link = $this->config->item('base_url') . 'backend/'
. $appointment_data['hash'];
. $appointment['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, $provider,
$service, $customer, $company_settings, $customer_title,
$customer_message, $customer_link, $customer['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']);
$this->notifications->send_appointment_details($appointment, $provider,
$service, $customer, $company_settings, $provider_title,
$provider_message, $provider_link, $provider['email']);
} catch(Exception $exc) {
$warnings[] = exceptionToJavascript($exc);
@ -298,7 +302,7 @@ class Backend_api extends CI_Controller {
try {
$this->load->model('customers_model');
$key = $_POST['key']; //$this->db->escape($_POST['key']);
$key = $_POST['key']; // @task $this->db->escape($_POST['key']);
$where_clause =
'first_name LIKE "%' . $key . '%" OR ' .
@ -316,6 +320,76 @@ class Backend_api extends CI_Controller {
));
}
}
/**
* [AJAX] Insert of update unavailable time period to database.
*
* @param array $_POST['unavailable'] JSON encoded array that contains the unavailable
* period data.
*/
public function ajax_save_unavailable() {
try {
$this->load->model('appointments_model');
$this->load->model('providers_model');
// Add appointment
$unavailable = json_decode($_POST['unavailable'], true);
$this->appointments_model->add_unavailable($unavailable);
// Google Sync
try {
$google_sync = $this->providers_model->get_setting('google_sync',
$unavailable['id_users_provider']);
if ($google_sync) {
$google_token = json_decode($this->providers_model->get_setting('google_token',
$unavailable['id_users_provider']));
$this->load->library('google_sync');
$this->google_sync->refresh_token($google_token->refresh_token);
// @task Sync with gcal.
$google_event = $this->google_sync->add_unavailable($unavailable);
$unavailable['id_google_calendar'] = $google_event->id;
$this->appointments_model->add_unavailable($unavailable);
}
} catch(Exception $exc) {
$warnings[] = $exc;
}
if (isset($warnings)) {
echo json_encode(array(
'warnings' => $warnings
));
} else {
echo json_encode('SUCCESS');
}
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array($exc)
));
}
}
/**
* [AJAX] Delete an unavailable time period from database.
*
* @param numeric $_POST['unavailable_id'] Record id to be deleted.
*/
public function ajax_delete_unavailable() {
try {
// Delete unavailable
// Google Sync
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array($exc)
));
}
}
}
/* End of file backend_api.php */

View file

@ -94,41 +94,40 @@ class Google_Sync {
* If yes, the selected appointment record is going to be added to the Google
* Calendar account.
*
* @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.
* @param array $appointment Contains the appointment record data.
* @param array $provider Contains the provider record data.
* @param array $service Contains the service record data.
* @param array $customer 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.
*/
public function add_appointment($appointment_data, $provider_data, $service_data,
$customer_data, $company_settings) {
public function add_appointment($appointment, $provider, $service, $customer, $company_settings) {
$this->CI->load->helper('general');
$event = new Google_Event();
$event->setSummary($service_data['name']);
$event->setSummary($service['name']);
$event->setLocation($company_settings['company_name']);
$start = new Google_EventDateTime();
$start->setDateTime(date3339(strtotime($appointment_data['start_datetime'])));
$start->setDateTime(date3339(strtotime($appointment['start_datetime'])));
$event->setStart($start);
$end = new Google_EventDateTime();
$end->setDateTime(date3339(strtotime($appointment_data['end_datetime'])));
$end->setDateTime(date3339(strtotime($appointment['end_datetime'])));
$event->setEnd($end);
$eventProvider = new Google_EventAttendee();
$eventProvider->setDisplayName($provider_data['first_name'] . ' '
. $provider_data['last_name']);
$eventProvider->setEmail($provider_data['email']);
$eventProvider->setDisplayName($provider['first_name'] . ' '
. $provider['last_name']);
$eventProvider->setEmail($provider['email']);
$eventCustomer = new Google_EventAttendee();
$eventCustomer->setDisplayName($customer_data['first_name'] . ' '
. $customer_data['last_name']);
$eventCustomer->setEmail($customer_data['email']);
$eventCustomer->setDisplayName($customer['first_name'] . ' '
. $customer['last_name']);
$eventCustomer->setEmail($customer['email']);
$event->attendees = array(
$eventProvider,
@ -138,10 +137,6 @@ class Google_Sync {
// Add the new event to the "primary" calendar.
$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;
$this->CI->appointments_model->add($appointment_data);
return $created_event;
}
@ -151,43 +146,42 @@ class Google_Sync {
* This method updates the google calendar event item that is connected with the
* provided appointment record of Easy!Appointments.
*
* @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.
* @param array $appointment Contains the appointment record data.
* @param array $provider Contains the provider record data.
* @param array $service Contains the service record data.
* @param array $customer 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.
*/
public function update_appointment($appointment_data, $provider_data,
$service_data, $customer_data, $company_settings) {
public function update_appointment($appointment, $provider, $service, $customer, $company_settings) {
$this->CI->load->helper('general');
$event = $this->service->events->get('primary', $appointment_data['id_google_calendar']);
$event = $this->service->events->get('primary', $appointment['id_google_calendar']);
// Convert event to object
$event->setSummary($service_data['name']);
$event->setSummary($service['name']);
$event->setLocation($company_settings['company_name']);
$start = new Google_EventDateTime();
$start->setDateTime(date3339(strtotime($appointment_data['start_datetime'])));
$start->setDateTime(date3339(strtotime($appointment['start_datetime'])));
$event->setStart($start);
$end = new Google_EventDateTime();
$end->setDateTime(date3339(strtotime($appointment_data['end_datetime'])));
$end->setDateTime(date3339(strtotime($appointment['end_datetime'])));
$event->setEnd($end);
$event_provider = new Google_EventAttendee();
$event_provider->setDisplayName($provider_data['first_name'] . ' '
. $provider_data['last_name']);
$event_provider->setEmail($provider_data['email']);
$event_provider->setDisplayName($provider['first_name'] . ' '
. $provider['last_name']);
$event_provider->setEmail($provider['email']);
$event_customer = new Google_EventAttendee();
$event_customer->setDisplayName($customer_data['first_name'] . ' '
. $customer_data['last_name']);
$event_customer->setEmail($customer_data['email']);
$event_customer->setDisplayName($customer['first_name'] . ' '
. $customer['last_name']);
$event_customer->setEmail($customer['email']);
$event->attendees = array(
$event_provider,
@ -208,6 +202,10 @@ class Google_Sync {
public function delete_appointment($google_calendar_id) {
$this->service->events->delete('primary', $google_calendar_id);
}
public function add_unavailble($unavailable) {
// @task Implement
}
}
/* End of file google_sync.php */

View file

@ -217,12 +217,10 @@ class Appointments_Model extends CI_Model {
*/
public function delete($appointment_id) {
if (!is_numeric($appointment_id)) {
throw new Exception('Invalid argument type $appointment_id : '
. $appointment_id);
throw new Exception('Invalid argument type $appointment_id (value:"' . $appointment_id . '")');
}
$num_rows = $this->db->get_where('ea_appointments',
array('id' => $appointment_id))->num_rows();
$num_rows = $this->db->get_where('ea_appointments', array('id' => $appointment_id))->num_rows();
if ($num_rows == 0) {
return FALSE; // Record does not exist.
@ -315,6 +313,66 @@ class Appointments_Model extends CI_Model {
$current_date = new DateTime();
return md5($current_date->getTimestamp());
}
/**
* Inserts or updates an unavailable period record in the database.
*
* @param array $unavailable Contains the unavaible data.
* @return int Returns the record id.
*/
public function add_unavailable($unavailable) {
// Validate period
$start = strtotime($unavailable['start_datetime']);
$end = strtotime($unavailable['end_datetime']);
if ($start > $end) {
throw new Exception('Unavailable period start must be prior to end.');
}
// Validate provider record
$where_clause = array(
'id' => $unavailable['id_users_provider'],
'id_roles' => $this->db->get_where('ea_roles', array('slug' => DB_SLUG_PROVIDER))->row()->id
);
if ($this->db->get_where('ea_users', $where_clause)->num_rows() == 0) {
throw new Exception('Provider id was not found in database.');
}
// Add record to database (insert or update).
if (!isset($unavailable['id'])) {
$unavailable['book_datetime'] = date('Y-m-d H:i:s');
$unavailable['is_unavailable'] = true;
$this->db->insert('ea_appointments', $unavailable);
$unavailable['id'] = $this->db->insert_id();
} else {
$this->db->where(array('id' => $unavailable['id']));
$this->db->update('ea_appointments', $unavailable);
}
return $unavailable['id'];
}
/**
* Delete an unavailable period.
*
* @param numeric $unavailable_id Record id to be deleted.
*/
public function delete_unavailable($unavailable_id) {
if (!is_numeric($unavailable_id)) {
throw new Exception('Invalid argument type $appointment_id (value:"' .
$unavailable_id . '")');
}
$num_rows = $this->db->get_where('ea_appointments', array('id' => $unavailable_id))
->num_rows();
if ($num_rows == 0) {
return FALSE; // Record does not exist.
}
$this->db->where('id', $unavailable_id);
return $this->db->delete('ea_appointments');
}
}
/* End of file appointments_model.php */

View file

@ -10,14 +10,14 @@ class Services_Model extends CI_Model {
/**
* Get a specific row from the services db table.
*
* @param int $service_id The record's id to be returned.
* @param numeric $service_id The record's id to be returned.
* @return array Returns an associative array with the selected
* record's data. Each key has the same name as the database
* field names.
*/
public function get_row($service_id) {
if (!is_numeric($service_id)) {
throw new Exception('$service_id argument is not an integer : ' . $service_id);
throw new Exception('$service_id argument is not an numeric (value: "' . $service_id . '")');
}
return $this->db->get_where('ea_services', array('id' => $service_id))->row_array();
}

View file

@ -58,7 +58,7 @@
</button>
<button id="insert-unavailable" class="btn"
title="During unavailalbe period the provider won't accept new appointments.">
title="During unavailable periods the provider won't accept new appointments.">
<i class="icon-ban-circle"></i>
<span>Unavailable</span>
</button>
@ -66,7 +66,7 @@
</div>
</div>
<div id="calendar"></div>
<div id="calendar"></div> <?php // Main calendar container ?>
</div>
<div id="manage-appointment" class="modal hide fade">
@ -178,7 +178,50 @@
</div>
<div class="modal-footer">
<button id="save-button" class="btn btn-primary">Save</button>
<button id="cancel-button" class="btn">Cancel</button>
<button id="save-appointment" class="btn btn-primary">Save</button>
<button id="cancel-appointment" class="btn">Cancel</button>
</div>
</div>
<div id="manage-unavailable" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">&times;</button>
<h3>Add Unavailable Period</h3>
<div class="modal-message" class="alert" style="display: none;"></div>
</div>
<div class="modal-body">
<form class="form-horizontal">
<fieldset>
<input id="unavailable-id" type="hidden" />
<div class="control-group">
<label for="unavailable-start" class="control-label">Start</label>
<div class="controls">
<input type="text" id="unavailable-start" />
</div>
</div>
<div class="control-group">
<label for="unavailable-end" class="control-label">End</label>
<div class="controls">
<input type="text" id="unavailable-end" />
</div>
</div>
<div class="control-group">
<label for="unavailable-notes" class="control-label">Notes</label>
<div class="controls">
<textarea id="unavailable-notes"></textarea>
</div>
</div>
</fieldset>
</form>
</div>
<div class="modal-footer">
<button id="save-unavailable" class="btn btn-primary">Save</button>
<button id="cancel-unavailable" class="btn">Cancel</button>
</div>
</div>

View file

@ -22,6 +22,14 @@ $(document).ready(function() {
* @namespace Backend
*/
var Backend = {
/**
* Backend Constants
*/
EXCEPTIONS_TITLE: 'Unexpected Issues',
EXCEPTIONS_MESSAGE: 'The operation could not complete due to unexpected issues. ',
WARNINGS_TITLE: 'Unexpected Warnings',
WARNINGS_MESSAGE: 'The operation completed but some warnings appeared. ',
/**
* Place the backend footer always on the bottom of the page.
*/

View file

@ -113,13 +113,10 @@ var BackendCalendar = {
=== BackendCalendar.FILTER_TYPE_SERVICE) {
$('#google-sync, #enable-sync, #insert-appointment, #insert-unavailable')
.prop('disabled', true);
// @task Hide the unavailable periods.
} else {
$('#google-sync, #enable-sync, #insert-appointment, #insert-unavailable')
.prop('disabled', false);
// @task Show the unavailable periods.
// If the user has already the sync enabled then apply the proper
// style changes.
if ($('#select-filter-item option:selected').attr('google-sync') === 'true') {
@ -226,17 +223,14 @@ var BackendCalendar = {
if (response.exceptions) {
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
+ 'the operation could not complete successfully. The following '
+ 'issues occured:');
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
return;
}
if (response.warnings) {
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
GeneralFunctions.displayMessageBox('Unexpected Warnings', 'The operation '
+ 'was completed but the following warnings appeared:');
GeneralFunctions.displayMessageBox(Backend.WARNINGS_TITLE, Backend.WARNINGS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
}
@ -260,7 +254,7 @@ var BackendCalendar = {
*
* Closes the dialog without saving any changes to the database.
*/
$('#manage-appointment #cancel-button').click(function() {
$('#manage-appointment #cancel-appointment').click(function() {
$('#manage-appointment').modal('hide');
});
@ -270,7 +264,7 @@ var BackendCalendar = {
* Stores the appointment changes or inserts a new appointment depending the dialog
* mode.
*/
$('#manage-appointment #save-button').click(function() {
$('#manage-appointment #save-appointment').click(function() {
// Before doing anything the appointment data need to be validated.
if (!BackendCalendar.validateAppointmentForm()) {
return; // validation failed
@ -320,9 +314,7 @@ var BackendCalendar = {
var successCallback = function(response) {
if (response.exceptions) {
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
+ 'the operation could not complete successfully. The following '
+ 'issues occured:');
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
$('#messsage_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
$dialog.find('.modal-header').append(
@ -357,10 +349,70 @@ var BackendCalendar = {
};
// :: CALL THE UPDATE APPOINTMENT METHOD
BackendCalendar.saveAppointmentData(appointment, customer,
BackendCalendar.saveAppointment(appointment, customer,
successCallback, errorCallback);
});
$('#manage-unavailable #save-unavailable').click(function() {
var $dialog = $('#manage-unavailable');
var start = Date.parseExact($dialog.find('#unavailable-start').val(), 'dd/MM/yyyy HH:mm');
var end = Date.parseExact($dialog.find('#unavailable-end').val(), 'dd/MM/yyyy HH:mm');
if (start > end) {
// Start time is after end time - display message to user.
$dialog.find('.modal-message').html(
'<div class="alert alert-error">' +
'Start date value is bigger than end date!' +
'</div>');
return;
}
// Unavailable period records go to the appointments table.
var unavailable = {
'start_datetime': start.toString('yyyy-MM-dd HH:mm'),
'end_datetime': end.toString('yyyy-MM-dd HH:mm'),
'notes': $dialog.find('#unavailable-notes').val(),
'id_users_provider': $('#select-filter-item').val() // curr provider
};
var successCallback = function(response) {
///////////////////////////////////////////////////////////////////
console.log('Save Unavailable Time Period Response:', response);
///////////////////////////////////////////////////////////////////
if (response.exceptions) {
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
return;
}
if (response.warnings) {
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
GeneralFunctions.displayMessageBox(Backend.WARNINGS_TITLE, Backend.WARNINGS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
}
$('#manage-unavailable').modal('hide');
};
var errorCallback = function(jqXHR, textStatus, errorThrown) {
////////////////////////////////////////////////////////////////////////
console.log('Save Unavailable Error:', jqXHR, textStatus, errorThrown);
////////////////////////////////////////////////////////////////////////
GeneralFunctions.displayMessageBox('Communication Error', 'Unfortunately ' +
'the operation could not complete due to server communication errors.');
};
BackendCalendar.saveUnavalable(unavailable, successCallback, errorCallback);
});
$('#manage-unavailable #cancel-unavailable').click(function() {
$('#manage-unavailable').modal('hide');
});
/**
* Event: Enable - Disable Synchronization Button "Click"
*
@ -438,7 +490,10 @@ var BackendCalendar = {
* a time period where he cannot accept any appointments.
*/
$('#insert-unavailable').click(function() {
// @task Implement this event handler.
BackendCalendar.resetUnavailableDialog();
var $dialog = $('#manage-unavailable');
$dialog.find('.modal-header h3').text('New Unavailable Period');
$dialog.modal('show');
});
},
@ -483,17 +538,14 @@ var BackendCalendar = {
if (response.exceptions) {
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
+ 'the operation could not complete successfully. The following '
+ 'issues occured:');
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
return;
}
if (response.warnings) {
response.warnings = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox('Unexpected Warnings', 'The operation was '
+ 'completed but the following warnings appeared.');
GeneralFunctions.displayMessageBox(Backend.WARNINGS_TITLE, Backend.WARNINGS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
}
@ -655,10 +707,8 @@ var BackendCalendar = {
$('#calendar').fullCalendar('renderEvent', unavailablePeriod, true);
});
// @task Add custom unavailable periods.
currDateStart.addDays(1);
currDateEnd.addDays(1);
});
@ -683,8 +733,7 @@ var BackendCalendar = {
* @param {function} errorCallback (OPTIONAL) If defined, this function is
* going to be executed on post failure.
*/
saveAppointmentData : function(appointment, customer,
successCallback, errorCallback) {
saveAppointment: function(appointment, customer, successCallback, errorCallback) {
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_appointment';
var postData = {};
@ -722,6 +771,29 @@ var BackendCalendar = {
});
},
/**
* Save unavailable period to database.
*
* @param {object} unavailable Containts the unavailable period data.
* @param {function} successCallback The ajax success callback function.
* @param {function} errorCallback The ajax failure callback function.
*/
saveUnavalable: function(unavailable, successCallback, errorCallback) {
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_unavailable';
var postData = {
'unavailable': JSON.stringify(unavailable)
};
$.ajax({
'type': 'POST',
'url': postUrl,
'data': postData,
'success': successCallback,
'error': errorCallback
});
},
/**
* Calendar Event "Resize" Callback
*
@ -755,9 +827,7 @@ var BackendCalendar = {
var successCallback = function(response) {
if (response.exceptions) {
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
+ 'the operation could not complete successfully. The following '
+ 'issues occured:');
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
return;
}
@ -765,8 +835,7 @@ var BackendCalendar = {
if (response.warnings) {
// Display warning information to the user.
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
GeneralFunctions.displayMessageBox('Warnings', 'The operation completed but '
+ 'there were some warnings:');
GeneralFunctions.displayMessageBox(Backend.WARNINGS_TITLE, Backend.WARNINGS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
}
@ -796,7 +865,7 @@ var BackendCalendar = {
};
// :: UPDATE APPOINTMENT DATA VIA AJAX CALL
BackendCalendar.saveAppointmentData(appointment, undefined,
BackendCalendar.saveAppointment(appointment, undefined,
successCallback, undefined);
},
@ -836,39 +905,56 @@ var BackendCalendar = {
calendarEventClick: function(event, jsEvent, view) {
$('.popover').remove(); // Close all open popovers.
if ($(jsEvent.target).hasClass('fc-unavailable')) {
return; // do not show popover on unavailable events
}
var html;
// Display a popover with the event details.
var html =
'<style type="text/css">'
+ '.popover-content strong {min-width: 80px; display:inline-block;}'
+ '.popover-content button {margin-right: 10px;}'
+ '</style>' +
'<strong>Start</strong> '
+ event.start.toString('dd/MM/yyyy HH:mm')
+ '<br>' +
'<strong>End</strong> '
+ event.end.toString('dd/MM/yyyy HH:mm')
+ '<br>' +
'<strong>Service</strong> '
+ event.data['service']['name']
+ '<br>' +
'<strong>Provider</strong> '
+ event.data['provider']['first_name'] + ' '
+ event.data['provider']['last_name']
+ '<br>' +
'<strong>Customer</strong> '
+ event.data['customer']['first_name'] + ' '
+ event.data['customer']['last_name']
+ '<hr>' +
'<center>' +
'<button class="edit-popover btn btn-primary">Edit</button>' +
'<button class="delete-popover btn btn-danger">Delete</button>' +
'<button class="close-popover btn" data-po=' + jsEvent.target + '>Close</button>' +
'</center>';
if ($(jsEvent.target.offsetParent).hasClass('fc-unavailable')
|| $(jsEvent.target).parents().eq(1).hasClass('fc-unavailable')) {
html =
'<style type="text/css">'
+ '.popover-content strong {min-width: 80px; display:inline-block;}'
+ '.popover-content button {margin-right: 10px;}'
+ '</style>' +
'<strong>Start</strong> '
+ event.start.toString('dd/MM/yyyy HH:mm')
+ '<br>' +
'<strong>End</strong> '
+ event.end.toString('dd/MM/yyyy HH:mm')
+ '<br>' +
'<center>' +
'<button class="edit-popover btn btn-primary">Edit</button>' +
'<button class="delete-popover btn btn-danger">Delete</button>' +
'<button class="close-popover btn" data-po=' + jsEvent.target + '>Close</button>' +
'</center>';
} else {
html =
'<style type="text/css">'
+ '.popover-content strong {min-width: 80px; display:inline-block;}'
+ '.popover-content button {margin-right: 10px;}'
+ '</style>' +
'<strong>Start</strong> '
+ event.start.toString('dd/MM/yyyy HH:mm')
+ '<br>' +
'<strong>End</strong> '
+ event.end.toString('dd/MM/yyyy HH:mm')
+ '<br>' +
'<strong>Service</strong> '
+ event.data['service']['name']
+ '<br>' +
'<strong>Provider</strong> '
+ event.data['provider']['first_name'] + ' '
+ event.data['provider']['last_name']
+ '<br>' +
'<strong>Customer</strong> '
+ event.data['customer']['first_name'] + ' '
+ event.data['customer']['last_name']
+ '<hr>' +
'<center>' +
'<button class="edit-popover btn btn-primary">Edit</button>' +
'<button class="delete-popover btn btn-danger">Delete</button>' +
'<button class="close-popover btn" data-po=' + jsEvent.target + '>Close</button>' +
'</center>';
}
$(jsEvent.target).popover({
'placement': 'top',
'title': event.title,
@ -921,9 +1007,7 @@ var BackendCalendar = {
var successCallback = function(response) {
if (response.exceptions) {
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
+ 'the operation could not complete successfully. The following '
+ 'issues occured:');
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
return;
}
@ -931,8 +1015,7 @@ var BackendCalendar = {
if (response.warnings) {
// Display warning information to the user.
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
GeneralFunctions.displayMessageBox('Warnings', 'The operation completed but '
+ 'there were some warnings:');
GeneralFunctions.displayMessageBox(Backend.WARNINGS_TITLE, Backend.WARNINGS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
}
@ -972,7 +1055,7 @@ var BackendCalendar = {
};
// :: UPDATE APPOINTMENT DATA VIA AJAX CALL
BackendCalendar.saveAppointmentData(appointment, undefined,
BackendCalendar.saveAppointment(appointment, undefined,
successCallback, undefined);
},
@ -983,8 +1066,10 @@ var BackendCalendar = {
* need to be made, in order to display proper information to the user.
*/
calendarViewDisplay : function(view) {
// Place the footer into correct position because the calendar
// height might change.
if ($('#select-filter-item').val() === null) {
return;
}
BackendCalendar.refreshCalendarAppointments(
$('#calendar'),
$('#select-filter-item').val(),
@ -1016,9 +1101,7 @@ var BackendCalendar = {
if (response.exceptions) {
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately '
+ 'the operation could not complete successfully. The following '
+ 'issues occured:');
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
return;
}
@ -1132,15 +1215,31 @@ var BackendCalendar = {
return false;
}
},
/**
* This method adds an unavailable time period to calendar.
*
* @param {date} start The period start date and time.
* @param {date} end The period end date and time.
* @return {bool} Returns the operation result.
* Reset the "#manage-unavailable" dialog. Use this method to bring the dialog
* to the initial state before it becomes visible to the user.
*/
addUnavailableTimePeriod: function(start, end) {
// @task Use this method whenever you need to add an unavailable period on calendar.
resetUnavailableDialog: function() {
var $dialog = $('#manage-unavailable');
// Set default time values
var start = new Date().toString('dd/MM/yyyy HH:mm');
var end = new Date().addHours(1).toString('dd/MM/yyyy HH:mm');
$dialog.find('#unavailable-start').datetimepicker({
'dateFormat': 'dd/mm/yy',
'minDate': 0
});
$dialog.find('#unavailable-start').val(start);
$dialog.find('#unavailable-end').datetimepicker({
'dateFormat': 'dd/mm/yy',
'minDate': 0
});
$dialog.find('#unavailable-end').val(end);
// Clear the unavailable notes field.
$dialog.find('#unavailable-notes').val('');
}
};

View file

@ -1,13 +1,13 @@
<?php
class SystemConfiguration {
// General Settings
public static $base_url = 'http://localhost/dev/easy_appointments/trunk/src/';
public static $base_url = 'http://localhost/dev/external/easy_appointments/trunk/src/';
// Database Settings
public static $db_host = 'localhost';
public static $db_name = 'easy_appointments';
public static $db_username = 'root';
public static $db_password = 'root';
public static $db_password = '';
// Google Calendar API Settings
public static $google_product_name = 'Easy!Appointments';