diff --git a/Release Notes.txt b/Release Notes.txt index ee1cbb64..a3386a31 100644 --- a/Release Notes.txt +++ b/Release Notes.txt @@ -1,9 +1,9 @@ VERSION 0.2 =========== - Use the PHPMailer class for sending HTML emails. +- Display error message to users. - Includes complete Google Sync protocol document. - Customers can book appointments only for the available hours. -- Generation of code documentation. -- Unit test the controller classes. +- Generation of code documentation. - Customers can edit the application through unique links (from their emails). - Minor Fixes diff --git a/db/easy_appointments.sql b/db/easy_appointments.sql index cc602087..a346be48 100644 --- a/db/easy_appointments.sql +++ b/db/easy_appointments.sql @@ -3,7 +3,7 @@ -- http://www.phpmyadmin.net -- -- Φιλοξενητής: localhost --- Χρόνος δημιουργίας: 08 Μάη 2013 στις 17:29:41 +-- Χρόνος δημιουργίας: 08 Ιουν 2013 στις 12:49:21 -- Έκδοση διακομιστή: 5.5.24-log -- Έκδοση PHP: 5.4.3 @@ -28,9 +28,11 @@ SET time_zone = "+00:00"; CREATE TABLE IF NOT EXISTS `ea_appointments` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `book_datetime` datetime DEFAULT NULL, `start_datetime` datetime DEFAULT NULL, `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, @@ -38,48 +40,14 @@ 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=50 ; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=43 ; -- -- Άδειασμα δεδομένων του πίνακα `ea_appointments` -- -INSERT INTO `ea_appointments` (`id`, `start_datetime`, `end_datetime`, `notes`, `id_users_provider`, `id_users_customer`, `id_services`) VALUES -(14, '2013-04-26 12:40:00', '2013-04-26 12:40:00', '', 2, 1, 1), -(15, '2013-04-26 16:00:00', '2013-04-26 16:00:00', '', 2, 1, 1), -(16, '2013-04-26 13:00:00', '2013-04-26 13:00:00', 'Something else here ...', 2, 19, 1), -(17, '2013-04-26 14:00:00', '2013-04-26 14:00:00', '', 2, 20, 1), -(18, '2013-04-26 14:20:00', '2013-04-26 14:20:00', '', 2, 19, 1), -(19, '2013-04-26 14:20:00', '2013-04-26 14:20:00', 'Some notes ...', 2, 20, 1), -(20, '2013-04-26 14:30:00', '2013-04-26 14:30:00', 'ooo', 3, 20, 2), -(21, '2013-04-26 15:40:00', '2013-04-26 15:40:00', '', 2, 21, 1), -(22, '2013-04-26 16:40:00', '2013-04-26 16:40:00', '', 2, 21, 1), -(23, '2013-04-26 14:40:00', '2013-04-26 14:40:00', '', 2, 21, 1), -(24, '2013-05-01 18:00:00', '2013-05-01 18:00:00', '', 2, 19, 1), -(25, '2013-05-01 18:20:00', '2013-05-01 18:20:00', '', 2, 19, 1), -(26, '2013-05-01 18:40:00', '2013-05-01 18:40:00', '', 2, 19, 1), -(27, '2013-05-02 00:00:00', '2013-05-02 19:01:00', '', 2, 19, 1), -(28, '2013-05-03 13:00:00', '2013-05-03 13:00:00', '', 2, 19, 1), -(29, '2013-05-03 13:40:00', '2013-05-03 13:40:00', '', 2, 19, 1), -(30, '2013-05-03 14:20:00', '2013-05-03 14:20:00', '', 2, 19, 1), -(31, '2013-05-04 08:00:00', '2013-05-04 08:00:00', '', 3, 19, 3), -(32, '2013-05-03 00:00:00', '2013-05-03 20:45:00', '', 3, 19, 2), -(33, '2013-05-04 08:20:00', '2013-05-04 08:20:00', '', 2, 19, 1), -(34, '2013-05-04 09:20:00', '2013-05-04 09:20:00', '', 2, 19, 1), -(35, '2013-05-04 12:40:00', '2013-05-04 12:40:00', '', 2, 19, 1), -(36, '2013-05-04 13:20:00', '2013-05-04 13:20:00', '', 2, 19, 1), -(37, '2013-05-04 08:00:00', '2013-05-04 08:00:00', '', 2, 19, 1), -(38, '2013-05-03 00:00:00', '2013-05-03 23:18:00', '', 2, 19, 1), -(40, '2013-05-04 11:20:00', '2013-05-04 11:20:00', '', 2, 19, 1), -(41, '2013-05-04 12:00:00', '2013-05-04 12:00:00', '', 2, 19, 1), -(42, '2013-05-04 17:30:00', '2013-05-04 17:30:00', '', 3, 19, 2), -(43, '2013-05-04 19:00:00', '2013-05-04 19:00:00', '', 3, 19, 3), -(44, '2013-05-04 18:30:00', '2013-05-04 18:30:00', '', 4, 20, 2), -(45, '2013-05-07 11:00:00', '2013-05-07 11:00:00', 'Some notes ...', 2, 19, 1), -(46, '2013-05-07 11:20:00', '2013-05-07 11:20:00', '', 2, 19, 1), -(47, '2013-05-07 14:40:00', '2013-05-07 14:40:00', '', 2, 19, 1), -(48, '2013-05-07 15:00:00', '2013-05-07 15:00:00', '', 2, 20, 1), -(49, '2013-05-07 11:40:00', '2013-05-07 11:40:00', '', 2, 19, 1); +INSERT INTO `ea_appointments` (`id`, `book_datetime`, `start_datetime`, `end_datetime`, `notes`, `hash`, `id_users_provider`, `id_users_customer`, `id_services`) VALUES +(10, NULL, '2013-06-07 15:30:00', '2013-06-07 15:50:00', '', 'c4baf9ea27dcd0fdc5449eb91b0ee2c5', 2, 20, 1); -- -------------------------------------------------------- @@ -125,7 +93,7 @@ CREATE TABLE IF NOT EXISTS `ea_services` ( `id_service_categories` bigint(20) unsigned DEFAULT NULL, PRIMARY KEY (`id`), KEY `id_service_categories` (`id_service_categories`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=22 ; -- -- Άδειασμα δεδομένων του πίνακα `ea_services` @@ -134,7 +102,8 @@ 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); +(3, 'Νευρολογική Εξέταση', 20, '35.00', 'euro', 'Νευρολογική εξέταση του ασθενή.', NULL), +(9, 'General Examination', 30, '50.00', 'euro', 'This is some service description.', NULL); -- -------------------------------------------------------- @@ -187,16 +156,18 @@ CREATE TABLE IF NOT EXISTS `ea_settings` ( `name` varchar(512) DEFAULT NULL, `value` longtext, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=22 ; -- -- Άδειασμα δεδομένων του πίνακα `ea_settings` -- INSERT INTO `ea_settings` (`id`, `name`, `value`) VALUES -(1, 'business_name', 'Javation & Co'), -(2, 'business_working_hours', '{}'), -(3, 'business_email', 'alextselegidis@gmail.com'); +(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'), +(9, 'book_advance_timeout', '30'); -- -------------------------------------------------------- @@ -206,8 +177,6 @@ INSERT INTO `ea_settings` (`id`, `name`, `value`) VALUES CREATE TABLE IF NOT EXISTS `ea_users` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `username` varchar(256) DEFAULT NULL, - `password` varchar(512) DEFAULT NULL, `first_name` varchar(256) DEFAULT NULL, `last_name` varchar(512) DEFAULT NULL, `email` varchar(512) DEFAULT NULL, @@ -221,20 +190,44 @@ 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=22 ; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=116 ; -- -- Άδειασμα δεδομένων του πίνακα `ea_users` -- -INSERT INTO `ea_users` (`id`, `username`, `password`, `first_name`, `last_name`, `email`, `mobile_number`, `phone_number`, `address`, `city`, `state`, `zip_code`, `notes`, `id_roles`) VALUES -(1, 'admin', 'admin', '', '1', 'alextselegidis@gmail.com', '123456789', '1', '', '', NULL, '', 'This is me making Easy!Appointments', 1), -(2, 'provider_1', 'provider_1', 'Γεώργιος', 'Παπαδόπουλος', 'alextselegidis@gmail.com', '1212121212', '1', '', '', NULL, '', 'This is a test provider', 2), -(3, 'provider_2', 'provider_2', 'Νίκος', 'Αναστασίου', 'prov2@test.gr', '1313133113131', '32132165146', 'Some Street 3', NULL, NULL, NULL, NULL, 2), -(4, 'provider_3', 'provider_3', 'Ηρώ', 'Καριοφύλη', 'prov3@test.gr', '239203490', '029340923', 'John Doe 3 ', NULL, NULL, NULL, NULL, 2), -(19, NULL, NULL, '', 'a', 'alextselegidis@gmail.com', NULL, 'a', '', '', NULL, '', NULL, 3), -(20, NULL, NULL, 'Alex', 'Tselegidis', 'alextselegidis@yahoo.gr', NULL, '6988589365', '', '', NULL, '', NULL, 3), -(21, NULL, NULL, '', '1', 'black-sabbath1967@hotmail.com', NULL, '1', '', '', NULL, '', NULL, 3); +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), +(20, 'Alex', 'Tselegidis', 'alextselegidis@yahoo.gr', NULL, '123456789', 'Some Str', 'Some City', NULL, '12345', NULL, 3), +(76, '', 'a', 'alextselegidis@yahoo.gr', NULL, 'a', '', '', NULL, '', NULL, 3); + +-- -------------------------------------------------------- + +-- +-- Δομή πίνακα για τον πίνακα `ea_user_settings` +-- + +CREATE TABLE IF NOT EXISTS `ea_user_settings` ( + `id_users` bigint(20) unsigned NOT NULL, + `username` varchar(256) DEFAULT NULL, + `password` varchar(512) DEFAULT NULL, + `working_plan` text, + `notifications` text, + `google_sync` tinyint(4) DEFAULT NULL, + PRIMARY KEY (`id_users`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Άδειασμα δεδομένων του πίνακα `ea_user_settings` +-- + +INSERT INTO `ea_user_settings` (`id_users`, `username`, `password`, `working_plan`, `notifications`, `google_sync`) 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), +(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), +(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); -- -- Περιορισμοί για άχρηστους πίνακες @@ -267,6 +260,12 @@ ALTER TABLE `ea_services_providers` ALTER TABLE `ea_users` ADD CONSTRAINT `ea_users_ibfk_1` FOREIGN KEY (`id_roles`) REFERENCES `ea_roles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +-- +-- Περιορισμοί για πίνακα `ea_user_settings` +-- +ALTER TABLE `ea_user_settings` + ADD CONSTRAINT `ea_user_settings_ibfk_1` FOREIGN KEY (`id_users`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; + /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/doc/code-docs/js/bookAppointment.html b/doc/code-docs/js/bookAppointment.html index 692a57db..40edd0b9 100644 --- a/doc/code-docs/js/bookAppointment.html +++ b/doc/code-docs/js/bookAppointment.html @@ -30,7 +30,7 @@ bookAppointment -
Implelements the js part of the appointment booking page.
+
Implements the js part of the appointment booking page.
@@ -49,9 +49,9 @@
- This class implements the book appointment page functionality. -Once the initialize() method is called the page is fully functional -and can serve the appointment booking process. + This class implements the book appointment page functionality. Once +the initialize() method is called the page is fully functional and +can serve the appointment booking process.
@@ -123,12 +123,266 @@ and can serve the appointment booking process. +

