Created backend customers page.

This commit is contained in:
alextselegidis@gmail.com 2013-07-05 08:39:52 +00:00
parent 4b52ccfd40
commit 756114685b
7 changed files with 281 additions and 18 deletions

View file

@ -16,8 +16,7 @@ class Backend extends CI_Controller {
$this->load->model('Services_Model'); $this->load->model('Services_Model');
$this->load->model('Settings_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['book_advance_timeout'] = $this->Settings_Model->get_setting('book_advance_timeout');
$view_data['company_name'] = $this->Settings_Model->get_setting('company_name'); $view_data['company_name'] = $this->Settings_Model->get_setting('company_name');
$view_data['available_providers'] = $this->Providers_Model->get_available_providers(); $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); $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() { public function customers() {
echo '<h1>Not implemented yet.</h1>'; // @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() { 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 */ /* End of file backend.php */

View file

@ -23,9 +23,11 @@ class SyncException extends Exception {}
/** /**
* Print an exception to an HTML text. * 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 * 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. * 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. * @param Exception $exception The exception to be displayed.
* @return string Returns the html markup of the exception. * @return string Returns the html markup of the exception.

View file

@ -1,7 +1,32 @@
<?php <script type="text/javascript"
src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery-ui-timepicker-addon.js"></script>
<script type="text/javascript"
src="<?php echo $base_url; ?>assets/js/backend_customers.js"></script>
<script type="text/javascript">
var GlobalVariables = {
'availableProviders': <?php echo json_encode($available_providers); ?>,
'availableServices': <?php echo json_encode($available_services); ?>,
'baseUrl': <?php echo '"' . $base_url . '"'; ?>,
'customers': <?php echo json_encode($customers); ?>
};
$(document).ready(function() {
BackendCustomers.initialize(true);
});
</script>
/* <div id="customers-page" class="row-fluid">
* To change this template, choose Tools | Templates <div class="span4">
* and open the template in the editor. <div class="filter-customers">
*/ <label for="filter-input">Filter</label>
?> <input type="text" id="filter-key" />
<div id="filter-results"></div>
</div>
</div>
<div class="span8">
</div>
</div>

View file

@ -73,7 +73,7 @@
<div id="header-menu"> <div id="header-menu">
<?php // CALENDAR MENU ITEM <?php // CALENDAR MENU ITEM
// ------------------------------------------------------ ?> // ------------------------------------------------------ ?>
<a href="<?php echo $base_url; ?>backend/calendar" class="menu-item"> <a href="<?php echo $base_url; ?>backend" class="menu-item">
Calendar Calendar
</a> </a>

View file

@ -111,13 +111,18 @@ var BackendCalendar = {
// disabled. // disabled.
if ($('#select-filter-item option:selected').attr('type') if ($('#select-filter-item option:selected').attr('type')
=== BackendCalendar.FILTER_TYPE_SERVICE) { === BackendCalendar.FILTER_TYPE_SERVICE) {
$('#calendar-actions').hide(); $('#google-sync, #enable-sync, #insert-appointment, #insert-unavailable')
.prop('disabled', true);
// @task Hide the unavailable periods.
} else { } 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 // If the user has already the sync enabled then apply the proper
// style changes. // style changes.
if ($('#select-filter-item option:selected').attr('google-sync') if ($('#select-filter-item option:selected').attr('google-sync') === 'true') {
=== 'true') {
$('#enable-sync').addClass('btn-success enabled'); $('#enable-sync').addClass('btn-success enabled');
$('#enable-sync i').addClass('icon-white'); $('#enable-sync i').addClass('icon-white');
$('#enable-sync span').text('Disable Sync'); $('#enable-sync span').text('Disable Sync');
@ -485,6 +490,13 @@ var BackendCalendar = {
return; 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. // Add the appointments to the calendar.
var calendarEvents = new Array(); var calendarEvents = new Array();
@ -505,6 +517,37 @@ var BackendCalendar = {
calendarHandle.fullCalendar('removeEvents'); calendarHandle.fullCalendar('removeEvents');
calendarHandle.fullCalendar('addEventSource', calendarEvents); 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'); }, 'json');
}, },
@ -972,10 +1015,34 @@ var BackendCalendar = {
} }
return true; return true;
} catch(exc) { } catch(exc) {
dialog.find('#modal-message').addClass('alert-error').text(exc).show('fade'); dialog.find('#modal-message').addClass('alert-error').text(exc).show('fade');
return false; 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;
}
} }
}; };

View file

@ -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 =
'<div class="customer-data" data-id="' + customer['id'] + '">' +
'<strong>' +
customer['first_name'] + ' ' + customer['last_name'] +
'</strong><br>' +
'<span>' + customer['email'] + '</span> | ' +
'<span>' + customer['phone_number'] + '</span><hr>' +
'</div>';
$('#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() {
}
};

View file

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