mirror of
https://github.com/alextselegidis/easyappointments.git
synced 2024-12-22 06:32:24 +03:00
Αλλαγές στα υπάρχον αρχεία που σχετίζονται με την κράτηση ραντεβού έτσι ώστε να είναι εφικτή η δημιουργία link, τα οποία θα επιτρέπουν στους πελάτες να πραγματοποιούν αλλαγές στα ραντεβού που έχουν καταχωρήσει.
This commit is contained in:
parent
2112164b4a
commit
f9a6b20052
16 changed files with 3552 additions and 180 deletions
|
@ -1,53 +1,146 @@
|
|||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class Appointments extends CI_Controller {
|
||||
/**
|
||||
* This page displays the book appointment wizard
|
||||
* for the customers.
|
||||
*/
|
||||
public function index() {
|
||||
if (strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {
|
||||
// Display the appointment booking page to the customer.
|
||||
// Get business name.
|
||||
/**
|
||||
* Default callback method of the application.
|
||||
*
|
||||
* This method creates the appointment book wizard. If an appointment hash
|
||||
* is provided then it means that the customer followed the appointment
|
||||
* manage link that was send with the book success email.
|
||||
*
|
||||
* @param string $appointment_hash The db appointment hash of an existing
|
||||
* record.
|
||||
*/
|
||||
public function index($appointment_hash = '') {
|
||||
if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') {
|
||||
$this->load->model('Settings_Model');
|
||||
$view_data['company_name'] = $this->Settings_Model->get_setting('company_name');
|
||||
|
||||
// Get the available services and providers.
|
||||
$this->load->model('Services_Model');
|
||||
$view_data['available_services'] = $this->Services_Model->get_available_services();
|
||||
|
||||
$this->load->model('Providers_Model');
|
||||
$view_data['available_providers'] = $this->Providers_Model->get_available_providers();
|
||||
|
||||
$company_name = $this->Settings_Model->get_setting('company_name');
|
||||
$available_services = $this->Services_Model->get_available_services();
|
||||
$available_providers = $this->Providers_Model->get_available_providers();
|
||||
|
||||
// If an appointment hash is provided then it means that the customer
|
||||
// is trying to edit a registered record.
|
||||
if ($appointment_hash !== ''){
|
||||
// Load the appointments data and set the manage mode of the page.
|
||||
$this->load->model('Appointments_Model');
|
||||
$this->load->model('Customers_Model');
|
||||
|
||||
$manage_mode = TRUE;
|
||||
|
||||
$appointment_data = $this->Appointments_Model
|
||||
->get_batch(array('hash' => $appointment_hash))[0];
|
||||
$provider_data = $this->Providers_Model
|
||||
->get_row($appointment_data['id_users_provider']);
|
||||
$customer_data = $this->Customer_Model
|
||||
->get_row($appointment_data['id_users_customer']);
|
||||
} else {
|
||||
// The customer is going to book an 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();
|
||||
}
|
||||
|
||||
// Load the book appointment view.
|
||||
$view_data = array (
|
||||
'available_services' => $available_services,
|
||||
'available_providers' => $available_providers,
|
||||
'company_name' => $company_name,
|
||||
'manage_mode' => $manage_mode,
|
||||
'appointment_data' => $appointment_data,
|
||||
'provider_data' => $provider_data,
|
||||
'customer_data' => $customer_data
|
||||
);
|
||||
$this->load->view('appointments/book', $view_data);
|
||||
} else {
|
||||
$post_data = json_decode($_POST['post_data'], true);
|
||||
|
||||
// Add customer
|
||||
// The page is a post-back. Register the appointment and send
|
||||
// notification emails to the provider and the customer that are
|
||||
// related to the appointment.
|
||||
$post_data = json_decode($_POST['post_data'], true);
|
||||
$appointment_data = $post_data['appointment'];
|
||||
$customer_data = $post_data['customer'];
|
||||
|
||||
$this->load->model('Customers_Model');
|
||||
$customer_id = $this->Customers_Model->add($post_data['customer']);
|
||||
|
||||
// Add appointment
|
||||
$post_data['appointment']['id_users_customer'] = $customer_id;
|
||||
$this->load->model('Appointments_Model');
|
||||
$view_data['appointment_id'] = $this->Appointments_Model->add($post_data['appointment']);
|
||||
|
||||
|
||||
$customer_id = $this->Customers_Model->add($customer_data);
|
||||
$appointment_data['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']);
|
||||
|
||||
// Send an email to the customer with the appointment info.
|
||||
$this->load->library('Notifications');
|
||||
try {
|
||||
$this->notifications->send_book_success($post_data['customer'], $post_data['appointment']);
|
||||
$this->notifications->send_new_appointment($post_data['customer'], $post_data['appointment']);
|
||||
$this->notifications->send_book_success($customer_data, $appointment_data);
|
||||
$this->notifications->send_new_appointment($customer_data, $appointment_data);
|
||||
} catch (NotificationException $not_exc) {
|
||||
$view_data['notification_error'] = '<br><br><pre>An unexpected error occured while sending '
|
||||
. 'you an email. Please backup the appointment details so that you can restore them '
|
||||
. 'later. <br><br>Error:<br>' . $not_exc->getMessage() . '</pre>';
|
||||
$view_data['notification_error'] = '<br><br>'
|
||||
. '<pre>An unexpected error occured while sending you an '
|
||||
. 'email. Please backup the appointment details so that '
|
||||
. 'you can restore them later. <br><br>Error: <br>'
|
||||
. $not_exc->getMessage() . '</pre>';
|
||||
}
|
||||
|
||||
|
||||
// Load the book appointment view.
|
||||
$view_data['appointment_id'] = $appointment_data['id'];
|
||||
$this->load->view('appointments/book_success', $view_data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the view - manage screen of an external
|
||||
* appointment link.
|
||||
*
|
||||
* This method loads the page that is going to be displayed
|
||||
* whenever a customer, or a provider clicks on the email link
|
||||
* that enables him to preview and make changes to the selected
|
||||
* appointment.
|
||||
*
|
||||
* @param string $user_type Link user type (one of the
|
||||
* DB_SLUG_CUSTOMER, ... constants).
|
||||
* @param string $appointment_hash the appointment db hash. This
|
||||
* is used to identify the appointment record.
|
||||
*
|
||||
*/
|
||||
public function external_link($user_type, $appointment_hash) {
|
||||
if (strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {
|
||||
// Prepare and display the external manage view page.
|
||||
$this->load->model('Appointments_Model');
|
||||
$this->load->model('Providers_Model');
|
||||
$this->load->model('Customers_Model');
|
||||
$this->load->model('Services_Model');
|
||||
|
||||
$appointment_data = $this->Appointments_Model
|
||||
->get_batch(array('hash' => $appointment_hash))[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']);
|
||||
|
||||
$available_providers = $this->Providers_Model->get_available_providers();
|
||||
$available_services = $this->Services_Model->get_available_services();
|
||||
|
||||
$view_data = array(
|
||||
'appointment_data' => $appointment_data,
|
||||
'customer_data' => $customer_data,
|
||||
'provider_data' => $provider_data,
|
||||
'user_type' => $user_type,
|
||||
'available_providers' => $available_providers,
|
||||
'available_services' => $available_services
|
||||
);
|
||||
$this->load->view('appointments/external_manage', $view_data);
|
||||
} else {
|
||||
// The external manage page was posted back. Save the
|
||||
// changes of the user.
|
||||
|
||||
// @task Save user changes.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [AJAX] Get the available appointment hours for the given date.
|
||||
|
@ -69,12 +162,20 @@ class Appointments extends CI_Controller {
|
|||
$working_plan = json_decode($this->Providers_Model
|
||||
->get_value('working_plan', $_POST['provider_id']), true);
|
||||
|
||||
$reserved_appointments = $this->Appointments_Model->get_batch(
|
||||
array(
|
||||
'DATE(start_datetime)' => date('Y-m-d', strtotime($_POST['selected_date'])),
|
||||
'id_users_provider' => $_POST['provider_id'],
|
||||
'id_services' => $_POST['service_id']
|
||||
));
|
||||
$where_clause = array(
|
||||
'DATE(start_datetime)' => date('Y-m-d', strtotime($_POST['selected_date'])),
|
||||
'id_users_provider' => $_POST['provider_id'],
|
||||
'id_services' => $_POST['service_id']
|
||||
);
|
||||
|
||||
if ($_POST['manage_mode']) {
|
||||
// Current record id shouldn't be included as reserved time,
|
||||
// whent the manage mode is true.
|
||||
$where_clause['id !='] = $_POST['appointment_id'];
|
||||
}
|
||||
|
||||
$reserved_appointments = $this->Appointments_Model->get_batch($where_clause);
|
||||
|
||||
|
||||
// Find the empty spaces on the plan. The first split between
|
||||
// the plan is due to a break (if exist). After that every reserved
|
||||
|
@ -109,7 +210,7 @@ class Appointments extends CI_Controller {
|
|||
'end' => $sel_date_working_plan['end']
|
||||
);
|
||||
}
|
||||
|
||||
// PROBLEM
|
||||
// Break the empty spaces with the reserved appointments.
|
||||
$empty_spaces_with_appointments = array();
|
||||
if (count($reserved_appointments) > 0) {
|
||||
|
@ -133,10 +234,27 @@ class Appointments extends CI_Controller {
|
|||
'end' => $space_end
|
||||
);
|
||||
} else {
|
||||
$empty_spaces_with_appointments[] = array(
|
||||
'start' => $space_start,
|
||||
'end' => $space_end
|
||||
);
|
||||
// Check if there are any other appointments between this
|
||||
// time space. If not, it is going to be added as it is.
|
||||
$found = FALSE;
|
||||
foreach($reserved_appointments as $appt) {
|
||||
$appt_start = date('H:i', strtotime($appt['start_datetime']));
|
||||
$appt_end = date('H:i', strtotime($appt['end_datetime']));
|
||||
if ($space_start < $appt_start && $space_end > $appt_end) {
|
||||
$found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// It is also necessary to check that this time period doesn't
|
||||
// already exist in the "$empty_spaces_with_appointments" array.
|
||||
$empty_space = array(
|
||||
'start' => $space_start,
|
||||
'end' => $space_end
|
||||
);
|
||||
$already_exist = in_array($empty_space, $empty_spaces_with_appointments);
|
||||
if ($found === FALSE && $already_exist === FALSE) {
|
||||
$empty_spaces_with_appointments[] = $empty_space;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ class Unit_tests extends CI_Driver_Library {
|
|||
*/
|
||||
public function run_library_tests($output_report = true) {
|
||||
// @task Implement unit tests for the libraries.
|
||||
|
||||
|
||||
if ($output_report) {
|
||||
$this->CI->output->append_output($this->CI->unit->report());
|
||||
}
|
||||
|
|
|
@ -74,8 +74,9 @@ class Unit_tests_appointments_model extends CI_Driver {
|
|||
|
||||
// Check if the record is the one that was inserted.
|
||||
$db_data = $this->CI->db->get_where('ea_appointments', array('id' => $appointment_data['id']))->row_array();
|
||||
unset($db_data['hash']); // This should not be included because is generate when the record is inserted.
|
||||
$this->CI->unit->run($appointment_data, $db_data, 'Test if add() appointment (insert operation) has successfully inserted a record.');
|
||||
|
||||
|
||||
// Delete inserted record.
|
||||
$this->CI->db->delete('ea_appointments', array('id' => $appointment_data['id']));
|
||||
}
|
||||
|
@ -355,7 +356,7 @@ class Unit_tests_appointments_model extends CI_Driver {
|
|||
$appointment_data = array(
|
||||
'start_datetime' => '2013-05-01 12:30:00',
|
||||
'end_datetime' => '2013-05-01 13:00:00',
|
||||
'notes' => 'Some notes right here...',
|
||||
'notes' => 'Some notes right here...',
|
||||
'id_users_provider' => $this->provider_id,
|
||||
'id_users_customer' => $this->customer_id,
|
||||
'id_services' => $this->service_id
|
||||
|
@ -407,6 +408,7 @@ class Unit_tests_appointments_model extends CI_Driver {
|
|||
'start_datetime' => '2013-05-01 12:30:00',
|
||||
'end_datetime' => '2013-05-01 13:00:00',
|
||||
'notes' => 'Some notes right here...',
|
||||
'hash' => '91de2d31f5cbb6d26a5b1b3e710d38d1',
|
||||
'id_users_provider' => $this->provider_id,
|
||||
'id_users_customer' => $this->customer_id,
|
||||
'id_services' => $this->service_id
|
||||
|
|
|
@ -120,7 +120,7 @@ class Unit_tests_customers_model extends CI_Driver {
|
|||
$has_thrown_exception = TRUE;
|
||||
}
|
||||
|
||||
$this->CI->unit->run($has_thrown_exception, TRUE, 'Test add() customer with invalid email address');
|
||||
$this->CI->unit->run($has_thrown_exception, TRUE, 'Test add() customer with invalid email address.');
|
||||
}
|
||||
|
||||
private function test_add_missing_no_last_name() {
|
||||
|
|
2934
src/application/libraries/external/class.phpmailer.php
vendored
Normal file
2934
src/application/libraries/external/class.phpmailer.php
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -7,7 +7,7 @@ require_once dirname(__FILE__) . '/external/class.phpmailer.php';
|
|||
* on the system.
|
||||
*
|
||||
* Custom system settings for the notification section are loaded
|
||||
* during the execution of the class methods.
|
||||
* during the execution of each class methods.
|
||||
*/
|
||||
class Notifications {
|
||||
private $CI;
|
||||
|
@ -29,8 +29,8 @@ class Notifications {
|
|||
* @param array $replace_array Array that contains the variables
|
||||
* to be replaced.
|
||||
* @param string $email_html The email template hmtl.
|
||||
* @return string Returns the new email html that contain the variables
|
||||
* of the $replace_array.
|
||||
* @return string Returns the new email html that contain the
|
||||
* variables of the $replace_array.
|
||||
*/
|
||||
private function replace_template_variables($replace_array, $email_html) {
|
||||
foreach($replace_array as $var=>$value) {
|
||||
|
@ -58,17 +58,20 @@ class Notifications {
|
|||
$this->CI->load->model('Services_Model');
|
||||
$this->CI->load->model('Settings_Model');
|
||||
|
||||
$provider_data = $this->CI->Providers_Model->get_row($appointment_data['id_users_provider']);
|
||||
$service_data = $this->CI->Services_Model->get_row($appointment_data['id_services']);
|
||||
$provider_data = $this->CI->Providers_Model
|
||||
->get_row($appointment_data['id_users_provider']);
|
||||
$service_data = $this->CI->Services_Model
|
||||
->get_row($appointment_data['id_services']);
|
||||
|
||||
$replace_array = array(
|
||||
'$appointment_service' => $service_data['name'],
|
||||
'$appointment_service' => $service_data['name'],
|
||||
'$appointment_provider' => $provider_data['first_name'] . ' ' . $provider_data['last_name'],
|
||||
'$appointment_date' => date('d/m/Y H:i', strtotime($appointment_data['start_datetime'])),
|
||||
'$appointment_date' => date('d/m/Y H:i', strtotime($appointment_data['start_datetime'])),
|
||||
'$appointment_duration' => $service_data['duration'] . ' minutes',
|
||||
'$company_link' => $this->CI->Settings_Model->get_setting('company_link'),
|
||||
'$company_name' => $this->CI->Settings_Model->get_setting('company_name'),
|
||||
'$customer_name' => $customer_data['first_name'] . ' ' . $customer_data['last_name']
|
||||
'$appointment_link' => $this->CI->config->item('base_url') . $appointment_data['hash'],
|
||||
'$company_link' => $this->CI->Settings_Model->get_setting('company_link'),
|
||||
'$company_name' => $this->CI->Settings_Model->get_setting('company_name'),
|
||||
'$customer_name' => $customer_data['first_name'] . ' ' . $customer_data['last_name']
|
||||
);
|
||||
|
||||
$email_html = file_get_contents(dirname(dirname(__FILE__)) . '/views/emails/book_success.php');
|
||||
|
@ -105,7 +108,6 @@ class Notifications {
|
|||
* @return bool Returns the operation result.
|
||||
*/
|
||||
public function send_new_appointment($customer_data, $appointment_data) {
|
||||
$this->CI =& get_instance();
|
||||
$this->CI->load->model('Providers_Model');
|
||||
$this->CI->load->model('Services_Model');
|
||||
$this->CI->load->model('Settings_Model');
|
||||
|
@ -114,31 +116,33 @@ class Notifications {
|
|||
$service_data = $this->CI->Services_Model->get_row($appointment_data['id_services']);
|
||||
|
||||
$replace_array = array(
|
||||
'$appointment_service' => $service_data['name'],
|
||||
'$appointment_service' => $service_data['name'],
|
||||
'$appointment_provider' => $provider_data['first_name'] . ' ' . $provider_data['last_name'],
|
||||
'$appointment_date' => date('d/m/Y H:i', strtotime($appointment_data['start_datetime'])),
|
||||
'$appointment_date' => date('d/m/Y H:i', strtotime($appointment_data['start_datetime'])),
|
||||
'$appointment_duration' => $service_data['duration'] . ' minutes',
|
||||
'$company_link' => $this->CI->Settings_Model->get_setting('company_link'),
|
||||
'$company_name' => $this->CI->Settings_Model->get_setting('company_name'),
|
||||
'$customer_name' => $customer_data['first_name'] . ' ' . $customer_data['last_name'],
|
||||
'$customer_email' => $customer_data['email'],
|
||||
'$customer_phone' => $customer_data['phone_number'],
|
||||
'$customer_address' => $customer_data['address']
|
||||
'$appointment_link' => $this->CI->config->item('base_url') . 'appointments/admin/' . $appointment_data['hash'],
|
||||
'$company_link' => $this->CI->Settings_Model->get_setting('company_link'),
|
||||
'$company_name' => $this->CI->Settings_Model->get_setting('company_name'),
|
||||
'$customer_name' => $customer_data['first_name'] . ' ' . $customer_data['last_name'],
|
||||
'$customer_email' => $customer_data['email'],
|
||||
'$customer_phone' => $customer_data['phone_number'],
|
||||
'$customer_address' => $customer_data['address']
|
||||
);
|
||||
|
||||
$email_html = file_get_contents(dirname(dirname(__FILE__)) . '/views/emails/new_appointment.php');
|
||||
$email_html = file_get_contents(dirname(dirname(__FILE__))
|
||||
. '/views/emails/new_appointment.php');
|
||||
$email_html = $this->replace_template_variables($replace_array, $email_html);
|
||||
|
||||
$mail = new PHPMailer();
|
||||
$mail->From = $this->CI->Settings_Model->get_setting('company_email');
|
||||
$mail->FromName = $this->CI->Settings_Model->get_setting('company_name');;
|
||||
$mail->AddAddress($provider_data['email']); // Do not use the name argument, phpmailer crushes.
|
||||
$mail->AddAddress($provider_data['email']); // "Name" argument crushes the phpmailer class.
|
||||
$mail->IsHTML(true);
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->Subject = 'New Appointment';
|
||||
$mail->Body = $email_html;
|
||||
|
||||
if(!$mail->Send()) {
|
||||
if (!$mail->Send()) {
|
||||
throw new NotificationException('Email could not been sent. '
|
||||
. 'Mailer Error (Line ' . __LINE__ . '): ' . $mail->ErrorInfo);
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ class Appointments_Model extends CI_Model {
|
|||
* @return int Returns the id of the new record.
|
||||
*/
|
||||
private function insert($appointment_data) {
|
||||
$appointment_data['hash'] = $this->generate_hash();
|
||||
if (!$this->db->insert('ea_appointments', $appointment_data)) {
|
||||
throw new DatabaseException('Could not insert appointment record.');
|
||||
}
|
||||
|
@ -287,6 +288,21 @@ class Appointments_Model extends CI_Model {
|
|||
|
||||
return $this->db->get('ea_appointments')->result_array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique hash for the given appointment data.
|
||||
*
|
||||
* This method uses the current date-time to generate a unique
|
||||
* hash string that is later used to identify this appointment.
|
||||
* Hash is needed when the email is send to the user with an
|
||||
* edit link.
|
||||
*
|
||||
* @return string Returns the unique appointment hash.
|
||||
*/
|
||||
public function generate_hash() {
|
||||
$current_date = new DateTime();
|
||||
return md5($current_date->getTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
/* End of file appointments_model.php */
|
||||
|
|
|
@ -179,7 +179,6 @@ class Customers_Model extends CI_Model {
|
|||
|
||||
return TRUE;
|
||||
} catch (Exception $exc) {
|
||||
echo $exc->getMessage();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
|
||||
<?php // INCLUDE CSS FILES ?>
|
||||
<?php
|
||||
// ------------------------------------------------------------
|
||||
// INCLUDE CSS FILES
|
||||
// ------------------------------------------------------------ ?>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
|
@ -25,7 +28,10 @@
|
|||
type="text/css"
|
||||
href="<?php echo $this->config->base_url(); ?>assets/css/style.css">
|
||||
|
||||
<?php // INCLUDE JS FILES ?>
|
||||
<?php
|
||||
// ------------------------------------------------------------
|
||||
// INCLUDE JAVASCRIPT FILES
|
||||
// ------------------------------------------------------------ ?>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/js/libs/jquery/jquery.min.js">
|
||||
|
@ -55,37 +61,50 @@
|
|||
src="<?php echo $this->config->base_url(); ?>assets/js/general_functions.js">
|
||||
</script>
|
||||
|
||||
<?php // SET FAVICON FOR PAGE ?>
|
||||
<?php
|
||||
// ------------------------------------------------------------
|
||||
// WEBPAGE FAVICON
|
||||
// ------------------------------------------------------------ ?>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="<?php echo $this->config->base_url(); ?>assets/images/favicon.ico">
|
||||
|
||||
<?php // JS GLOBAL VARIABLE DECLARATION ?>
|
||||
<?php
|
||||
// ------------------------------------------------------------
|
||||
// VIEW FILE JAVASCRIPT CODE
|
||||
// ------------------------------------------------------------ ?>
|
||||
<script type="text/javascript">
|
||||
// Define some global variables.
|
||||
GlobalVariables = {
|
||||
services : <?php echo json_encode($available_services); ?>,
|
||||
providers : <?php echo json_encode($available_providers); ?>,
|
||||
baseUrl : <?php echo '"' . $this->config->base_url() . '"'; ?>
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php // JQUERY PAGE STUFF ?>
|
||||
<script type="text/javascript">
|
||||
availableServices : <?php echo json_encode($available_services); ?>,
|
||||
availableProviders : <?php echo json_encode($available_providers); ?>,
|
||||
baseUrl : <?php echo '"' . $this->config->base_url() . '"'; ?>,
|
||||
manageMode : <?php echo ($manage_mode) ? 'true' : 'false'; ?>,
|
||||
appointmentData : <?php echo json_encode($appointment_data); ?>,
|
||||
providerData : <?php echo json_encode($provider_data); ?>,
|
||||
customerData : <?php echo json_encode($customer_data); ?>
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
bookAppointment.initialize(true);
|
||||
GeneralFunctions.centerElementOnPage($('#book-appointment'));
|
||||
bookAppointment.initialize(true, GlobalVariables.manageMode);
|
||||
GeneralFunctions.centerElementOnPage($('#book-appointment-wizard'));
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="main" class="container">
|
||||
<div id="book-appointment">
|
||||
<div id="top-bar">
|
||||
<span id="business-name"><?php echo $company_name; ?></span>
|
||||
<div id="book-steps">
|
||||
|
||||
<div id="book-appointment-wizard">
|
||||
|
||||
<?php
|
||||
// ------------------------------------------------------
|
||||
// FRAME TOP BAR
|
||||
// ------------------------------------------------------ ?>
|
||||
<div id="header">
|
||||
<span id="company-name"><?php echo $company_name; ?></span>
|
||||
|
||||
<div id="steps">
|
||||
<div id="step-1" class="book-step active-step" title="Select Service & Provider">
|
||||
<strong>1</strong>
|
||||
</div>
|
||||
|
@ -101,13 +120,36 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php // SELECT SERVICE AND PROVIDER ?>
|
||||
<div id="book-appointment-1" class="book-appoinment-step">
|
||||
<div class="step-frame">
|
||||
<h2 class="step-title">Select Service & Provider</h2>
|
||||
<div class="step-content" style="width:270px">
|
||||
<label for="select-service"><strong>Select Service</strong></label>
|
||||
|
||||
<?php
|
||||
// ------------------------------------------------------
|
||||
// CANCEL APPOINTMENT BUTTON
|
||||
// ------------------------------------------------------
|
||||
if ($manage_mode === TRUE) {
|
||||
echo '
|
||||
<div id="cancel-appointment-frame">
|
||||
<p>
|
||||
Press the "Cancel" button to remove the appointment
|
||||
from the company schedule.
|
||||
</p>
|
||||
<button id="cancel-appointment" class="button">Cancel</button>
|
||||
</div>';
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
// ------------------------------------------------------
|
||||
// SELECT SERVICE AND PROVIDER
|
||||
// ------------------------------------------------------ ?>
|
||||
<div id="wizard-frame-1" class="wizard-frame">
|
||||
<div class="frame-container">
|
||||
<h2 class="frame-title">Select Service & Provider</h2>
|
||||
|
||||
<div class="frame-content" style="width:270px">
|
||||
<label for="select-service">
|
||||
<strong>Select Service</strong>
|
||||
</label>
|
||||
|
||||
<select id="select-service">
|
||||
<?php
|
||||
foreach($available_services as $service) {
|
||||
|
@ -117,7 +159,10 @@
|
|||
?>
|
||||
</select>
|
||||
|
||||
<label for="select-provider"><strong>Select Provider</strong></label>
|
||||
<label for="select-provider">
|
||||
<strong>Select Provider</strong>
|
||||
</label>
|
||||
|
||||
<select id="select-provider"></select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -128,11 +173,16 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<?php // APPOINTMENT DATE ?>
|
||||
<div id="book-appointment-2" class="book-appoinment-step" style="display:none;">
|
||||
<div class="step-frame">
|
||||
<h2 class="step-title">Select Appointment Date And Time</h2>
|
||||
<div class="step-content" style="width:600px">
|
||||
<?php
|
||||
// ------------------------------------------------------
|
||||
// SELECT APPOINTMENT DATE
|
||||
// ------------------------------------------------------ ?>
|
||||
<div id="wizard-frame-2" class="wizard-frame" style="display:none;">
|
||||
<div class="frame-container">
|
||||
|
||||
<h2 class="frame-title">Select Appointment Date And Time</h2>
|
||||
|
||||
<div class="frame-content" style="width:600px">
|
||||
<div class="span3">
|
||||
<div id="select-date"></div>
|
||||
</div>
|
||||
|
@ -152,11 +202,16 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<?php // CUSTOMER'S INFO ?>
|
||||
<div id="book-appointment-3" class="book-appoinment-step" style="display:none;">
|
||||
<div class="step-frame">
|
||||
<h2 class="step-title">Fill In Your Information</h2>
|
||||
<div class="step-content" style="width:600px">
|
||||
<?php
|
||||
// ------------------------------------------------------
|
||||
// ENTER CUSTOMER DATA
|
||||
// ------------------------------------------------------ ?>
|
||||
<div id="wizard-frame-3" class="wizard-frame" style="display:none;">
|
||||
<div class="frame-container">
|
||||
|
||||
<h2 class="frame-title">Fill In Your Information</h2>
|
||||
|
||||
<div class="frame-content" style="width:600px">
|
||||
<div class="span3">
|
||||
<label for="last-name">Last Name *</label>
|
||||
<input type="text" id="last-name" class="required" maxlength="250" />
|
||||
|
@ -198,11 +253,14 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<?php // CONFIRMATION STEP ?>
|
||||
<div id="book-appointment-4" class="book-appoinment-step" style="display:none;">
|
||||
<div class="step-frame">
|
||||
<h2 class="step-title">Confirm Appointment</h2>
|
||||
<div class="step-content" style="width:600px">
|
||||
<?php
|
||||
// ------------------------------------------------------
|
||||
// APPOINTMENT DATA CONFIRMATION
|
||||
// ------------------------------------------------------ ?>
|
||||
<div id="wizard-frame-4" class="wizard-frame" style="display:none;">
|
||||
<div class="frame-container">
|
||||
<h2 class="frame-title">Confirm Appointment</h2>
|
||||
<div class="frame-content" style="width:600px">
|
||||
<div id="appointment-info" class="span3"></div>
|
||||
<div id="customer-info" class="span3"></div>
|
||||
</div>
|
||||
|
@ -213,14 +271,25 @@
|
|||
data-step_index="4"><i class="icon-backward"></i> Back</button>
|
||||
<form id="book-appointment-form" style="display:inline-block" method="post">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="icon-ok icon-white"></i>Confirm</button>
|
||||
<i class="icon-ok icon-white"></i>
|
||||
<?php
|
||||
echo (!$manage_mode) ? "Confirm" : "Update";
|
||||
?>
|
||||
</button>
|
||||
<input type="hidden" name="post_data" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
// ------------------------------------------------------
|
||||
// FRAME FOOTER
|
||||
// ------------------------------------------------------ ?>
|
||||
<div id="frame-footer">
|
||||
Powered By <a href="https://code.google.com/p/easy-appointments/">Easy!Appointments</a>
|
||||
Powered By
|
||||
<a href="https://code.google.com/p/easy-appointments/">
|
||||
Easy!Appointments
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="success-frame" class="container">
|
||||
<div id="success-frame" class="frame-container">
|
||||
<img id="success-icon" src="<?php echo $this->config->base_url(); ?>assets/images/success.png" />
|
||||
|
||||
<h2>Your appointment has been successfully registered.</h2>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="message-frame" class="container">
|
||||
<div id="message-frame" class="frame-container">
|
||||
<img
|
||||
id="message-icon"
|
||||
src="<?php echo $this->config->base_url(); ?>assets/images/<?php echo $image; ?>" />
|
||||
|
|
56
src/application/views/emails/book_success.php
Normal file
56
src/application/views/emails/book_success.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Appointment Book Success</title>
|
||||
</head>
|
||||
<body style="font: 13px arial, helvetica, tahoma;">
|
||||
<div class="email-container" style="width: 650px;border: 1px solid #eee;">
|
||||
<div id="header" style="background-color: #3DD481; border-bottom: 4px solid #1A865F;
|
||||
height: 40px;padding: 10px 15px;">
|
||||
<strong id="logo" style="color: white; font-size: 31px;
|
||||
text-shadow: 1px 1px 1px #8F8888;">$company_name</strong>
|
||||
</div>
|
||||
|
||||
<div id="content" style="padding: 10px 15px;">
|
||||
<h2>Your appointment has been successfully booked!</h2>
|
||||
<p>
|
||||
Thank you $customer_name for arranging an appointment with us.
|
||||
Below you can see the appointment details. Click on the edit
|
||||
link to make changes to your appointment.
|
||||
</p>
|
||||
|
||||
<h2>Appointment Details</h2>
|
||||
<table id="appointment-details">
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Service</td>
|
||||
<td style="padding: 3px;">$appointment_service</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Provider</td>
|
||||
<td style="padding: 3px;">$appointment_provider</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Date</td>
|
||||
<td style="padding: 3px;">$appointment_date</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Duration</td>
|
||||
<td style="padding: 3px;">$appointment_duration</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Edit Link</h2>
|
||||
<p>
|
||||
Press the following link to make changes to your appointment reservation.
|
||||
You are able to change the appointment details three hours before
|
||||
the appointment.
|
||||
</p>
|
||||
<a href="$appointment_link">$appointment_link</a>
|
||||
</div>
|
||||
|
||||
<div id="footer" style="padding: 10px; text-align: center;
|
||||
border-top: 1px solid #EEE;background: #FAFAFA;">
|
||||
<a href="$company_link">$company_name</a> | Powered by Easy!Appointments
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
67
src/application/views/emails/new_appointment.php
Normal file
67
src/application/views/emails/new_appointment.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>New Appointment</title>
|
||||
</head>
|
||||
|
||||
<body style="font: 13px arial, helvetica, tahoma;">
|
||||
<div class="email-container" style="width: 650px;border: 1px solid #eee;">
|
||||
<div id="header" style="background-color: #3DD481; border-bottom: 4px solid #1A865F;
|
||||
height: 40px; padding: 10px 15px;">
|
||||
<strong id="logo" style="color: white; font-size: 31px;
|
||||
text-shadow: 1px 1px 1px #8F8888;">$company_name</strong>
|
||||
</div>
|
||||
|
||||
<div id="content" style="padding: 10px 15px;">
|
||||
<h2>A new appointment has been added to your plan.</h2>
|
||||
<h2>Appointment Details</h2>
|
||||
<table id="appointment-details">
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Service</td>
|
||||
<td style="padding: 3px;">$appointment_service</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Provider</td>
|
||||
<td style="padding: 3px;">$appointment_provider</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Date</td>
|
||||
<td style="padding: 3px;">$appointment_date</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Duration</td>
|
||||
<td style="padding: 3px;">$appointment_duration</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Customer Details</h2>
|
||||
<table id="appointment-details">
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Name</td>
|
||||
<td style="padding: 3px;">$customer_name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Email</td>
|
||||
<td style="padding: 3px;">$customer_email</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Phone</td>
|
||||
<td style="padding: 3px;">$customer_phone</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label" style="padding: 3px;font-weight: bold;">Address</td>
|
||||
<td style="padding: 3px;">$customer_address</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Appointment Link</h2>
|
||||
<p>You can make more actions by pressing the following link.</p>
|
||||
<a href="$appointment_link">$appointment_link</a>
|
||||
</div>
|
||||
|
||||
<div id="footer" style="padding: 10px; text-align: center;
|
||||
border-top: 1px solid #EEE; background: #FAFAFA;">
|
||||
<a href="$company_link">$company_name</a> | Powered by Easy!Appointments
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -10,23 +10,23 @@ body {
|
|||
}
|
||||
|
||||
|
||||
/* REGISTER APPOINTMENT
|
||||
/* BOOK APPOINTMENT WIZARD
|
||||
------------------------------------------------------------------------------ */
|
||||
#book-appointment {
|
||||
#book-appointment-wizard {
|
||||
width: 660px;
|
||||
background: #FFF;
|
||||
box-shadow: 0px 1px 1px #B6B6B6;
|
||||
min-height: 480px;
|
||||
}
|
||||
|
||||
#book-appointment #top-bar {
|
||||
#book-appointment-wizard #header {
|
||||
padding: 5px;
|
||||
height: 70px;
|
||||
background: #3DD481;
|
||||
border-bottom: 4px solid #1A865F;
|
||||
}
|
||||
|
||||
#book-appointment #business-name {
|
||||
#book-appointment-wizard #company-name {
|
||||
font-weight: bold;
|
||||
color: #FFF;
|
||||
font-size: 27px;
|
||||
|
@ -36,43 +36,43 @@ body {
|
|||
float: left;
|
||||
}
|
||||
|
||||
#book-appointment #book-steps {
|
||||
#book-appointment-wizard #steps {
|
||||
width: 204px;
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#book-appointment .book-appoinment-step {
|
||||
#book-appointment-wizard .wizard-frame {
|
||||
padding: 10px 20px;
|
||||
height: 434px;
|
||||
}
|
||||
|
||||
#book-appointment .book-appoinment-step .step-frame {
|
||||
#book-appointment-wizard .wizard-frame .frame-container {
|
||||
height: 370px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#book-appointment .step-frame .step-title {
|
||||
#book-appointment-wizard .frame-container .frame-title {
|
||||
text-align: center;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
#book-appointment .step-frame .step-content {
|
||||
#book-appointment-wizard .frame-container .frame-content {
|
||||
margin: auto;
|
||||
float: none;
|
||||
}
|
||||
|
||||
#book-appointment .command-buttons {
|
||||
#book-appointment-wizard .wizard-frame .command-buttons {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#book-appointment .command-buttons .btn {
|
||||
#book-appointment-wizard .wizard-frame .command-buttons .btn {
|
||||
min-width: 80px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#book-appointment .book-step {
|
||||
#book-appointment-wizard .book-step {
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
|
@ -84,14 +84,14 @@ body {
|
|||
border: 3px solid #38A07A;
|
||||
}
|
||||
|
||||
#book-appointment .book-step strong {
|
||||
#book-appointment-wizard .book-step strong {
|
||||
font-size: 18px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
color: #B6DFC6;
|
||||
}
|
||||
|
||||
#book-appointment .active-step {
|
||||
#book-appointment-wizard .active-step {
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
|
@ -103,40 +103,49 @@ body {
|
|||
border: 3px solid #38A07A;
|
||||
}
|
||||
|
||||
#book-appointment .active-step strong {
|
||||
#book-appointment-wizard .active-step strong {
|
||||
color: #396946;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
#book-appointment #frame-footer {
|
||||
#book-appointment-wizard #frame-footer {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #EEE;
|
||||
background: #FAFAFA;
|
||||
}
|
||||
|
||||
.custom-qtip {
|
||||
#book-appointment-wizard #steps .custom-qtip {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
#available-hours .available-hour {
|
||||
#book-appointment-wizard #available-hours .available-hour {
|
||||
font-size: 15px;
|
||||
padding: 1px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#available-hours .available-hour:hover {
|
||||
#book-appointment-wizard #available-hours .available-hour:hover {
|
||||
font-weight: bold;
|
||||
background-color: #CAEDF3;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#available-hours .selected-hour {
|
||||
#book-appointment-wizard #available-hours .selected-hour {
|
||||
color: #0088cc;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#book-appointment .span3 {
|
||||
#book-appointment-wizard .span3 {
|
||||
min-width: 270px; /* This is especially needed for ie8 */
|
||||
}
|
||||
|
||||
#cancel-appointment-frame {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,20 +1,34 @@
|
|||
/**
|
||||
* 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) {
|
||||
bookAppointment.manageMode = false; // Default Value
|
||||
}
|
||||
|
||||
// Initialize page's components (tooltips, datepickers etc).
|
||||
|
@ -34,7 +48,7 @@ var bookAppointment = {
|
|||
defaultDate : Date.today(),
|
||||
onSelect : function(dateText, instance) {
|
||||
bookAppointment.getAvailableHours(dateText);
|
||||
bookAppointment.updateConfirmData();
|
||||
bookAppointment.updateConfirmFrame();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -43,22 +57,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();
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -71,21 +94,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();
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -101,9 +124,10 @@ var bookAppointment = {
|
|||
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>');
|
||||
$('#available-hours').append('<br><br>'
|
||||
+ '<strong id="select-hour-prompt" class="text-error">'
|
||||
+ 'Please select an appointment hour before continuing!'
|
||||
+ '</strong>');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -112,10 +136,10 @@ var bookAppointment = {
|
|||
// 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 (!bookAppointment.validateCustomerForm()) {
|
||||
return; // Validation failed, do not continue.
|
||||
} else {
|
||||
bookAppointment.updateConfirmData();
|
||||
bookAppointment.updateConfirmFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +149,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');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -141,7 +165,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');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -154,7 +178,7 @@ var bookAppointment = {
|
|||
$('#available-hours').on('click', '.available-hour', function() {
|
||||
$('.selected-hour').removeClass('selected-hour');
|
||||
$(this).addClass('selected-hour');
|
||||
bookAppointment.updateConfirmData();
|
||||
bookAppointment.updateConfirmFrame();
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -169,24 +193,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 {
|
||||
|
@ -199,27 +230,32 @@ var bookAppointment = {
|
|||
// 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')
|
||||
.append('<div style="width:50px; float:left;"></div>');
|
||||
}
|
||||
|
||||
$('#available-hours div:eq(' + (currColumn - 1) + ')')
|
||||
.append('<span class="available-hour">' + availableHour + '</span><br/>');
|
||||
.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 not available appointment hours for '
|
||||
+ 'the selected date. Please choose another date.');
|
||||
$('#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.');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -230,7 +266,7 @@ var bookAppointment = {
|
|||
*
|
||||
* @return {bool} Returns the validation result.
|
||||
*/
|
||||
validateCustomerDataForm : function() {
|
||||
validateCustomerForm : function() {
|
||||
var validationResult = true;
|
||||
$('.required').css('border', '');
|
||||
|
||||
|
@ -249,7 +285,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) {
|
||||
|
@ -308,7 +344,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 ...
|
||||
|
@ -328,5 +364,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']);
|
||||
$('#select-provider').val(appointmentData['id_users_provider']);
|
||||
|
||||
// Set Appointment Date
|
||||
$('.available-hour').removeClass('selected-hour');
|
||||
$('.available-hour').filter(function() {
|
||||
return $(this).text() === Date.parseExact(appointmentData['start_datetime'],
|
||||
'yyyy-MM-dd HH:mm').toString('HH:mm');
|
||||
}).addClass('selected-hour');
|
||||
|
||||
// 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']);
|
||||
$('notes').text(customerData['notes']);
|
||||
|
||||
bookAppointment.updateConfirmFrame();
|
||||
|
||||
return true;
|
||||
} catch(exc) {
|
||||
console.log(exc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -82,4 +82,24 @@ 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];
|
||||
}
|
Loading…
Reference in a new issue