Members

+ +
+ +
+

<static> manageMode :Boolean

+ + +
+
+ +
+ Determines the functionality of the page. +
+ + + +
Type:
+ + + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + +
+ +
+

Methods

+
+

<static> applyAppointmentData(appointmentData, providerData, customerData) → {bool}

+ + +
+
+ + +
+ This method applies the appointment's data to the wizard so +that the user can start making changes on an existing record. +
+ + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
appointmentData + + +object + + + + Selected appointment's data.
providerData + + +object + + + + Selected provider's data.
customerData + + +object + + + + Selected customer's data.
+ + + +
+ + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + +
Returns:
+ + +
+ Returns the operation result. +
+ + + +
+
+ Type +
+
+ +bool + + +
+
+ + + + +
+ + +

<static> bindEventHandlers()

@@ -138,8 +392,8 @@ and can serve the appointment booking process.
- This method binds the necessary event handlers -for the book appointments page. + This method binds the necessary event handlers for the book +appointments page.
@@ -172,7 +426,7 @@ for the book appointments page.
Source:
@@ -242,7 +496,7 @@ End datetime is depending on the service and start datetime fieldss.
Source:
@@ -383,7 +637,7 @@ hours we need to receive.
Source:
@@ -411,7 +665,7 @@ hours we need to receive.
-

