From 756114685be5e122d8f3a943d2e15307e369b897 Mon Sep 17 00:00:00 2001 From: "alextselegidis@gmail.com" Date: Fri, 5 Jul 2013 08:39:52 +0000 Subject: [PATCH] Created backend customers page. --- src/application/controllers/backend.php | 54 +++++++- .../helpers/custom_exceptions_helper.php | 4 +- src/application/views/backend/customers.php | 37 +++++- src/application/views/backend/header.php | 2 +- src/assets/js/backend_calendar.js | 77 ++++++++++- src/assets/js/backend_customers.js | 121 ++++++++++++++++++ src/configuration.php | 4 +- 7 files changed, 281 insertions(+), 18 deletions(-) create mode 100644 src/assets/js/backend_customers.js diff --git a/src/application/controllers/backend.php b/src/application/controllers/backend.php index 0fbe1d90..17b45254 100644 --- a/src/application/controllers/backend.php +++ b/src/application/controllers/backend.php @@ -16,8 +16,7 @@ class Backend extends CI_Controller { $this->load->model('Services_Model'); $this->load->model('Settings_Model'); - // Display the main backend page. - $view_data['base_url'] = $this->config->item('base_url'); + $view_data['base_url'] = $this->config->item('base_url'); $view_data['book_advance_timeout'] = $this->Settings_Model->get_setting('book_advance_timeout'); $view_data['company_name'] = $this->Settings_Model->get_setting('company_name'); $view_data['available_providers'] = $this->Providers_Model->get_available_providers(); @@ -28,8 +27,28 @@ class Backend extends CI_Controller { $this->load->view('backend/footer', $view_data); } + /** + * Display the backend customers page + * + * In this page the user can manage all the customer records of the system. + */ public function customers() { - echo '

Not implemented yet.

'; + // @task Require user to be logged in the application. + + $this->load->model('Providers_Model'); + $this->load->model('Customers_Model'); + $this->load->model('Services_Model'); + $this->load->model('Settings_Model'); + + $view_data['base_url'] = $this->config->item('base_url'); + $view_data['company_name'] = $this->Settings_Model->get_setting('company_name'); + $view_data['customers'] = $this->Customers_Model->get_batch(); + $view_data['available_providers'] = $this->Providers_Model->get_available_providers(); + $view_data['available_services'] = $this->Services_Model->get_available_services(); + + $this->load->view('backend/header', $view_data); + $this->load->view('backend/customers', $view_data); + $this->load->view('backend/footer', $view_data); } public function services() { @@ -327,6 +346,35 @@ class Backend extends CI_Controller { )); } } + + /** + * [AJAX] Filter the customer records with the given key string. + * + * @param string $_POST['key'] The filter key string + * @return array Returns the search results. + */ + public function ajax_filter_customers() { + try { + $this->load->model('Customers_Model'); + + $key = $_POST['key']; //$this->db->escape($_POST['key']); + + $where_clause = + 'first_name LIKE "%' . $key . '%" OR ' . + 'last_name LIKE "%' . $key . '%" OR ' . + 'email LIKE "%' . $key . '%" OR ' . + 'phone_number LIKE "%' . $key . '%" OR ' . + 'address LIKE "%' . $key . '%" OR ' . + 'city LIKE "%' . $key . '%" OR ' . + 'zip_code LIKE "%' . $key . '%" '; + + echo json_encode($this->Customers_Model->get_batch($where_clause)); + } catch(Exception $exc) { + echo json_encode(array( + 'exceptions' => array($exc) + )); + } + } } /* End of file backend.php */ diff --git a/src/application/helpers/custom_exceptions_helper.php b/src/application/helpers/custom_exceptions_helper.php index b5fdefdd..b0cd60b6 100644 --- a/src/application/helpers/custom_exceptions_helper.php +++ b/src/application/helpers/custom_exceptions_helper.php @@ -23,9 +23,11 @@ class SyncException extends Exception {} /** * Print an exception to an HTML text. * - * This method is used to display exceptions in a way that is userful and easy + * This method is used to display exceptions in a way that is useful and easy * for the user to see. It uses the Bootstrap CSS accordion markup to display * the message and when the user clicks on it the exception trace will be revealed. + * 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. * @return string Returns the html markup of the exception. diff --git a/src/application/views/backend/customers.php b/src/application/views/backend/customers.php index b6eddc13..c984488e 100644 --- a/src/application/views/backend/customers.php +++ b/src/application/views/backend/customers.php @@ -1,7 +1,32 @@ -assets/js/libs/jquery/jquery-ui-timepicker-addon.js"> + + + + -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -?> +
+
+
+ + +
+
+
+ +
+ +
+
\ No newline at end of file diff --git a/src/application/views/backend/header.php b/src/application/views/backend/header.php index e9183613..ad2dc23e 100644 --- a/src/application/views/backend/header.php +++ b/src/application/views/backend/header.php @@ -73,7 +73,7 @@
- + Calendar diff --git a/src/assets/js/backend_calendar.js b/src/assets/js/backend_calendar.js index d22b5200..caceb52d 100644 --- a/src/assets/js/backend_calendar.js +++ b/src/assets/js/backend_calendar.js @@ -111,13 +111,18 @@ var BackendCalendar = { // disabled. if ($('#select-filter-item option:selected').attr('type') === BackendCalendar.FILTER_TYPE_SERVICE) { - $('#calendar-actions').hide(); + $('#google-sync, #enable-sync, #insert-appointment, #insert-unavailable') + .prop('disabled', true); + // @task Hide the unavailable periods. } else { - $('#calendar-actions').show(); + + $('#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') { + if ($('#select-filter-item option:selected').attr('google-sync') === 'true') { $('#enable-sync').addClass('btn-success enabled'); $('#enable-sync i').addClass('icon-white'); $('#enable-sync span').text('Disable Sync'); @@ -485,6 +490,13 @@ var BackendCalendar = { return; } + if (response.warnings) { + response.warnings = GeneralFunctions.parseExceptions(response.exceptions); + GeneralFunctions.displayMessageBox('Unexpected Warnings', 'The operation was ' + + 'completed but the following warnings appeared.'); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings)); + } + // Add the appointments to the calendar. var calendarEvents = new Array(); @@ -505,6 +517,37 @@ var BackendCalendar = { calendarHandle.fullCalendar('removeEvents'); calendarHandle.fullCalendar('addEventSource', calendarEvents); + + // Add the provider's unavailable time periods. + $.each(GlobalVariables.availalbeProviders, function(index, provider) { + if (provider['id'] == recordId) { + var workingPlan = provider['settings']['working_plan']; + var start, end; + var calStart = ''; + var calEnd = ''; + + $.each(workingPlan, function(index, workingDay) { + // Add before the work start an unavailable time period. + start = ''; + end = ''; + BackendCalendar.addUnavailableTimePeriod(start, end); + + // Add after the work end an unavailable time period. + + + // Add the break time periods. + + + // @task Add custom unavailable time periods. + + }); + + return; // break $.each() + } + }); + + + }, 'json'); }, @@ -972,10 +1015,34 @@ var BackendCalendar = { } return true; - } catch(exc) { dialog.find('#modal-message').addClass('alert-error').text(exc).show('fade'); 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. + */ + addUnavailableTimePeriod: function(start, end) { + try { + var slotsCount = $('#calendar').find('.fc-agenda-slots tr').length; + var slotsPerHour = slotsCount / 24; + + var startSlot = start.toString('H'); + var endSlot = end.toString('H') * slotsPerHour; // Include all the slots on the calculation + + $('#calendar .fc-agena-slots tr').slice(startSlot, endSlot) + .css('background-color', '#AAA'); + + return true; + } catch(exc) { + console.log('Add Unavailable Time Period Exc:', exc); + return false; + } } }; \ No newline at end of file diff --git a/src/assets/js/backend_customers.js b/src/assets/js/backend_customers.js new file mode 100644 index 00000000..48b17ec4 --- /dev/null +++ b/src/assets/js/backend_customers.js @@ -0,0 +1,121 @@ +/** + * Backend Customers javasript namespace. Contains the main functionality + * of the backend customers page. If you need to use this namespace in a + * different page, do not bind the default event handlers during initialization. + * + * @namespace Backend Customers + */ + +var BackendCustomers = { + /** + * This method initializes the backend customers page. If you use this namespace + * in a different page do not use this method. + * + * @param {bool} bindDefaultEventHandlers Whether to bind the default event handlers + * or not. + */ + initialize: function(bindDefaultEventHandlers) { + if (bindDefaultEventHandlers === undefined) { + bindDefaultEventHandlers = false; // default value + } + + // :: INITIALIZE BACKEND CUSTOMERS PAGE + BackendCustomers.filterCustomers(''); + + // :: BIND DEFAULT EVENT HANDLERS (IF NEEDED) + if (bindDefaultEventHandlers) { + BackendCustomers.bindEventHandlers(); + } + }, + + bindEventHandlers: function() { + + + + }, + + /** + * This method displays the customer data on the right part of the page. + * When a customer is selected the user can make changes and update the + * customer record. + * + * @param {int} customerId Selected customer's record id. + */ + displayCustomer: function(customerId) { + + }, + + /** + * This method makes an ajax call to the server and save the changes of + * an existing customer record, or inserts a new customer row when on insert + * mode. + * + * NOTICE: User the "deleteCustomer" method to delete a customer record. + * + * @param {object} customerData Contains the customer data. If "id" is not + * provided then the record is going to be inserted. + */ + saveCustomer: function(customerData) { + + }, + + /** + * This method makes an ajax call to the server and deletes the selected + * customer record. + * + * @param {int} customerId The customer record id to be deleted. + */ + deleteCustomer: function(customerId) { + + }, + + /** + * This method filters the system registered customers. Pass an empty string + * to display all customers. + * + * @param {string} key The filter key string. + */ + filterCustomers: function(key) { + var postUrl = GlobalVariables.baseUrl + 'backend/ajax_filter_customers'; + var postData = { 'key': key }; + $.post(postUrl, postData, function(response) { + if (response.exceptions) { + response.exceptions = GeneralFunctions.parseExcpetions(response.exceptions); + GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately the ' + + 'filter operation could not complete successfully. The following ' + + 'issues occured.'); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions)); + return; + } + + if (response.warnings) { + response.warnings = GeneralFunctions.parseExcpetions(response.warnings); + GeneralFunctions.displayMessageBox('Unexpected Warnings', 'The filter operation ' + + 'complete with the following warnings.'); + $('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings)); + } + + $.each(response, function(index, customer) { + var html = + '
' + + '' + + customer['first_name'] + ' ' + customer['last_name'] + + '
' + + '' + customer['email'] + ' | ' + + '' + customer['phone_number'] + '
' + + '
'; + $('#filter-results').append(html); + }); + }, 'json'); + }, + + /** + * This method validates the main customer form of the page. There are certain + * rules that the record must fullfil before getting into the system database. + * + * @return {bool} Returns the validation result. + */ + validateCustomerForm: function() { + + } +}; \ No newline at end of file diff --git a/src/configuration.php b/src/configuration.php index 7ebebd4e..146b204a 100644 --- a/src/configuration.php +++ b/src/configuration.php @@ -1,13 +1,13 @@