diff --git a/Release Notes.txt b/Release Notes.txt index e17f568c..903429d5 100644 --- a/Release Notes.txt +++ b/Release Notes.txt @@ -10,4 +10,5 @@ Main Minor - Display javascript ajax error messages to users. +- Provider can edit appointment from email link. \ No newline at end of file diff --git a/db/easy_appointments.sql b/db/easy_appointments.sql index d66c0435..a703614e 100644 --- a/db/easy_appointments.sql +++ b/db/easy_appointments.sql @@ -3,7 +3,7 @@ -- http://www.phpmyadmin.net -- -- Φιλοξενητής: localhost --- Χρόνος δημιουργίας: 09 Ιουλ 2013 στις 15:16:49 +-- Χρόνος δημιουργίας: 15 Ιουλ 2013 στις 10:07:35 -- Έκδοση διακομιστή: 5.5.24-log -- Έκδοση PHP: 5.4.3 @@ -42,23 +42,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=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'); +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=102 ; -- -------------------------------------------------------- @@ -111,10 +95,9 @@ CREATE TABLE IF NOT EXISTS `ea_services` ( -- INSERT INTO `ea_services` (`id`, `name`, `duration`, `price`, `currency`, `description`, `id_service_categories`) VALUES -(1, 'Γενική Εξέταση', 20, '50.00', 'euro', 'Γενική εξέταση του ασθενή.', NULL), -(2, 'Εξέταση Καρδιάς', 30, '40.00', 'euro', 'Εξέταση του ασθενή για νοσήματα καρδιάς.', NULL), -(3, 'Νευρολογική Εξέταση', 20, '35.00', 'euro', 'Νευρολογική εξέταση του ασθενή.', NULL), -(9, 'General Examination', 30, '50.00', 'euro', 'This is some service description.', NULL); +(1, 'General Examination', 20, '50.00', 'euro', 'General examination of the patient.', NULL), +(2, 'Heart Examination', 30, '40.00', 'euro', 'Checkup for heart problems.', NULL), +(3, 'Neurological Examination', 20, '35.00', 'euro', 'Neurological tests for the patient.', NULL); -- -------------------------------------------------------- @@ -177,7 +160,7 @@ INSERT INTO `ea_settings` (`id`, `name`, `value`) VALUES (1, 'company_name', 'Javation & Co'), (2, 'company_working_plan', '{"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"}]}}'), (3, 'company_email', 'alextselegidis@gmail.com'), -(8, 'company_link', 'http://google.gr'), +(8, 'company_link', 'http://javation.com'), (9, 'book_advance_timeout', '30'); -- -------------------------------------------------------- @@ -208,11 +191,11 @@ CREATE TABLE IF NOT EXISTS `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, '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), -(5, '', 'a', 'alextselegidis@yahoo.gr', NULL, 'a', '', '', NULL, '', NULL, 3); +(1, 'Ringo', 'Starr', 'alextselegidis@gmail.com', '0000000000000', '0000000000000', 'Some Str', 'Some City', 'Some State 0', '00000', 'This is me making Easy!Appointments :P', 1), +(2, 'George', 'Harrison', 'alextselegidis@gmail.com', '1111111111111', '1111111111111', 'Some Str 1', 'Some City 1', 'Some State 1', '11111', 'This is a test provider (with my email for google syncing).', 2), +(3, 'John', 'Lennon', 'prov2@test.gr', '2222222222222', '2222222222222', 'Some Str 2', 'Some City 2', 'Some State 2', '22222', NULL, 2), +(4, 'Paul', 'McCartney', 'prov3@test.gr', '3333333333333', '3333333333333', 'Some Str 3', 'Some City 3', 'Some State 3', '33333', NULL, 2), +(5, 'John', 'Doe', 'alextselegidis@yahoo.gr', NULL, '0123456789', '', '', NULL, '', 'This is my testing customer.', 3); -- -------------------------------------------------------- @@ -228,6 +211,8 @@ CREATE TABLE IF NOT EXISTS `ea_user_settings` ( `notifications` text, `google_sync` tinyint(4) DEFAULT '0', `google_token` text, + `sync_past_days` int(11) DEFAULT '5', + `sync_future_days` int(11) DEFAULT '5', PRIMARY KEY (`id_users`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -235,10 +220,10 @@ CREATE TABLE IF NOT EXISTS `ea_user_settings` ( -- Άδειασμα δεδομένων του πίνακα `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.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, 0, NULL); +INSERT INTO `ea_user_settings` (`id_users`, `username`, `password`, `working_plan`, `notifications`, `google_sync`, `google_token`, `sync_past_days`, `sync_future_days`) 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, 0, NULL, 5, 5), +(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, 5, 5), +(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, 5, 5); -- -- Περιορισμοί για άχρηστους πίνακες diff --git a/doc/Θέμα Πτυχιακής.pdf b/doc/thesis-topic.pdf similarity index 100% rename from doc/Θέμα Πτυχιακής.pdf rename to doc/thesis-topic.pdf diff --git a/src/application/controllers/appointments.php b/src/application/controllers/appointments.php index ed510221..7d27815d 100644 --- a/src/application/controllers/appointments.php +++ b/src/application/controllers/appointments.php @@ -149,7 +149,7 @@ class Appointments extends CI_Controller { $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/' + $provider_link = $this->config->item('base_url') . 'backend/index/' . $appointment['hash']; } else { $customer_title = 'Appointment changes have been successfully saved!'; @@ -159,7 +159,7 @@ class Appointments extends CI_Controller { $provider_title = 'Appointment details have changed.'; $provider_message = ''; - $provider_link = $this->config->item('base_url') . 'backend/' + $provider_link = $this->config->item('base_url') . 'backend/index/' . $appointment['hash']; } diff --git a/src/application/controllers/backend.php b/src/application/controllers/backend.php index 33be1ed4..02612537 100644 --- a/src/application/controllers/backend.php +++ b/src/application/controllers/backend.php @@ -18,6 +18,7 @@ class Backend extends CI_Controller { $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'); $view['base_url'] = $this->config->item('base_url'); @@ -28,7 +29,9 @@ class Backend extends CI_Controller { if ($appointment_hash != '') { $results = $this->appointments_model->get_batch(array('hash' => $appointment_hash)); - $view['edit_appointment'] = $results[0]; // This will display the appointment edit dialog on page load. + $appointment = $results[0]; + $appointment['customer'] = $this->customers_model->get_row($appointment['id_users_customer']); + $view['edit_appointment'] = $appointment; // This will display the appointment edit dialog on page load. } else { $view['edit_appointment'] = NULL; } diff --git a/src/application/controllers/google.php b/src/application/controllers/google.php index fcf25975..8f39fecf 100644 --- a/src/application/controllers/google.php +++ b/src/application/controllers/google.php @@ -73,7 +73,8 @@ class Google extends CI_Controller { * * @param numeric $provider_id Provider record to be synced. * - * @task This method must be executed only by the system and noone else outside. It is a big security issue. + * @task This method must be executed only by the system and noone else outside. + * It is a big security issue. */ public function sync($provider_id = NULL) { try { @@ -127,52 +128,62 @@ class Google extends CI_Controller { $service = $this->services_model->get_row($appointment['id_services']); $customer = $this->customers_model->get_row($appointment['id_users_customer']); - // :: APPOINTMENT WITH NO GCAL_ID -> ADD TO GCAL + // If current appointment not synced yet, add to gcal. 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); // save gcal id - } - - // :: SYNCED APPOINTMENT NOT FOUND ON GCAL -> DELETE E!A RECORD - if ($appointment['id_google_calendar'] != NULL) { + $this->appointments_model->add($appointment); // Save gcal id + } else { + // Appointment is synced with google calendar. try { $google_event = $this->google_sync->get_event($appointment['id_google_calendar']); - } catch(Exception $exc) { - $this->appointments_model->delete($appointment['id']); - $appointment['id_google_calendar'] = NULL; // Do not proceed with the rest sync actions. - } - } - - // :: SYNCED APPOINTMENT DIFFERENT FROM GCAL EVENT -> UPDATE E!A RECORD - if ($appointment['id_google_calendar'] != NULL) { - $is_different = FALSE; - $appt_start = strtotime($appointment['start_datetime']); - $appt_end = strtotime($appointment['end_datetime']); - $event_start = strtotime($google_event->getStart()->getDateTime()); - $event_end = strtotime($google_event->getEnd()->getDateTime()); - - if ($appt_start != $event_start - || $appt_end != $event_end) { - $is_different = TRUE; - } - - if ($is_different) { - $appointment['start_datetime'] = date('Y-m-d H:i:s', $event_start); - $appointment['end_datetime'] = date('Y-m-d H:i:s', $event_end); - $this->appointments_model->add($appointment); - } - - } - - // @task :: GCAL EVENT NOT FOUND ON E!A -> ADD EVENT TO E!A - + // If gcal event is different from e!a appointment then update e!a record. + $is_different = FALSE; + $appt_start = strtotime($appointment['start_datetime']); + $appt_end = strtotime($appointment['end_datetime']); + $event_start = strtotime($google_event->getStart()->getDateTime()); + $event_end = strtotime($google_event->getEnd()->getDateTime()); + + if ($appt_start != $event_start || $appt_end != $event_end) { + $is_different = TRUE; + } + + if ($is_different) { + $appointment['start_datetime'] = date('Y-m-d H:i:s', $event_start); + $appointment['end_datetime'] = date('Y-m-d H:i:s', $event_end); + $this->appointments_model->add($appointment); + } + } catch(Exception $exc) { + // Appointment not found on gcal, delete from e!a. + $this->appointments_model->delete($appointment['id']); + $appointment['id_google_calendar'] = NULL; + } + } } - // @task Sync unavailable periods with Google Calendar + // :: ADD GCAL EVENTS THAT ARE NOT PRESENT ON E!A + $events = $this->google_sync->get_sync_events($start, $end); + foreach($events->getItems() as $event) { + $results = $this->appointments_model->get_batch(array('id_google_calendar' => $event->getId())); + if (count($results) == 0) { + // Record doesn't exist in E!A, so add the event now. + $appointment = array( + 'start_datetime' => date('Y-m-d H:i:s', strtotime($event->start->getDateTime())), + 'end_datetime' => date('Y-m-d H:i:s', strtotime($event->end->getDateTime())), + 'is_unavailable' => TRUE, + 'notes' => $event->getSummary() . ' ' . $event->getDescription(), + 'id_users_provider' => $provider_id, + 'id_google_calendar' => $event->getId(), + 'id_users_customer' => NULL, + 'id_services' => NULL, + ); + + $this->appointments_model->add($appointment); + } + } echo json_encode('SUCCESS'); diff --git a/src/application/helpers/custom_exceptions_helper.php b/src/application/helpers/custom_exceptions_helper.php index b0cd60b6..63e46690 100644 --- a/src/application/helpers/custom_exceptions_helper.php +++ b/src/application/helpers/custom_exceptions_helper.php @@ -29,22 +29,22 @@ class SyncException extends Exception {} * We display only one exceptions at a time because the user needs to be able * to display the details of each exception seperately. (In contrast with js). * - * @param Exception $exception The exception to be displayed. + * @param Exception $exc The exception to be displayed. * @return string Returns the html markup of the exception. */ -function exceptionToHtml($exception) { +function exceptionToHtml($exc) { return '
' . $exception->getTraceAsString() . '+
' . $exc->getTraceAsString() . '