<static> initialize(bindEventHandlers)

+

<static> initialize(bindEventHandlers, manageMode)

@@ -469,11 +723,36 @@ hours we need to receive. - (OPTIONAL) Determines wether + (OPTIONAL) Determines whether the default event handlers will be binded to the dom elements. + + + + manageMode + + + + + +bool + + + + + + + + + + (OPTIONAL) Determines whether the customer +is going to make changes to an existing appointment rather than +booking a new one. + + + @@ -501,7 +780,7 @@ the default event handlers will be binded to the dom elements.
Source:
@@ -529,7 +808,7 @@ the default event handlers will be binded to the dom elements.
-

<static> updateConfirmData()

+

<static> updateConfirmFrame()

@@ -572,7 +851,7 @@ booking.
Source:
@@ -600,7 +879,7 @@ booking.
-

<static> validateCustomerDataForm() → {bool}

+

<static> validateCustomerForm() → {bool}

@@ -642,7 +921,7 @@ It only checks for empty fields by the time.
Source:
@@ -711,7 +990,7 @@ It only checks for empty fields by the time.
diff --git a/doc/code-docs/js/book_appointment.js.html b/doc/code-docs/js/book_appointment.js.html index 9c4a0a73..6bad074e 100644 --- a/doc/code-docs/js/book_appointment.js.html +++ b/doc/code-docs/js/book_appointment.js.html @@ -26,24 +26,40 @@
/**
- * This class implements the book appointment page functionality. 
- * Once the initialize() method is called the page is fully functional 
- * and can serve the appointment booking process.
+ * This class implements the book appointment page functionality. Once 
+ * the initialize() method is called the page is fully functional and 
+ * can serve the appointment booking process.
  * 
- * @class Implelements the js part of the appointment booking page.
+ * @class Implements the js part of the appointment booking page.
  */
 var bookAppointment = {
+    /**
+     * Determines the functionality of the page.
+     * 
+     * @type Boolean
+     */
+    manageMode      : false,  
+    
     /**
      * This method initializes the book appointment page.
      * 
-     * @param {bool} bindEventHandlers (OPTIONAL) Determines wether 
+     * @param {bool} bindEventHandlers (OPTIONAL) Determines whether 
      * the default event handlers will be binded to the dom elements.
+     * @param {bool} manageMode (OPTIONAL) Determines whether the customer
+     * is going to make changes to an existing appointment rather than
+     * booking a new one.
      */
-    initialize : function(bindEventHandlers) {
-        if (bindEventHandlers == undefined) {
-            bindEventHandlers = true; // Default value
+    initialize : function(bindEventHandlers, manageMode) {
+        if (bindEventHandlers === undefined) {
+            bindEventHandlers = true; // Default Value
         }
         
+        if (manageMode === undefined) {
+            manageMode = false; // Default Value
+        }
+        
+        bookAppointment.manageMode = manageMode;
+        
         // Initialize page's components (tooltips, datepickers etc).
         $('.book-step').qtip({
             position: {
@@ -61,7 +77,7 @@ var bookAppointment = {
             defaultDate : Date.today(),
             onSelect    : function(dateText, instance) {
                 bookAppointment.getAvailableHours(dateText);
-                bookAppointment.updateConfirmData();
+                bookAppointment.updateConfirmFrame();
             }
         });
        
@@ -70,22 +86,31 @@ var bookAppointment = {
         if (bindEventHandlers) {
             bookAppointment.bindEventHandlers();
         }
-       
-        // Execute other necessary operations on startup.
-        $('#select-service').trigger('change');
+        
+        // If the manage mode is true, the appointments data should be
+        // loaded by default.
+        if (bookAppointment.manageMode) {
+            bookAppointment.applyAppointmentData(GlobalVariables.appointmentData,
+                    GlobalVariables.providerData, GlobalVariables.customerData);
+        } else {
+            $('#select-service').trigger('change'); // Load the available hours.
+        }
     },
     
     /**
-     * This method binds the necessary event handlers 
-     * for the book appointments page.
+     * This method binds the necessary event handlers for the book 
+     * appointments page.
      */
     bindEventHandlers : function() {
         /**
          * Event : Selected Provider "Changed"
+         * 
+         * Whenever the provider changes the available appointment
+         * date - time periods must be updated.
          */
         $('#select-provider').change(function() {
             bookAppointment.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
-            bookAppointment.updateConfirmData();
+            bookAppointment.updateConfirmFrame();
         });
         
         /**
@@ -98,21 +123,21 @@ var bookAppointment = {
             var currServiceId = $('#select-service').val();
             $('#select-provider').empty();
 
-            $.each(GlobalVariables.providers, function(indexProvider, provider) {
+            $.each(GlobalVariables.availableProviders, function(indexProvider, provider) {
                 $.each(provider['services'], function(indexService, serviceId) {
-                    // If the current provider is able to provide the selected 
-                    // service, add him to the listbox. 
+                    // If the current provider is able to provide the selected service,
+                    // add him to the listbox. 
                     if (serviceId == currServiceId) { 
                         var optionHtml = '<option value="' + provider['id'] + '">' 
-                            + provider['last_name']  + ' ' + provider['first_name'] 
-                            + '</option>';
+                                + provider['last_name']  + ' ' + provider['first_name'] 
+                                + '</option>';
                         $('#select-provider').append(optionHtml);
                     }
                 });
             });
 
             bookAppointment.getAvailableHours(Date.today().toString('dd-MM-yyyy'));
-            bookAppointment.updateConfirmData();
+            bookAppointment.updateConfirmFrame();
         });
         
         /**
@@ -123,13 +148,27 @@ var bookAppointment = {
          * be perfomed, depending the current wizard step.
          */
         $('.button-next').click(function() {
+            // If we are on the 2nd tab then the user should have 
+            // an appointment hour selected.
+            if ($(this).attr('data-step_index') === '2') {
+                if ($('.selected-hour').length == 0) {
+                    if ($('#select-hour-prompt').length == 0) {
+                        $('#available-hours').append('<br><br>'
+                                + '<strong id="select-hour-prompt" class="text-error">'
+                                + 'Please select an appointment hour before continuing!' 
+                                + '</strong>');
+                    }
+                    return;
+                }
+            }
+            
             // If we are on the 3rd tab then we will need to validate the user's 
             // input before proceeding to the next step.
-            if ($(this).attr('data-step_index') == '3') {
-                if (!bookAppointment.validateCustomerDataForm()) {
+            if ($(this).attr('data-step_index') === '3') {
+                if (!bookAppointment.validateCustomerForm()) {
                     return; // Validation failed, do not continue.
                 } else {
-                    bookAppointment.updateConfirmData();
+                    bookAppointment.updateConfirmFrame();
                 }
             }
             
@@ -139,7 +178,7 @@ var bookAppointment = {
             $(this).parents().eq(1).hide('fade', function() {    
                 $('.active-step').removeClass('active-step');
                 $('#step-' + nextTabIndex).addClass('active-step');
-                $('#book-appointment-' + nextTabIndex).show('fade');
+                $('#wizard-frame-' + nextTabIndex).show('fade');
             });
         });
 
@@ -155,7 +194,7 @@ var bookAppointment = {
             $(this).parents().eq(1).hide('fade', function() {    
                 $('.active-step').removeClass('active-step');
                 $('#step-' + prevTabIndex).addClass('active-step');
-                $('#book-appointment-' + prevTabIndex).show('fade');
+                $('#wizard-frame-' + prevTabIndex).show('fade');
             });
         });
 
@@ -168,7 +207,7 @@ var bookAppointment = {
         $('#available-hours').on('click', '.available-hour', function() {
             $('.selected-hour').removeClass('selected-hour');
             $(this).addClass('selected-hour');
-            bookAppointment.updateConfirmData();
+            bookAppointment.updateConfirmFrame();
         });
     },
     
@@ -183,24 +222,31 @@ var bookAppointment = {
         // Find the selected service duration (it is going to 
         // be send within the "postData" object.
         var selServiceDuration = 15; // Default value of duration (in minutes).
-        $.each(GlobalVariables.services, function(index, service) {
+        $.each(GlobalVariables.availableServices, function(index, service) {
             if (service['id'] == $('#select-service').val()) {
                 selServiceDuration = service['duration']; 
             }
         });
+        
+        // If the manage mode is true then the appointment's start 
+        // date should return as available too.
+        var appointmentId = (bookAppointment.manageMode) 
+                ? GlobalVariables.appointmentData['id'] : undefined;
 
         var postData = {
-            'service_id'         : $('#select-service').val(),
-            'provider_id'        : $('#select-provider').val(),
-            'selected_date'      : selDate,
-            'service_duration'   : selServiceDuration
+            'service_id'        : $('#select-service').val(),
+            'provider_id'       : $('#select-provider').val(),
+            'selected_date'     : selDate,
+            'service_duration'  : selServiceDuration,
+            'manage_mode'       : bookAppointment.manageMode,
+            'appointment_id'    : appointmentId
         };
 
         // Make ajax post request and get the available hours.
         var ajaxurl = GlobalVariables.baseUrl + 'appointments/ajax_get_available_hours';
         jQuery.post(ajaxurl, postData, function(postResponse) {
             ////////////////////////////////////////////////////////////////////////////////
-            console.log('\n\n Get Available Hours Post Response :', postResponse, '\n\n');
+            //console.log('\n\n Get Available Hours Post Response :', postResponse, '\n\n');
             ////////////////////////////////////////////////////////////////////////////////
 
             try {
@@ -209,25 +255,47 @@ var bookAppointment = {
                 //console.log('\n\n Get Available Hours JSON Response :', jsonResponse, '\n\n');
                 ////////////////////////////////////////////////////////////////////////////////
 
-                // Fill the available time div
-                var currColumn = 1;
-                $('#available-hours').html('<div style="width:50px; float:left;"></div>');
-                $.each(jsonResponse, function(index, availableHour) {
-                    if ((currColumn * 10) < (index + 1)) {
-                        currColumn++;
-                        $('#available-hours').append('<div style="width:50px; float:left;"></div>');
+                if (jsonResponse.length > 0) {
+                    // Fill the available time div
+                    var currColumn = 1;
+                    $('#available-hours').html('<div style="width:50px; float:left;"></div>');
+                    
+                    $.each(jsonResponse, function(index, availableHour) {
+                        if ((currColumn * 10) < (index + 1)) {
+                            currColumn++;
+                            $('#available-hours')
+                                    .append('<div style="width:50px; float:left;"></div>');
+                        }
+
+                        $('#available-hours div:eq(' + (currColumn - 1) + ')')
+                                .append('<span class="available-hour">' + availableHour 
+                                + '</span><br/>');
+                    });
+
+                    if (bookAppointment.manageMode) {
+                        // Set the appointment start time as selected.
+                        $('.available-hour').removeClass('selected-hour');
+                        $('.available-hour').filter(function() {
+                            return $(this).text() === Date.parseExact(
+                                    GlobalVariables.appointmentData['start_datetime'],
+                                    'yyyy-MM-dd HH:mm:ss').toString('HH:mm');
+                        }).addClass('selected-hour');
+                    } else {
+                        // Set the first item as selected.
+                        $('.available-hour:eq(0)').addClass('selected-hour');
                     }
-
-                    $('#available-hours div:eq(' + (currColumn - 1) + ')')
-                        .append('<span class="available-hour">' + availableHour + '</span><br/>');
-                });
-
-                // Set the first item as selected.
-                $('.available-hour:eq(0)').addClass('selected-hour');
-                bookAppointment.updateConfirmData();
+                    
+                    bookAppointment.updateConfirmFrame();
+                } else {
+                    $('#available-hours').text('There are no available appointment'
+                            + 'hours for the selected date. Please choose another '
+                            + 'date.');
+                }
+                
             } catch(exception) {
-                GeneralFunctions.displayMessageBox('Unexpected Error', 'An unexpected error occured ' 
-                    + 'during the available hours calculation. Please refresh the page and try again.');
+                GeneralFunctions.displayMessageBox('Unexpected Error', 'An unexpected '
+                        + 'error occured during the available hours calculation. Please '
+                        + 'refresh the page and try again.');
             }
         });
     },
@@ -238,7 +306,7 @@ var bookAppointment = {
      * 
      * @return {bool} Returns the validation result.
      */
-    validateCustomerDataForm : function() {
+    validateCustomerForm : function() {
         var validationResult = true;
         $('.required').css('border', '');
 
@@ -257,7 +325,7 @@ var bookAppointment = {
      * page with the latest customer settigns and input for the appointment 
      * booking.
      */
-    updateConfirmData : function() {
+    updateConfirmFrame : function() {
         /*** SET APPOINTMENT INFO ***/
         var selectedDate = $('#select-date').datepicker('getDate');
         if (selectedDate !== null) {
@@ -303,6 +371,13 @@ var bookAppointment = {
             'id_services'       : $('#select-service').val()
         };
         
+        postData['manage_mode'] = bookAppointment.manageMode;
+        
+        if (bookAppointment.manageMode) {
+            postData['appointment']['id'] = GlobalVariables.appointmentData['id'];
+            postData['customer']['id'] = GlobalVariables.customerData['id'];
+        }
+        
         $('input[name="post_data"]').val(JSON.stringify(postData));
     },
     
@@ -316,7 +391,7 @@ var bookAppointment = {
         // Find selected service duration. 
         var selServiceDuration = undefined;
         
-        $.each(GlobalVariables.services, function(index, service) {
+        $.each(GlobalVariables.availableServices, function(index, service) {
             if (service.id == $('#select-service').val()) {
                 selServiceDuration = service.duration;
                 return; // Stop searching ... 
@@ -336,6 +411,47 @@ var bookAppointment = {
         }
         
         return endDatetime.toString('yyyy-MM-dd HH:mm:ss');
+    },
+    
+    /**
+     * This method applies the appointment's data to the wizard so 
+     * that the user can start making changes on an existing record.
+     * 
+     * @param {object} appointmentData Selected appointment's data.
+     * @param {object} providerData Selected provider's data.
+     * @param {object} customerData Selected customer's data.
+     * @returns {bool} Returns the operation result.
+     */
+    applyAppointmentData : function(appointmentData, providerData, customerData) {
+        try {
+            // Select Service & Provider
+            $('#select-service').val(appointmentData['id_services']).trigger('change');
+            $('#select-provider').val(appointmentData['id_users_provider']);
+            
+            // Set Appointment Date
+            $('#select-date').datepicker('setDate', Date.parseExact(
+                    appointmentData['start_datetime'], 'yyyy-MM-dd HH:mm:ss'));
+            bookAppointment.getAvailableHours($('#select-date').val());
+            
+            // Apply Customer's Data
+            $('#last-name').val(customerData['last_name']);
+            $('#first-name').val(customerData['first_name']);
+            $('#email').val(customerData['email']);
+            $('#phone-number').val(customerData['phone_number']);
+            
+            $('#address').val(customerData['address']);
+            $('#city').val(customerData['city']);
+            $('#zip-code').val(customerData['zip_code']);
+            var appointmentNotes = (appointmentData['notes'] !== null) ? appointmentData['notes'] : '';
+            $('#notes').val(appointmentNotes);
+            
+            bookAppointment.updateConfirmFrame();
+            
+            return true;
+        } catch(exc) {
+            console.log(exc);
+            return false;
+        }
     }
 }
@@ -353,7 +469,7 @@ var bookAppointment = {
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 18:38:05 GMT+0300 (EEST) + Documentation generated by JSDoc 3.2.0-dev on Sat Jun 08 2013 12:49:54 GMT+0300 (EEST)
diff --git a/doc/code-docs/js/functions..html b/doc/code-docs/js/functions..html index 910dc27e..0be7c93b 100644 --- a/doc/code-docs/js/functions..html +++ b/doc/code-docs/js/functions..html @@ -115,7 +115,7 @@ end of the application.
- Documentation generated by JSDoc 3.2.0-dev on Mon May 20 2013 18:38:06 GMT+0300 (EEST) + Documentation generated by JSDoc 3.2.0-dev on Sat Jun 08 2013 12:49:55 GMT+0300 (EEST)
diff --git a/doc/code-docs/js/general_functions.js.html b/doc/code-docs/js/general_functions.js.html index bae1137b..9aa75b87 100644 --- a/doc/code-docs/js/general_functions.js.html +++ b/doc/code-docs/js/general_functions.js.html @@ -109,6 +109,26 @@ GeneralFunctions.centerElementOnPage = function(elementHandle) { }); }); $(window).resize(); +} + +/** + * This function retrieves a parameter from a "GET" formed url. + * + * @link http://www.netlobo.com/url_query_string_javascript.html + * + * @param {string} url The selected url. + * @param {string} name The parameter name. + * @returns {String} Returns the parameter value. + */ +GeneralFunctions.getUrlParameter = function(url, parameterName) { + parameterName = parameterName.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); + var regexS = "[\\#&]"+parameterName+"=([^&#]*)"; + var regex = new RegExp( regexS ); + var results = regex.exec( url ); + if( results == null ) + return ""; + else + return results[1]; }
@@ -125,7 +145,7 @@ GeneralFunctions.centerElementOnPage = function(elementHandle) {
diff --git a/doc/code-docs/js/index.html b/doc/code-docs/js/index.html index c7094b53..422cba15 100644 --- a/doc/code-docs/js/index.html +++ b/doc/code-docs/js/index.html @@ -54,7 +54,7 @@
diff --git a/doc/code-docs/php/class-Appointments.html b/doc/code-docs/php/class-Appointments.html index 66642888..fce4e140 100644 --- a/doc/code-docs/php/class-Appointments.html +++ b/doc/code-docs/php/class-Appointments.html @@ -105,7 +105,7 @@ CI_Controller - Located at appointments.php
+ Located at appointments.php
@@ -123,20 +123,71 @@ CI_Controller
# - index( ) + index( string $appointment_hash = '' )
-

This page displays the book appointment wizard for the customers.

+

Default callback method of the application.

+
+ + + + + public + + + + + +
+ # + cancel( string $appointment_hash ) + +
+ +

Cancel an existing appointment.

+ +
+ +