Extra working days outside default working plan
Add function to add extra working days outside the default working plan.
This commit is contained in:
parent
43b9cf678b
commit
9c7ae5dfdc
41 changed files with 1162 additions and 21 deletions
2
src/application/config/migration.php
Normal file → Executable file
2
src/application/config/migration.php
Normal file → Executable file
|
@ -37,7 +37,7 @@ $config['migration_table'] = 'ea_migrations';
|
||||||
| be upgraded / downgraded to.
|
| be upgraded / downgraded to.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
$config['migration_version'] = 10; // current
|
$config['migration_version'] = 11; // current
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -790,6 +790,9 @@ class Appointments extends CI_Controller {
|
||||||
// Get the service, provider's working plan and provider appointments.
|
// Get the service, provider's working plan and provider appointments.
|
||||||
$working_plan = json_decode($this->providers_model->get_setting('working_plan', $provider_id), TRUE);
|
$working_plan = json_decode($this->providers_model->get_setting('working_plan', $provider_id), TRUE);
|
||||||
|
|
||||||
|
// Get the provider's extra working plan.
|
||||||
|
$extra_working_plan = json_decode($this->providers_model->get_setting('extra_working_plan', $provider_id), TRUE);
|
||||||
|
|
||||||
$provider_appointments = $this->appointments_model->get_batch([
|
$provider_appointments = $this->appointments_model->get_batch([
|
||||||
'id_users_provider' => $provider_id,
|
'id_users_provider' => $provider_id,
|
||||||
]);
|
]);
|
||||||
|
@ -811,6 +814,14 @@ class Appointments extends CI_Controller {
|
||||||
// every reserved appointment is considered to be a taken space in the plan.
|
// every reserved appointment is considered to be a taken space in the plan.
|
||||||
$selected_date_working_plan = $working_plan[strtolower(date('l', strtotime($selected_date)))];
|
$selected_date_working_plan = $working_plan[strtolower(date('l', strtotime($selected_date)))];
|
||||||
|
|
||||||
|
// Search if the $selected_date is an extra date added outside the normal working plan
|
||||||
|
if ($selected_date_working_plan == null) {
|
||||||
|
if (isset($extra_working_plan[strtolower(date('Y-m-d', strtotime($selected_date)))])){
|
||||||
|
$selected_date_working_plan = $extra_working_plan[strtolower(date('Y-m-d', strtotime($selected_date)))];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$periods = [];
|
$periods = [];
|
||||||
|
|
||||||
if (isset($selected_date_working_plan['breaks']))
|
if (isset($selected_date_working_plan['breaks']))
|
||||||
|
|
|
@ -212,6 +212,7 @@ class Backend extends CI_Controller {
|
||||||
$view['secretaries'] = $this->secretaries_model->get_batch();
|
$view['secretaries'] = $this->secretaries_model->get_batch();
|
||||||
$view['services'] = $this->services_model->get_batch();
|
$view['services'] = $this->services_model->get_batch();
|
||||||
$view['working_plan'] = $this->settings_model->get_setting('company_working_plan');
|
$view['working_plan'] = $this->settings_model->get_setting('company_working_plan');
|
||||||
|
$view['extra_working_plan'] = "{}";
|
||||||
$this->set_user_data($view);
|
$this->set_user_data($view);
|
||||||
|
|
||||||
$this->load->view('backend/header', $view);
|
$this->load->view('backend/header', $view);
|
||||||
|
|
|
@ -798,6 +798,101 @@ class Backend_api extends CI_Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [AJAX] Insert of update extra working plan time period to database.
|
||||||
|
*
|
||||||
|
* Required POST Parameters:
|
||||||
|
*
|
||||||
|
* - array $_POST['extra_period'] JSON encoded array that contains the unavailable period data.
|
||||||
|
*/
|
||||||
|
public function ajax_save_extra_period()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check privileges
|
||||||
|
$extra_period = json_decode($this->input->post('extra_period'), TRUE);
|
||||||
|
|
||||||
|
$REQUIRED_PRIV = ( ! isset($extra_period['id']))
|
||||||
|
? $this->privileges[PRIV_APPOINTMENTS]['add']
|
||||||
|
: $this->privileges[PRIV_APPOINTMENTS]['edit'];
|
||||||
|
if ($REQUIRED_PRIV == FALSE)
|
||||||
|
{
|
||||||
|
throw new Exception('You do not have the required privileges for this task.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->load->model('providers_model');
|
||||||
|
|
||||||
|
$success = $this->providers_model->set_extra_working_day($extra_period, $extra_period['id_users_provider']);
|
||||||
|
|
||||||
|
if ( ! $success)
|
||||||
|
{
|
||||||
|
$this->output
|
||||||
|
->set_content_type('application/json')
|
||||||
|
->set_output(json_encode(['warnings' => 'Error on saving extra period.']));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->output
|
||||||
|
->set_content_type('application/json')
|
||||||
|
->set_output(json_encode(AJAX_SUCCESS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $exc)
|
||||||
|
{
|
||||||
|
$this->output
|
||||||
|
->set_content_type('application/json')
|
||||||
|
->set_output(json_encode(['exceptions' => [exceptionToJavaScript($exc)]]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [AJAX] Delete an extra working plan time period to database.
|
||||||
|
*
|
||||||
|
* Required POST Parameters:
|
||||||
|
*
|
||||||
|
* - String $_POST['extra_period'] Date to be deleted.
|
||||||
|
* - int $_POST['provider_id'] Record id to be deleted.
|
||||||
|
*/
|
||||||
|
public function ajax_delete_extra_period()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ($this->privileges[PRIV_APPOINTMENTS]['delete'] == FALSE)
|
||||||
|
{
|
||||||
|
throw new Exception('You do not have the required privileges for this task.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check privileges
|
||||||
|
$extra_period = $this->input->post('extra_period');
|
||||||
|
$provider_id = $this->input->post('provider_id');
|
||||||
|
|
||||||
|
$this->load->model('providers_model');
|
||||||
|
|
||||||
|
// Delete unavailable
|
||||||
|
$success = $this->providers_model->delete_extra_working_day($extra_period, $provider_id);
|
||||||
|
|
||||||
|
if ( ! $success)
|
||||||
|
{
|
||||||
|
$this->output
|
||||||
|
->set_content_type('application/json')
|
||||||
|
->set_output(json_encode(['warnings' => 'Error on deleting extra working day']));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->output
|
||||||
|
->set_content_type('application/json')
|
||||||
|
->set_output(json_encode(AJAX_SUCCESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
} //
|
||||||
|
catch (Exception $exc) //
|
||||||
|
{ //
|
||||||
|
$this->output //
|
||||||
|
->set_content_type('application/json') //
|
||||||
|
->set_output(json_encode(['exceptions' => [exceptionToJavaScript($exc)]])); //
|
||||||
|
}//
|
||||||
|
} //
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [AJAX] Save (insert or update) a customer record.
|
* [AJAX] Save (insert or update) a customer record.
|
||||||
*
|
*
|
||||||
|
|
|
@ -281,3 +281,10 @@ $lang['availabilities_type'] = 'نوع التوفر أو الإتاحة';
|
||||||
$lang['flexible'] = 'مرن';
|
$lang['flexible'] = 'مرن';
|
||||||
$lang['fixed'] = 'ثابت';
|
$lang['fixed'] = 'ثابت';
|
||||||
$lang['attendants_number'] = 'عدد الحاضرين';
|
$lang['attendants_number'] = 'عدد الحاضرين';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Гъвкав';
|
||||||
$lang['fixed'] = 'Фиксиран';
|
$lang['fixed'] = 'Фиксиран';
|
||||||
$lang['attendants_number'] = 'Брой Посетители';
|
$lang['attendants_number'] = 'Брой Посетители';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexibel';
|
||||||
$lang['fixed'] = 'Vast';
|
$lang['fixed'] = 'Vast';
|
||||||
$lang['attendants_number'] = 'Aantal deelnemers';
|
$lang['attendants_number'] = 'Aantal deelnemers';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = 'Extra working day';
|
||||||
|
$lang['extra_periods'] = 'Extra working days';
|
||||||
|
$lang['extra_periods_hint'] = 'Add a working day outside the working plan.';
|
||||||
|
$lang['new_extra_period_title'] = 'New working day';
|
||||||
|
$lang['extra_period_saved'] = 'New working day saved successfully!';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = 'Add working days outside the working plan.';
|
||||||
|
$lang['add_extra_period'] = 'Add a working day';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -280,3 +280,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexibel';
|
||||||
$lang['fixed'] = 'Fest';
|
$lang['fixed'] = 'Fest';
|
||||||
$lang['attendants_number'] = 'Begleiternummer';
|
$lang['attendants_number'] = 'Begleiternummer';
|
||||||
$lang['reset_working_plan'] = 'Setzen Sie das Arbeitsplan zu die Standard Werte.';
|
$lang['reset_working_plan'] = 'Setzen Sie das Arbeitsplan zu die Standard Werte.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Ευέλικτος';
|
||||||
$lang['fixed'] = 'Σταθερός';
|
$lang['fixed'] = 'Σταθερός';
|
||||||
$lang['attendants_number'] = 'Αριθμός Παραστατών';
|
$lang['attendants_number'] = 'Αριθμός Παραστατών';
|
||||||
$lang['reset_working_plan'] = 'Επαναρυθμήστε το πλάνο εργασίας στις αρχικές του τιμές.';
|
$lang['reset_working_plan'] = 'Επαναρυθμήστε το πλάνο εργασίας στις αρχικές του τιμές.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -288,3 +288,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = 'Giorno extra';
|
||||||
|
$lang['extra_periods'] = 'Giorno Extra';
|
||||||
|
$lang['extra_periods_hint'] = 'Aggiungi una giornata lavorativa al di fuori del piano di lavoro.';
|
||||||
|
$lang['new_extra_period_title'] = 'Nuova giornata lavorativa';
|
||||||
|
$lang['extra_period_saved'] = 'Giornata lavorativa salvata con successo!';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = 'Aggiungi giornate lavorative al di fuori del piano di lavoro.';
|
||||||
|
$lang['add_extra_period'] = 'Aggiungi giornata lavorativa';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -288,3 +288,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexibilný';
|
||||||
$lang['fixed'] = 'Fixný';
|
$lang['fixed'] = 'Fixný';
|
||||||
$lang['attendants_number'] = 'Počet účastníkov';
|
$lang['attendants_number'] = 'Počet účastníkov';
|
||||||
$lang['reset_working_plan'] = 'Obnovte pracovný plán späť na predvolené hodnoty.';
|
$lang['reset_working_plan'] = 'Obnovte pracovný plán späť na predvolené hodnoty.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Número de Atenciones';
|
$lang['attendants_number'] = 'Número de Atenciones';
|
||||||
$lang['reset_working_plan'] = 'Reinicia el plan de trabajo a los valores por defecto.';
|
$lang['reset_working_plan'] = 'Reinicia el plan de trabajo a los valores por defecto.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -282,3 +282,10 @@ $lang['flexible'] = 'Flexible';
|
||||||
$lang['fixed'] = 'Fixed';
|
$lang['fixed'] = 'Fixed';
|
||||||
$lang['attendants_number'] = 'Attendants Number';
|
$lang['attendants_number'] = 'Attendants Number';
|
||||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||||
|
$lang['extra_period'] = '';
|
||||||
|
$lang['extra_periods'] = '';
|
||||||
|
$lang['extra_periods_hint'] = '';
|
||||||
|
$lang['new_extra_period_title'] = '';
|
||||||
|
$lang['extra_period_saved'] = '';
|
||||||
|
$lang['add_extra_periods_during_each_day'] = '';
|
||||||
|
$lang['add_extra_period'] = '';
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php defined('BASEPATH') OR exit('No direct script access allowed');
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Easy!Appointments - Open Source Web Scheduler
|
||||||
|
*
|
||||||
|
* @package EasyAppointments
|
||||||
|
* @author A.Tselegidis <alextselegidis@gmail.com>
|
||||||
|
* @copyright Copyright (c) 2013 - 2017, Alex Tselegidis
|
||||||
|
* @license http://opensource.org/licenses/GPL-3.0 - GPLv3
|
||||||
|
* @link http://easyappointments.org
|
||||||
|
* @since v1.2.0
|
||||||
|
* ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
class Migration_Add_user_extra_working_plan extends CI_Migration {
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
if (!$this->db->field_exists('extra_working_plan', 'ea_user_settings')) {
|
||||||
|
$fields = [
|
||||||
|
'extra_working_plan' => [
|
||||||
|
'type' => 'TEXT',
|
||||||
|
'null' => TRUE,
|
||||||
|
'default' => '',
|
||||||
|
'after' => 'working_plan'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->dbforge->add_column('ea_user_settings', $fields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
if (!$this->db->field_exists('extra_working_plan', 'ea_user_settings')) {
|
||||||
|
$this->dbforge->drop_column('ea_user_settings', 'extra_working_plan');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
src/application/models/Providers_model.php
Normal file → Executable file
87
src/application/models/Providers_model.php
Normal file → Executable file
|
@ -600,6 +600,13 @@ class Providers_Model extends CI_Model {
|
||||||
|
|
||||||
foreach ($settings as $name => $value)
|
foreach ($settings as $name => $value)
|
||||||
{
|
{
|
||||||
|
// Sort in descending order the extra working plan days
|
||||||
|
if ($name == 'extra_working_plan') {
|
||||||
|
$value = json_decode($value, true);
|
||||||
|
// Sort the array and put in reverse order
|
||||||
|
krsort($value);
|
||||||
|
$value = json_encode($value);
|
||||||
|
}
|
||||||
$this->set_setting($name, $value, $provider_id);
|
$this->set_setting($name, $value, $provider_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -638,6 +645,86 @@ class Providers_Model extends CI_Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the provider extra working plan days.
|
||||||
|
*
|
||||||
|
* @param array $extra_period Contains the date and the hours of the extra working plan day.
|
||||||
|
* @param int $provider_id The selected provider record id.
|
||||||
|
*
|
||||||
|
* @return bool Return if the new extra working plan is correctly saved to DB.
|
||||||
|
*
|
||||||
|
* @throws Exception If start time is after the end time.
|
||||||
|
* @throws Exception If $provider_id argument is invalid.
|
||||||
|
*/
|
||||||
|
public function set_extra_working_day($extra_period, $provider_id)
|
||||||
|
{
|
||||||
|
// Validate period
|
||||||
|
$dateStart = date('Y-m-d', strtotime($extra_period['start_datetime']));
|
||||||
|
$start = date('H:i',strtotime($extra_period['start_datetime']));
|
||||||
|
$end = date('H:i',strtotime($extra_period['end_datetime']));
|
||||||
|
if ($start > $end)
|
||||||
|
{
|
||||||
|
throw new Exception('Unavailable period start must be prior to end.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate provider record
|
||||||
|
$where_clause = [
|
||||||
|
'id' => $provider_id,
|
||||||
|
'id_roles' => $this->db->get_where('ea_roles', ['slug' => DB_SLUG_PROVIDER])->row()->id
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->db->get_where('ea_users', $where_clause)->num_rows() == 0)
|
||||||
|
{
|
||||||
|
throw new Exception('Provider id was not found in database.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add record to database.
|
||||||
|
$extra_working_plan = json_decode($this->get_setting('extra_working_plan', $provider_id), true);
|
||||||
|
|
||||||
|
$extra_working_plan[$dateStart] = [
|
||||||
|
'start' => $start,
|
||||||
|
'end' => $end,
|
||||||
|
'breaks' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
$success = $this->set_setting('extra_working_plan', json_encode($extra_working_plan), $provider_id);
|
||||||
|
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a provider extra working plan day.
|
||||||
|
*
|
||||||
|
* @param string $extra_period Contains the date to be deleted from the extra working plan.
|
||||||
|
* @param int $provider_id The selected provider record id.
|
||||||
|
*
|
||||||
|
* @return bool Return if the new extra working plan is correctly deleted from DB.
|
||||||
|
*
|
||||||
|
* @throws Exception If $provider_id argument is invalid.
|
||||||
|
*/
|
||||||
|
public function delete_extra_working_day($extra_period, $provider_id)
|
||||||
|
{
|
||||||
|
// Validate provider record
|
||||||
|
$where_clause = [
|
||||||
|
'id' => $provider_id,
|
||||||
|
'id_roles' => $this->db->get_where('ea_roles', ['slug' => DB_SLUG_PROVIDER])->row()->id
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->db->get_where('ea_users', $where_clause)->num_rows() == 0)
|
||||||
|
{
|
||||||
|
throw new Exception('Provider id was not found in database.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add record to database.
|
||||||
|
$extra_working_plan = json_decode($this->get_setting('extra_working_plan', $provider_id), true);
|
||||||
|
|
||||||
|
unset($extra_working_plan[$extra_period]);
|
||||||
|
|
||||||
|
$success = $this->set_setting('extra_working_plan', json_encode($extra_working_plan), $provider_id);
|
||||||
|
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate Records Username
|
* Validate Records Username
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<script src="<?= asset_url('assets/js/backend_calendar_google_sync.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/backend_calendar_google_sync.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/backend_calendar_appointments_modal.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/backend_calendar_appointments_modal.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/backend_calendar_unavailabilities_modal.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/backend_calendar_unavailabilities_modal.js') ?>"></script>
|
||||||
|
<script src="<?= asset_url('assets/js/backend_calendar_extra_periods_modal.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/backend_calendar_api.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/backend_calendar_api.js') ?>"></script>
|
||||||
<script>
|
<script>
|
||||||
var GlobalVariables = {
|
var GlobalVariables = {
|
||||||
|
@ -73,6 +74,11 @@
|
||||||
<span class="glyphicon glyphicon-plus"></span>
|
<span class="glyphicon glyphicon-plus"></span>
|
||||||
<?= lang('unavailable') ?>
|
<?= lang('unavailable') ?>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button id="insert-extra-period" class="btn btn-default" title="<?= lang('extra_periods_hint') ?>">
|
||||||
|
<span class="glyphicon glyphicon-plus"></span>
|
||||||
|
<?= lang('extra_period') ?>
|
||||||
|
</button>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
||||||
<button id="reload-appointments" class="btn btn-default" title="<?= lang('reload_appointments_hint') ?>">
|
<button id="reload-appointments" class="btn btn-default" title="<?= lang('reload_appointments_hint') ?>">
|
||||||
|
@ -321,6 +327,47 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- MANAGE EXTRA PERIOD MODAL -->
|
||||||
|
|
||||||
|
<div id="manage-extra" class="modal fade">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h3 class="modal-title"><?= lang('new_extra_period_title') ?></h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="modal-message alert hidden"></div>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<fieldset>
|
||||||
|
<input id="extra-id" type="hidden">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="extra-provider" class="control-label"><?= lang('provider') ?></label>
|
||||||
|
<select id="extra-provider" class="form-control"></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="extra-start" class="control-label"><?= lang('start') ?></label>
|
||||||
|
<input id="extra-start" class="form-control">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="extra-end" class="control-label"><?= lang('end') ?></label>
|
||||||
|
<input id="extra-end" class="form-control">
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="save-extra" class="btn btn-primary"><?= lang('save') ?></button>
|
||||||
|
<button id="cancel-extra" class="btn btn-default" data-dismiss="modal"><?= lang('cancel') ?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- SELECT GOOGLE CALENDAR MODAL -->
|
<!-- SELECT GOOGLE CALENDAR MODAL -->
|
||||||
|
|
||||||
<div id="select-google-calendar" class="modal fade">
|
<div id="select-google-calendar" class="modal fade">
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
secretaries : <?= json_encode($secretaries) ?>,
|
secretaries : <?= json_encode($secretaries) ?>,
|
||||||
services : <?= json_encode($services) ?>,
|
services : <?= json_encode($services) ?>,
|
||||||
workingPlan : <?= json_encode(json_decode($working_plan)) ?>,
|
workingPlan : <?= json_encode(json_decode($working_plan)) ?>,
|
||||||
|
extraWorkingPlan : <?= json_encode(json_decode($extra_working_plan)) ?>,
|
||||||
user : {
|
user : {
|
||||||
id : <?= $user_id ?>,
|
id : <?= $user_id ?>,
|
||||||
email : <?= json_encode($user_email) ?>,
|
email : <?= json_encode($user_email) ?>,
|
||||||
|
@ -332,6 +333,35 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody><!-- Dynamic Content --></tbody>
|
<tbody><!-- Dynamic Content --></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<h3><?= lang('extra_periods') ?></h3>
|
||||||
|
|
||||||
|
<span class="help-block">
|
||||||
|
<?= lang('add_extra_periods_during_each_day') ?>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button type="button" class="add-extra-periods btn btn-primary">
|
||||||
|
<span class="glyphicon glyphicon-plus"></span>
|
||||||
|
<?= lang('add_extra_period') ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<table class="extra-periods table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><?= lang('day') ?></th>
|
||||||
|
<th><?= lang('start') ?></th>
|
||||||
|
<th><?= lang('end') ?></th>
|
||||||
|
<th><?= lang('actions') ?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody><!-- Dynamic Content --></tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -657,10 +657,19 @@ body .form-horizontal .controls {
|
||||||
padding: 4px 7px;
|
padding: 4px 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#users-page #providers .extra-periods .btn {
|
||||||
|
margin-right: 5px;
|
||||||
|
padding: 4px 7px;
|
||||||
|
}
|
||||||
|
|
||||||
@-moz-document url-prefix() {
|
@-moz-document url-prefix() {
|
||||||
.breaks .break-day select {
|
.breaks .break-day select {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.extra-periods .extra-day select {
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#users-page .working-plan .checkbox,
|
#users-page .working-plan .checkbox,
|
||||||
|
|
1
src/assets/js/backend_calendar.js
Normal file → Executable file
1
src/assets/js/backend_calendar.js
Normal file → Executable file
|
@ -87,6 +87,7 @@ window.BackendCalendar = window.BackendCalendar || {};
|
||||||
BackendCalendarGoogleSync.initialize();
|
BackendCalendarGoogleSync.initialize();
|
||||||
BackendCalendarAppointmentsModal.initialize();
|
BackendCalendarAppointmentsModal.initialize();
|
||||||
BackendCalendarUnavailabilitiesModal.initialize();
|
BackendCalendarUnavailabilitiesModal.initialize();
|
||||||
|
BackendCalendarExtraPeriodsModal.initialize();
|
||||||
|
|
||||||
_bindEventHandlers();
|
_bindEventHandlers();
|
||||||
};
|
};
|
||||||
|
|
24
src/assets/js/backend_calendar_api.js
Normal file → Executable file
24
src/assets/js/backend_calendar_api.js
Normal file → Executable file
|
@ -85,4 +85,26 @@ window.BackendCalendarApi = window.BackendCalendarApi || {};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
})(window.BackendCalendarApi);
|
/**
|
||||||
|
* Save extra period of work to database.
|
||||||
|
* @param {Object} extra_periods Contains the extra period data.
|
||||||
|
* @param {Function} successCallback The ajax success callback function.
|
||||||
|
* @param {Function} errorCallback The ajax failure callback function.
|
||||||
|
*/
|
||||||
|
exports.saveExtraPeriod = function (extra_periods, successCallback, errorCallback) {
|
||||||
|
var postUrl = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_extra_period';
|
||||||
|
var postData = {
|
||||||
|
csrfToken: GlobalVariables.csrfToken,
|
||||||
|
extra_period: JSON.stringify(extra_periods)
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: postUrl,
|
||||||
|
data: postData,
|
||||||
|
success: successCallback,
|
||||||
|
error: errorCallback
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})(window.BackendCalendarApi);
|
||||||
|
|
|
@ -124,7 +124,41 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {};
|
||||||
$calendarPage.on('click', '.delete-popover', function () {
|
$calendarPage.on('click', '.delete-popover', function () {
|
||||||
$(this).parents().eq(2).remove(); // Hide the popover.
|
$(this).parents().eq(2).remove(); // Hide the popover.
|
||||||
|
|
||||||
if (lastFocusedEventData.data.is_unavailable == false) {
|
// If id_role parameter exists the popover is an extra working day.
|
||||||
|
if (lastFocusedEventData.data.hasOwnProperty('id_roles')) {
|
||||||
|
// Do not display confirmation prompt.
|
||||||
|
var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_delete_extra_period';
|
||||||
|
var data = {
|
||||||
|
csrfToken: GlobalVariables.csrfToken,
|
||||||
|
extra_period: lastFocusedEventData.start.format('YYYY-MM-DD'),
|
||||||
|
provider_id: lastFocusedEventData.data.id
|
||||||
|
};
|
||||||
|
|
||||||
|
$.post(url, data, function (response) {
|
||||||
|
$('#message_box').dialog('close');
|
||||||
|
|
||||||
|
if (response.exceptions) {
|
||||||
|
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||||
|
GeneralFunctions.displayMessageBox(GeneralFunctions.EXCEPTIONS_TITLE, GeneralFunctions.EXCEPTIONS_MESSAGE);
|
||||||
|
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.warnings) {
|
||||||
|
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||||
|
GeneralFunctions.displayMessageBox(GeneralFunctions.WARNINGS_TITLE, GeneralFunctions.WARNINGS_MESSAGE);
|
||||||
|
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||||
|
}
|
||||||
|
|
||||||
|
var extraWorkingPlan = jQuery.parseJSON(lastFocusedEventData.data.settings.extra_working_plan);
|
||||||
|
delete extraWorkingPlan[lastFocusedEventData.start.format('YYYY-MM-DD')];
|
||||||
|
lastFocusedEventData.data.settings.extra_working_plan = JSON.stringify(extraWorkingPlan);
|
||||||
|
|
||||||
|
// Refresh calendar event items.
|
||||||
|
$('#select-filter-item').trigger('change');
|
||||||
|
}, 'json').fail(GeneralFunctions.ajaxFailureHandler);
|
||||||
|
}
|
||||||
|
else if (lastFocusedEventData.data.is_unavailable == false) {
|
||||||
var buttons = [
|
var buttons = [
|
||||||
{
|
{
|
||||||
text: 'OK',
|
text: 'OK',
|
||||||
|
@ -302,6 +336,36 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {};
|
||||||
'<button class="delete-popover btn btn-danger ' + displayDelete + '">' + EALang.delete + '</button>' +
|
'<button class="delete-popover btn btn-danger ' + displayDelete + '">' + EALang.delete + '</button>' +
|
||||||
'<button class="close-popover btn btn-default" data-po=' + jsEvent.target + '>' + EALang.close + '</button>' +
|
'<button class="close-popover btn btn-default" data-po=' + jsEvent.target + '>' + EALang.close + '</button>' +
|
||||||
'</center>';
|
'</center>';
|
||||||
|
} else if ($(this).hasClass('fc-extra') || $parent.hasClass('fc-extra') || $altParent.hasClass('fc-extra')) {
|
||||||
|
displayDelete = (($parent.hasClass('fc-custom') || $altParent.hasClass('fc-custom'))
|
||||||
|
&& GlobalVariables.user.privileges.appointments.delete == true)
|
||||||
|
? '' : 'hide'; // Same value at the time.
|
||||||
|
|
||||||
|
var provider = '';
|
||||||
|
if (event.data) { // Only custom unavailable periods have notes.
|
||||||
|
provider = '<strong>' + EALang.provider + '</strong> ' + event.data.first_name + ' ' + event.data.last_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var extra_period = jQuery.parseJSON(event.data.settings.extra_working_plan)[event.start.format()];
|
||||||
|
|
||||||
|
html =
|
||||||
|
'<style type="text/css">'
|
||||||
|
+ '.popover-content strong {min-width: 80px; display:inline-block;}'
|
||||||
|
+ '.popover-content button {margin-right: 10px;}'
|
||||||
|
+ '</style>' +
|
||||||
|
'<strong>' + EALang.start + '</strong> '
|
||||||
|
+ GeneralFunctions.formatDate(event.start.format() + ' ' + extra_period.start, GlobalVariables.dateFormat, true)
|
||||||
|
+ '<br>' +
|
||||||
|
'<strong>' + EALang.end + '</strong> '
|
||||||
|
+ GeneralFunctions.formatDate(event.start.format() + ' ' + extra_period.end, GlobalVariables.dateFormat, true)
|
||||||
|
+ '<br>'
|
||||||
|
+ provider
|
||||||
|
+ '<hr>' +
|
||||||
|
'<center>' +
|
||||||
|
'<button class="delete-popover btn btn-danger ' + displayDelete + '">' + EALang.delete + '</button>' +
|
||||||
|
'<button class="close-popover btn btn-default" data-po=' + jsEvent.target + '>' + EALang.close + '</button>' +
|
||||||
|
'</center>';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
displayEdit = (GlobalVariables.user.privileges.appointments.edit == true)
|
displayEdit = (GlobalVariables.user.privileges.appointments.edit == true)
|
||||||
? '' : 'hide';
|
? '' : 'hide';
|
||||||
|
@ -796,6 +860,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {};
|
||||||
$.each(GlobalVariables.availableProviders, function (index, provider) {
|
$.each(GlobalVariables.availableProviders, function (index, provider) {
|
||||||
if (provider.id == recordId) {
|
if (provider.id == recordId) {
|
||||||
var workingPlan = jQuery.parseJSON(provider.settings.working_plan);
|
var workingPlan = jQuery.parseJSON(provider.settings.working_plan);
|
||||||
|
var extraWorkingPlan = jQuery.parseJSON(provider.settings.extra_working_plan);
|
||||||
var unavailablePeriod;
|
var unavailablePeriod;
|
||||||
|
|
||||||
switch (calendarView) {
|
switch (calendarView) {
|
||||||
|
@ -824,6 +889,29 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {};
|
||||||
$calendar.fullCalendar('renderEvent', unavailablePeriod, false);
|
$calendar.fullCalendar('renderEvent', unavailablePeriod, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Extra working plan day.
|
||||||
|
var selectedDay = $calendar.fullCalendar('getView').intervalStart.clone();
|
||||||
|
selectedDay.locale('en');
|
||||||
|
if (extraWorkingPlan != null && selectedDay.format() in extraWorkingPlan) {
|
||||||
|
workingPlan[selectedDay.format('dddd').toLowerCase()] = extraWorkingPlan[selectedDay.format('YYYY-MM-DD')];
|
||||||
|
|
||||||
|
var start_extra = selectedDay.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[selectedDay.format('YYYY-MM-DD')].start;
|
||||||
|
var end_extra = selectedDay.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[selectedDay.format('YYYY-MM-DD')].end;
|
||||||
|
|
||||||
|
var extraPeriod = {
|
||||||
|
title: EALang.extra_period,
|
||||||
|
start: moment(start_extra, 'YYYY-MM-DD HH:mm', true),
|
||||||
|
end: moment(end_extra, 'YYYY-MM-DD HH:mm', true).add(1, 'day'),
|
||||||
|
allDay: true,
|
||||||
|
color: '#879DB4',
|
||||||
|
editable: false,
|
||||||
|
className: 'fc-extra fc-custom',
|
||||||
|
data: provider
|
||||||
|
};
|
||||||
|
|
||||||
|
$calendar.fullCalendar('renderEvent', extraPeriod, false);
|
||||||
|
}
|
||||||
|
|
||||||
// Non-working day.
|
// Non-working day.
|
||||||
if (workingPlan[selectedDayName] == null) {
|
if (workingPlan[selectedDayName] == null) {
|
||||||
unavailablePeriod = {
|
unavailablePeriod = {
|
||||||
|
@ -942,22 +1030,43 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {};
|
||||||
|
|
||||||
$.each(workingPlan, function (index, workingDay) {
|
$.each(workingPlan, function (index, workingDay) {
|
||||||
if (workingDay == null) {
|
if (workingDay == null) {
|
||||||
// Add a full day unavailable event.
|
// Check if the day is an extra working day added to the working plan
|
||||||
unavailablePeriod = {
|
if (extraWorkingPlan != null && currentDateStart.format('YYYY-MM-DD') in extraWorkingPlan) {
|
||||||
title: EALang.not_working,
|
workingDay = extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')]
|
||||||
start: moment(currentDateStart.format('YYYY-MM-DD')),
|
|
||||||
end: moment(currentDateEnd.format('YYYY-MM-DD')),
|
|
||||||
allDay: false,
|
|
||||||
color: '#BEBEBE',
|
|
||||||
editable: false,
|
|
||||||
className: 'fc-unavailable'
|
|
||||||
};
|
|
||||||
|
|
||||||
$calendar.fullCalendar('renderEvent', unavailablePeriod, true);
|
var start_extra = currentDateStart.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')].start;
|
||||||
currentDateStart.add(1, 'days');
|
var end_extra = currentDateStart.format('YYYY-MM-DD') + ' ' + extraWorkingPlan[currentDateStart.format('YYYY-MM-DD')].end;
|
||||||
currentDateEnd.add(1, 'days');
|
|
||||||
|
|
||||||
return; // Go to the next loop.
|
var extraPeriod = {
|
||||||
|
title: EALang.extra_period,
|
||||||
|
start: moment(start_extra, 'YYYY-MM-DD HH:mm', true),
|
||||||
|
end: moment(end_extra, 'YYYY-MM-DD HH:mm', true).add(1, 'day'),
|
||||||
|
allDay: true,
|
||||||
|
color: '#879DB4',
|
||||||
|
editable: false,
|
||||||
|
className: 'fc-extra fc-custom',
|
||||||
|
data: provider
|
||||||
|
};
|
||||||
|
|
||||||
|
$calendar.fullCalendar('renderEvent', extraPeriod, false);
|
||||||
|
} else {
|
||||||
|
// Add a full day unavailable event.
|
||||||
|
unavailablePeriod = {
|
||||||
|
title: EALang.not_working,
|
||||||
|
start: moment(currentDateStart.format('YYYY-MM-DD')),
|
||||||
|
end: moment(currentDateEnd.format('YYYY-MM-DD')),
|
||||||
|
allDay: false,
|
||||||
|
color: '#BEBEBE',
|
||||||
|
editable: false,
|
||||||
|
className: 'fc-unavailable'
|
||||||
|
};
|
||||||
|
|
||||||
|
$calendar.fullCalendar('renderEvent', unavailablePeriod, true);
|
||||||
|
currentDateStart.add(1, 'days');
|
||||||
|
currentDateEnd.add(1, 'days');
|
||||||
|
|
||||||
|
return; // Go to the next loop.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var start;
|
var start;
|
||||||
|
|
253
src/assets/js/backend_calendar_extra_periods_modal.js
Normal file
253
src/assets/js/backend_calendar_extra_periods_modal.js
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Easy!Appointments - Open Source Web Scheduler
|
||||||
|
*
|
||||||
|
* @package EasyAppointments
|
||||||
|
* @author A.Tselegidis <alextselegidis@gmail.com>
|
||||||
|
* @copyright Copyright (c) 2013 - 2017, Alex Tselegidis
|
||||||
|
* @license http://opensource.org/licenses/GPL-3.0 - GPLv3
|
||||||
|
* @link http://easyappointments.org
|
||||||
|
* @since v1.2.0
|
||||||
|
* ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend Calendar Extra Periods Modal
|
||||||
|
*
|
||||||
|
* This module implements the extra periods modal functionality.
|
||||||
|
*
|
||||||
|
* @module BackendCalendarExtraPeriodsModal
|
||||||
|
*/
|
||||||
|
window.BackendCalendarExtraPeriodsModal = window.BackendCalendarExtraPeriodsModal || {};
|
||||||
|
|
||||||
|
(function (exports) {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function _bindEventHandlers() {
|
||||||
|
/**
|
||||||
|
* Event: Manage extra Dialog Save Button "Click"
|
||||||
|
*
|
||||||
|
* Stores the extra period changes or inserts a new record.
|
||||||
|
*/
|
||||||
|
$('#manage-extra #save-extra').click(function () {
|
||||||
|
var $dialog = $('#manage-extra');
|
||||||
|
$dialog.find('.has-error').removeClass('has-error');
|
||||||
|
var start = $dialog.find('#extra-start').datetimepicker('getDate');
|
||||||
|
var end = Date.parse($dialog.find('#extra-end').datetimepicker('getDate'));
|
||||||
|
|
||||||
|
if (start.toString('HH:mm') > end.toString('HH:mm')) {
|
||||||
|
// Start time is after end time - display message to user.
|
||||||
|
$dialog.find('.modal-message')
|
||||||
|
.text(EALang.start_date_before_end_error)
|
||||||
|
.addClass('alert-danger')
|
||||||
|
.removeClass('hidden');
|
||||||
|
|
||||||
|
$dialog.find('#extra-start, #extra-end').closest('.form-group').addClass('has-error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extra period records go to the appointments table.
|
||||||
|
var extra = {
|
||||||
|
start_datetime: start.toString('yyyy-MM-dd HH:mm'),
|
||||||
|
end_datetime: start.toString('yyyy-MM-dd') + ' ' + end.toString('HH:mm'),
|
||||||
|
id_users_provider: $('#extra-provider').val() // curr provider
|
||||||
|
};
|
||||||
|
|
||||||
|
//if ($dialog.find('#extra-id').val() !== '') {
|
||||||
|
// // Set the id value, only if we are editing an appointment.
|
||||||
|
// extra.id = $dialog.find('#extra-id').val();
|
||||||
|
//}
|
||||||
|
|
||||||
|
var successCallback = function (response) {
|
||||||
|
if (response.exceptions) {
|
||||||
|
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||||
|
GeneralFunctions.displayMessageBox(GeneralFunctions.EXCEPTIONS_TITLE,
|
||||||
|
GeneralFunctions.EXCEPTIONS_MESSAGE);
|
||||||
|
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||||
|
|
||||||
|
$dialog.find('.modal-message')
|
||||||
|
.text(EALang.unexpected_issues_occurred)
|
||||||
|
.addClass('alert-danger')
|
||||||
|
.removeClass('hidden');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.warnings) {
|
||||||
|
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||||
|
GeneralFunctions.displayMessageBox(GeneralFunctions.WARNINGS_TITLE,
|
||||||
|
GeneralFunctions.WARNINGS_MESSAGE);
|
||||||
|
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display success message to the user.
|
||||||
|
$dialog.find('.modal-message')
|
||||||
|
.text(EALang.extra_period_saved)
|
||||||
|
.addClass('alert-success')
|
||||||
|
.removeClass('alert-danger hidden');
|
||||||
|
|
||||||
|
// Close the modal dialog and refresh the calendar appointments after one second.
|
||||||
|
setTimeout(function () {
|
||||||
|
$dialog.find('.alert').addClass('hidden');
|
||||||
|
$dialog.modal('hide');
|
||||||
|
|
||||||
|
var providerId = $('#extra-provider').val();
|
||||||
|
var provider = GlobalVariables.availableProviders.filter(function (p) {
|
||||||
|
return p.id === providerId;
|
||||||
|
})[0];
|
||||||
|
var providerIdx = GlobalVariables.availableProviders.indexOf(provider);
|
||||||
|
|
||||||
|
var extraWorkingPlan = jQuery.parseJSON(provider.settings.extra_working_plan);
|
||||||
|
extraWorkingPlan[start.toString('yyyy-MM-dd')] = {
|
||||||
|
start: start.toString('HH:mm'),
|
||||||
|
end: end.toString('HH:mm'),
|
||||||
|
breaks: []
|
||||||
|
};
|
||||||
|
provider.settings.extra_working_plan = JSON.stringify(extraWorkingPlan);
|
||||||
|
GlobalVariables.availableProviders[providerIdx] = provider;
|
||||||
|
|
||||||
|
$('#select-filter-item').trigger('change');
|
||||||
|
}, 2000);
|
||||||
|
};
|
||||||
|
|
||||||
|
var errorCallback = function (jqXHR, textStatus, errorThrown) {
|
||||||
|
GeneralFunctions.displayMessageBox('Communication Error', 'Unfortunately ' +
|
||||||
|
'the operation could not complete due to server communication errors.');
|
||||||
|
|
||||||
|
$dialog.find('.modal-message').txt(EALang.service_communication_error);
|
||||||
|
$dialog.find('.modal-message').addClass('alert-danger').removeClass('hidden');
|
||||||
|
};
|
||||||
|
|
||||||
|
BackendCalendarApi.saveExtraPeriod(extra, successCallback, errorCallback);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event: Manage extra Dialog Cancel Button "Click"
|
||||||
|
*
|
||||||
|
* Closes the dialog without saveing any changes to the database.
|
||||||
|
*/
|
||||||
|
$('#manage-extra #cancel-extra').click(function () {
|
||||||
|
$('#manage-extra').modal('hide');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event : Insert extra Time Period Button "Click"
|
||||||
|
*
|
||||||
|
* When the user clicks this button a popup dialog appears and the use can set a time period where
|
||||||
|
* he cannot accept any appointments.
|
||||||
|
*/
|
||||||
|
$('#insert-extra-period').click(function () {
|
||||||
|
BackendCalendarExtraPeriodsModal.resetExtraDialog();
|
||||||
|
var $dialog = $('#manage-extra');
|
||||||
|
|
||||||
|
// Set the default datetime values.
|
||||||
|
var start = new Date();
|
||||||
|
start.addDays(1);
|
||||||
|
start.set({'hour': 8});
|
||||||
|
start.set({'minute': 30});
|
||||||
|
|
||||||
|
if ($('.calendar-view').length === 0) {
|
||||||
|
$dialog.find('#extra-provider')
|
||||||
|
.val($('#select-filter-item').val())
|
||||||
|
.closest('.form-group')
|
||||||
|
.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialog.find('#extra-start').val(GeneralFunctions.formatDate(start, GlobalVariables.dateFormat, true));
|
||||||
|
$dialog.find('#extra-end').val((GlobalVariables.timeFormat === 'h:mm tt') ? '8:00 PM' : '19:00');
|
||||||
|
$dialog.find('.modal-header h3').text(EALang.new_extra_period_title);
|
||||||
|
$dialog.modal('show');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset extra dialog form.
|
||||||
|
*
|
||||||
|
* Reset the "#manage-extra" dialog. Use this method to bring the dialog to the initial state
|
||||||
|
* before it becomes visible to the user.
|
||||||
|
*/
|
||||||
|
exports.resetExtraDialog = function () {
|
||||||
|
var $dialog = $('#manage-extra');
|
||||||
|
|
||||||
|
$dialog.find('#extra-id').val('');
|
||||||
|
|
||||||
|
// Set the default datetime values.
|
||||||
|
var start = new Date();
|
||||||
|
start.addDays(1);
|
||||||
|
start.set({'hour': 8});
|
||||||
|
start.set({'minute': 30});
|
||||||
|
|
||||||
|
var dateFormat;
|
||||||
|
|
||||||
|
switch (GlobalVariables.dateFormat) {
|
||||||
|
case 'DMY':
|
||||||
|
dateFormat = 'dd/mm/yy';
|
||||||
|
break;
|
||||||
|
case 'MDY':
|
||||||
|
dateFormat = 'mm/dd/yy';
|
||||||
|
break;
|
||||||
|
case 'YMD':
|
||||||
|
dateFormat = 'yy/mm/dd';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$dialog.find('#extra-start').datetimepicker({
|
||||||
|
dateFormat: dateFormat,
|
||||||
|
timeFormat: (GlobalVariables.timeFormat === 'h:mm tt') ? 'h:mm TT' : GlobalVariables.timeFormat,
|
||||||
|
|
||||||
|
// Translation
|
||||||
|
dayNames: [EALang.sunday, EALang.monday, EALang.tuesday, EALang.wednesday,
|
||||||
|
EALang.thursday, EALang.friday, EALang.saturday],
|
||||||
|
dayNamesShort: [EALang.sunday.substr(0, 3), EALang.monday.substr(0, 3),
|
||||||
|
EALang.tuesday.substr(0, 3), EALang.wednesday.substr(0, 3),
|
||||||
|
EALang.thursday.substr(0, 3), EALang.friday.substr(0, 3),
|
||||||
|
EALang.saturday.substr(0, 3)],
|
||||||
|
dayNamesMin: [EALang.sunday.substr(0, 2), EALang.monday.substr(0, 2),
|
||||||
|
EALang.tuesday.substr(0, 2), EALang.wednesday.substr(0, 2),
|
||||||
|
EALang.thursday.substr(0, 2), EALang.friday.substr(0, 2),
|
||||||
|
EALang.saturday.substr(0, 2)],
|
||||||
|
monthNames: [EALang.january, EALang.february, EALang.march, EALang.april,
|
||||||
|
EALang.may, EALang.june, EALang.july, EALang.august, EALang.september,
|
||||||
|
EALang.october, EALang.november, EALang.december],
|
||||||
|
prevText: EALang.previous,
|
||||||
|
nextText: EALang.next,
|
||||||
|
currentText: EALang.now,
|
||||||
|
closeText: EALang.close,
|
||||||
|
timeOnlyTitle: EALang.select_time,
|
||||||
|
timeText: EALang.time,
|
||||||
|
hourText: EALang.hour,
|
||||||
|
minuteText: EALang.minutes,
|
||||||
|
firstDay: 0
|
||||||
|
});
|
||||||
|
$dialog.find('#extra-start').val(GeneralFunctions.formatDate(start, GlobalVariables.dateFormat, true));
|
||||||
|
$dialog.find('#extra-start').draggable();
|
||||||
|
|
||||||
|
$dialog.find('#extra-end').timepicker({
|
||||||
|
timeFormat: (GlobalVariables.timeFormat === 'h:mm tt') ? 'h:mm TT' : GlobalVariables.timeFormat,
|
||||||
|
currentText: EALang.now,
|
||||||
|
closeText: EALang.close,
|
||||||
|
timeOnlyTitle: EALang.select_time,
|
||||||
|
timeText: EALang.time,
|
||||||
|
hourText: EALang.hour,
|
||||||
|
minuteText: EALang.minutes
|
||||||
|
});
|
||||||
|
$dialog.find('#extra-end').val((GlobalVariables.timeFormat === 'h:mm tt') ? '8:00 PM' : '19:00');
|
||||||
|
$dialog.find('#extra-end').draggable();
|
||||||
|
|
||||||
|
// Clear the extra notes field.
|
||||||
|
$dialog.find('#extra-notes').val('');
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.initialize = function () {
|
||||||
|
var extraProvider = $('#extra-provider');
|
||||||
|
|
||||||
|
for (var index in GlobalVariables.availableProviders) {
|
||||||
|
var provider = GlobalVariables.availableProviders[index];
|
||||||
|
|
||||||
|
extraProvider.append(new Option(provider.first_name + ' ' + provider.last_name, provider.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
_bindEventHandlers();
|
||||||
|
};
|
||||||
|
|
||||||
|
})(window.BackendCalendarExtraPeriodsModal);
|
14
src/assets/js/backend_users_providers.js
Normal file → Executable file
14
src/assets/js/backend_users_providers.js
Normal file → Executable file
|
@ -92,7 +92,7 @@
|
||||||
$('#providers .record-details').find('select').prop('disabled', false);
|
$('#providers .record-details').find('select').prop('disabled', false);
|
||||||
$('#provider-password, #provider-password-confirm').addClass('required');
|
$('#provider-password, #provider-password-confirm').addClass('required');
|
||||||
$('#provider-notifications').prop('disabled', false);
|
$('#provider-notifications').prop('disabled', false);
|
||||||
$('#providers').find('.add-break, .edit-break, .delete-break, #reset-working-plan').prop('disabled', false);
|
$('#providers').find('.add-break, .edit-break, .delete-break, .add-extra-periods, .edit-extra, .delete-extra, #reset-working-plan').prop('disabled', false);
|
||||||
$('#provider-services input:checkbox').prop('disabled', false);
|
$('#provider-services input:checkbox').prop('disabled', false);
|
||||||
$('#providers input:checkbox').prop('disabled', false);
|
$('#providers input:checkbox').prop('disabled', false);
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
$('#provider-password, #provider-password-confirm').removeClass('required');
|
$('#provider-password, #provider-password-confirm').removeClass('required');
|
||||||
$('#provider-notifications').prop('disabled', false);
|
$('#provider-notifications').prop('disabled', false);
|
||||||
$('#provider-services input:checkbox').prop('disabled', false);
|
$('#provider-services input:checkbox').prop('disabled', false);
|
||||||
$('#providers').find('.add-break, .edit-break, .delete-break, #reset-working-plan').prop('disabled', false);
|
$('#providers').find('.add-break, .edit-break, .delete-break, .add-extra-periods, .edit-extra, .delete-extra, #reset-working-plan').prop('disabled', false);
|
||||||
$('#providers input:checkbox').prop('disabled', false);
|
$('#providers input:checkbox').prop('disabled', false);
|
||||||
BackendUsers.wp.timepickers(false);
|
BackendUsers.wp.timepickers(false);
|
||||||
});
|
});
|
||||||
|
@ -163,6 +163,7 @@
|
||||||
settings: {
|
settings: {
|
||||||
username: $('#provider-username').val(),
|
username: $('#provider-username').val(),
|
||||||
working_plan: JSON.stringify(BackendUsers.wp.get()),
|
working_plan: JSON.stringify(BackendUsers.wp.get()),
|
||||||
|
extra_working_plan: JSON.stringify(BackendUsers.wp.getExtraWP()),
|
||||||
notifications: $('#provider-notifications').hasClass('active'),
|
notifications: $('#provider-notifications').hasClass('active'),
|
||||||
calendar_view: $('#provider-calendar-view').val()
|
calendar_view: $('#provider-calendar-view').val()
|
||||||
}
|
}
|
||||||
|
@ -233,6 +234,7 @@
|
||||||
*/
|
*/
|
||||||
$('#providers').on('click', '#reset-working-plan', function () {
|
$('#providers').on('click', '#reset-working-plan', function () {
|
||||||
$('.breaks tbody').empty();
|
$('.breaks tbody').empty();
|
||||||
|
$('.extra-periods tbody').empty();
|
||||||
$('.work-start, .work-end').val('');
|
$('.work-start, .work-end').val('');
|
||||||
BackendUsers.wp.setup(GlobalVariables.workingPlan);
|
BackendUsers.wp.setup(GlobalVariables.workingPlan);
|
||||||
BackendUsers.wp.timepickers(false);
|
BackendUsers.wp.timepickers(false);
|
||||||
|
@ -357,11 +359,12 @@
|
||||||
$('#provider-notifications').removeClass('active');
|
$('#provider-notifications').removeClass('active');
|
||||||
$('#provider-notifications').prop('disabled', true);
|
$('#provider-notifications').prop('disabled', true);
|
||||||
$('#provider-services input:checkbox').prop('disabled', true);
|
$('#provider-services input:checkbox').prop('disabled', true);
|
||||||
$('#providers .add-break, #reset-working-plan').prop('disabled', true);
|
$('#providers .add-break, .add-extra-periods, #reset-working-plan').prop('disabled', true);
|
||||||
BackendUsers.wp.timepickers(true);
|
BackendUsers.wp.timepickers(true);
|
||||||
$('#providers .working-plan input:text').timepicker('destroy');
|
$('#providers .working-plan input:text').timepicker('destroy');
|
||||||
$('#providers .working-plan input:checkbox').prop('disabled', true);
|
$('#providers .working-plan input:checkbox').prop('disabled', true);
|
||||||
$('.breaks').find('.edit-break, .delete-break').prop('disabled', true);
|
$('.breaks').find('.edit-break, .delete-break').prop('disabled', true);
|
||||||
|
$('.extra-periods').find('.edit-extra, .delete-extra').prop('disabled', true);
|
||||||
|
|
||||||
$('#edit-provider, #delete-provider').prop('disabled', true);
|
$('#edit-provider, #delete-provider').prop('disabled', true);
|
||||||
$('#providers .record-details').find('input, textarea').val('');
|
$('#providers .record-details').find('input, textarea').val('');
|
||||||
|
@ -369,6 +372,7 @@
|
||||||
$('#provider-services input:checkbox').prop('checked', false);
|
$('#provider-services input:checkbox').prop('checked', false);
|
||||||
$('#provider-services a').remove();
|
$('#provider-services a').remove();
|
||||||
$('#providers .breaks tbody').empty();
|
$('#providers .breaks tbody').empty();
|
||||||
|
$('#providers .extra-periods tbody').empty();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -426,6 +430,10 @@
|
||||||
var workingPlan = $.parseJSON(provider.settings.working_plan);
|
var workingPlan = $.parseJSON(provider.settings.working_plan);
|
||||||
BackendUsers.wp.setup(workingPlan);
|
BackendUsers.wp.setup(workingPlan);
|
||||||
$('.breaks').find('.edit-break, .delete-break').prop('disabled', true);
|
$('.breaks').find('.edit-break, .delete-break').prop('disabled', true);
|
||||||
|
$('#providers .extra-periods tbody').empty();
|
||||||
|
var extraWorkingPlan = $.parseJSON(provider.settings.extra_working_plan);
|
||||||
|
BackendUsers.wp.setupExtraPeriods(extraWorkingPlan);
|
||||||
|
$('.extra-periods').find('.edit-extra, .delete-extra').prop('disabled', true);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -431,4 +431,35 @@ window.GeneralFunctions = window.GeneralFunctions || {};
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a given date according to ISO 8601 date format string yyyy-mm-dd
|
||||||
|
* @param {String} date The date to be formatted.
|
||||||
|
* @param {String} dateFormatSetting The setting provided by PHP must be one of
|
||||||
|
* the "DMY", "MDY" or "YMD".
|
||||||
|
* @returns {String} Returns the formatted date string.
|
||||||
|
*/
|
||||||
|
exports.ISO8601DateString = function (date, dateFormatSetting) {
|
||||||
|
var dayArray;
|
||||||
|
|
||||||
|
// It's necessary to manually parse the date because Date.parse() not support
|
||||||
|
// some formats tha instead are supported by Easy!Appointments
|
||||||
|
// The unsupported format is dd/MM/yyyy
|
||||||
|
switch (dateFormatSetting) {
|
||||||
|
case 'DMY':
|
||||||
|
dayArray = date.split('/');
|
||||||
|
date = dayArray[2] + '-' + dayArray[1] + '-' + dayArray[0];
|
||||||
|
break;
|
||||||
|
case 'MDY':
|
||||||
|
dayArray = date.split('/');
|
||||||
|
date = dayArray[2] + '-' + dayArray[0] + '-' + dayArray[1];
|
||||||
|
break;
|
||||||
|
case 'YMD':
|
||||||
|
date = date.replace('/','-');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Invalid date format setting provided!', dateFormatSetting);
|
||||||
|
}
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
})(window.GeneralFunctions);
|
})(window.GeneralFunctions);
|
||||||
|
|
|
@ -89,6 +89,54 @@
|
||||||
this.editableBreakTime($('.breaks').find('.break-start, .break-end'));
|
this.editableBreakTime($('.breaks').find('.break-start, .break-end'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the dom elements of a given extra working plan day.
|
||||||
|
*
|
||||||
|
* @param {Object} extraWorkingPlan Contains the extra working day.
|
||||||
|
*/
|
||||||
|
WorkingPlan.prototype.setupExtraPeriods = function (extraWorkingPlan) {
|
||||||
|
$.each(extraWorkingPlan, function (index, extraWorkingDay) {
|
||||||
|
if (extraWorkingDay != null) {
|
||||||
|
|
||||||
|
$('#' + index).prop('checked', true);
|
||||||
|
$('#' + index + '-start').val(Date.parse(extraWorkingDay.start).toString(GlobalVariables.timeFormat).toUpperCase());
|
||||||
|
$('#' + index + '-end').val(Date.parse(extraWorkingDay.end).toString(GlobalVariables.timeFormat).toUpperCase());
|
||||||
|
|
||||||
|
var day = GeneralFunctions.formatDate(Date.parse(index), GlobalVariables.dateFormat, false);
|
||||||
|
|
||||||
|
var tr =
|
||||||
|
'<tr>' +
|
||||||
|
'<td class="extra-day editable">' + day + '</td>' +
|
||||||
|
'<td class="extra-start editable">' + Date.parse(extraWorkingDay.start).toString(GlobalVariables.timeFormat).toUpperCase() + '</td>' +
|
||||||
|
'<td class="extra-end editable">' + Date.parse(extraWorkingDay.end).toString(GlobalVariables.timeFormat).toUpperCase() + '</td>' +
|
||||||
|
'<td>' +
|
||||||
|
'<button type="button" class="btn btn-default btn-sm edit-extra" title="' + EALang.edit + '">' +
|
||||||
|
'<span class="glyphicon glyphicon-pencil"></span>' +
|
||||||
|
'</button>' +
|
||||||
|
'<button type="button" class="btn btn-default btn-sm delete-extra" title="' + EALang.delete + '">' +
|
||||||
|
'<span class="glyphicon glyphicon-remove"></span>' +
|
||||||
|
'</button>' +
|
||||||
|
'<button type="button" class="btn btn-default btn-sm save-extra hidden" title="' + EALang.save + '">' +
|
||||||
|
'<span class="glyphicon glyphicon-ok"></span>' +
|
||||||
|
'</button>' +
|
||||||
|
'<button type="button" class="btn btn-default btn-sm cancel-extra hidden" title="' + EALang.cancel + '">' +
|
||||||
|
'<span class="glyphicon glyphicon-ban-circle"></span>' +
|
||||||
|
'</button>' +
|
||||||
|
'</td>' +
|
||||||
|
'</tr>';
|
||||||
|
$('.extra-periods tbody').append(tr);
|
||||||
|
} else {
|
||||||
|
$('#' + index).prop('checked', false);
|
||||||
|
$('#' + index + '-start').prop('disabled', true);
|
||||||
|
$('#' + index + '-end').prop('disabled', true);
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
// Make break cells editable.
|
||||||
|
this.editableBreakTime($('.extra-periods .extra-day'));
|
||||||
|
this.editableBreakTime($('.extra-periods').find('.extra-start, .extra-end'));
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable editable break day.
|
* Enable editable break day.
|
||||||
*
|
*
|
||||||
|
@ -306,6 +354,172 @@
|
||||||
$(element).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
|
$(element).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
|
||||||
$('.add-break').prop('disabled', false);
|
$('.add-break').prop('disabled', false);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event: Add Extra Period Button "Click"
|
||||||
|
*
|
||||||
|
* A new row is added on the table and the user can enter the new extra day
|
||||||
|
* data. After that he can either press the save or cancel button.
|
||||||
|
*/
|
||||||
|
$('.add-extra-periods').click(function () {
|
||||||
|
var today = GeneralFunctions.formatDate(new Date(), GlobalVariables.dateFormat, false);
|
||||||
|
var tr =
|
||||||
|
'<tr>' +
|
||||||
|
'<td class="extra-day editable">' + today + '</td>' +
|
||||||
|
'<td class="extra-start editable">' + ((GlobalVariables.timeFormat === 'h:mm tt') ? '9:00 AM' : '09:00') + '</td>' +
|
||||||
|
'<td class="extra-end editable">' + ((GlobalVariables.timeFormat === 'h:mm tt') ? '10:00 AM' : '10:00') + '</td>' +
|
||||||
|
'<td>' +
|
||||||
|
'<button type="button" class="btn btn-default btn-sm edit-extra" title="' + EALang.edit + '">' +
|
||||||
|
'<span class="glyphicon glyphicon-pencil"></span>' +
|
||||||
|
'</button>' +
|
||||||
|
'<button type="button" class="btn btn-default btn-sm delete-extra" title="' + EALang.delete + '">' +
|
||||||
|
'<span class="glyphicon glyphicon-remove"></span>' +
|
||||||
|
'</button>' +
|
||||||
|
'<button type="button" class="btn btn-default btn-sm save-extra hidden" title="' + EALang.save + '">' +
|
||||||
|
'<span class="glyphicon glyphicon-ok"></span>' +
|
||||||
|
'</button>' +
|
||||||
|
'<button type="button" class="btn btn-default btn-sm cancel-extra hidden" title="' + EALang.cancel + '">' +
|
||||||
|
'<span class="glyphicon glyphicon-ban-circle"></span>' +
|
||||||
|
'</button>' +
|
||||||
|
'</td>' +
|
||||||
|
'</tr>';
|
||||||
|
$('.extra-periods').prepend(tr);
|
||||||
|
|
||||||
|
// Bind editable and event handlers.
|
||||||
|
tr = $('.extra-periods tr')[1];
|
||||||
|
this.editableBreakTime($(tr).find('.extra-day'));
|
||||||
|
this.editableBreakTime($(tr).find('.extra-start, .extra-end'));
|
||||||
|
$(tr).find('.edit-extra').trigger('click');
|
||||||
|
$('.add-extra-periods').prop('disabled', true);
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event: Edit Extra Period Button "Click"
|
||||||
|
*
|
||||||
|
* Enables the row editing for the "Extra Period" table rows.
|
||||||
|
*/
|
||||||
|
$(document).on('click', '.edit-extra', function () {
|
||||||
|
// Reset previous editable tds
|
||||||
|
var $previousEdt = $(this).closest('table').find('.editable').get();
|
||||||
|
$.each($previousEdt, function (index, editable) {
|
||||||
|
if (editable.reset !== undefined) {
|
||||||
|
editable.reset();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make all cells in current row editable.
|
||||||
|
$(this).parent().parent().children().trigger('edit');
|
||||||
|
$(this).parent().parent().find('.extra-start input, .extra-end input').timepicker({
|
||||||
|
timeFormat: (GlobalVariables.timeFormat === 'h:mm tt') ? 'h:mm TT' : GlobalVariables.timeFormat,
|
||||||
|
currentText: EALang.now,
|
||||||
|
closeText: EALang.close,
|
||||||
|
timeOnlyTitle: EALang.select_time,
|
||||||
|
timeText: EALang.time,
|
||||||
|
hourText: EALang.hour,
|
||||||
|
minuteText: EALang.minutes
|
||||||
|
});
|
||||||
|
|
||||||
|
var dateFormat;
|
||||||
|
|
||||||
|
switch (GlobalVariables.dateFormat) {
|
||||||
|
case 'DMY':
|
||||||
|
dateFormat = 'dd/mm/yy';
|
||||||
|
break;
|
||||||
|
case 'MDY':
|
||||||
|
dateFormat = 'mm/dd/yy';
|
||||||
|
break;
|
||||||
|
case 'YMD':
|
||||||
|
dateFormat = 'yy/mm/dd';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this).parent().parent().find('.extra-day input').datetimepicker({
|
||||||
|
dateFormat: dateFormat,
|
||||||
|
|
||||||
|
// Translation
|
||||||
|
dayNames: [EALang.sunday, EALang.monday, EALang.tuesday, EALang.wednesday,
|
||||||
|
EALang.thursday, EALang.friday, EALang.saturday],
|
||||||
|
dayNamesShort: [EALang.sunday.substr(0, 3), EALang.monday.substr(0, 3),
|
||||||
|
EALang.tuesday.substr(0, 3), EALang.wednesday.substr(0, 3),
|
||||||
|
EALang.thursday.substr(0, 3), EALang.friday.substr(0, 3),
|
||||||
|
EALang.saturday.substr(0, 3)],
|
||||||
|
dayNamesMin: [EALang.sunday.substr(0, 2), EALang.monday.substr(0, 2),
|
||||||
|
EALang.tuesday.substr(0, 2), EALang.wednesday.substr(0, 2),
|
||||||
|
EALang.thursday.substr(0, 2), EALang.friday.substr(0, 2),
|
||||||
|
EALang.saturday.substr(0, 2)],
|
||||||
|
monthNames: [EALang.january, EALang.february, EALang.march, EALang.april,
|
||||||
|
EALang.may, EALang.june, EALang.july, EALang.august, EALang.september,
|
||||||
|
EALang.october, EALang.november, EALang.december],
|
||||||
|
prevText: EALang.previous,
|
||||||
|
nextText: EALang.next,
|
||||||
|
currentText: EALang.now,
|
||||||
|
closeText: EALang.close,
|
||||||
|
firstDay: 1,
|
||||||
|
showTimepicker: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show save - cancel buttons.
|
||||||
|
$(this).closest('table').find('.edit-extra, .delete-extra').addClass('hidden');
|
||||||
|
$(this).parent().find('.save-extra, .cancel-extra').removeClass('hidden');
|
||||||
|
$(this).closest('tr').find('select,input:text').addClass('form-control input-sm')
|
||||||
|
|
||||||
|
$('.add-extra-periods').prop('disabled', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event: Delete Extra Period Button "Click"
|
||||||
|
*
|
||||||
|
* Removes the current line from the "Extra Periods" table.
|
||||||
|
*/
|
||||||
|
$(document).on('click', '.delete-extra', function () {
|
||||||
|
$(this).parent().parent().remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event: Cancel Extra Period Button "Click"
|
||||||
|
*
|
||||||
|
* Bring the ".extra-period" table back to its initial state.
|
||||||
|
*
|
||||||
|
* @param {jQuery.Event} e
|
||||||
|
*/
|
||||||
|
$(document).on('click', '.cancel-extra', function (e) {
|
||||||
|
var element = e.target;
|
||||||
|
var $modifiedRow = $(element).closest('tr');
|
||||||
|
this.enableCancel = true;
|
||||||
|
$modifiedRow.find('.cancel-editable').trigger('click');
|
||||||
|
this.enableCancel = false;
|
||||||
|
|
||||||
|
$(element).closest('table').find('.edit-extra, .delete-extra').removeClass('hidden');
|
||||||
|
$modifiedRow.find('.save-extra, .cancel-extra').addClass('hidden');
|
||||||
|
$('.add-extra-periods').prop('disabled', false);
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event: Save Extra Period Button "Click"
|
||||||
|
*
|
||||||
|
* Save the editable values and restore the table to its initial state.
|
||||||
|
*
|
||||||
|
* @param {jQuery.Event} e
|
||||||
|
*/
|
||||||
|
$(document).on('click', '.save-extra', function (e) {
|
||||||
|
// Break's start time must always be prior to break's end.
|
||||||
|
var element = e.target,
|
||||||
|
$modifiedRow = $(element).closest('tr'),
|
||||||
|
start = Date.parse($modifiedRow.find('.extra-start input').val()),
|
||||||
|
end = Date.parse($modifiedRow.find('.extra-end input').val());
|
||||||
|
|
||||||
|
if (start > end) {
|
||||||
|
$modifiedRow.find('.extra-end input').val(start.addHours(1).toString(GlobalVariables.timeFormat));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.enableSubmit = true;
|
||||||
|
$modifiedRow.find('.editable .submit-editable').trigger('click');
|
||||||
|
this.enableSubmit = false;
|
||||||
|
|
||||||
|
$modifiedRow.find('.save-extra, .cancel-extra').addClass('hidden');
|
||||||
|
$(element).closest('table').find('.edit-extra, .delete-extra').removeClass('hidden');
|
||||||
|
$('.add-extra-periods').prop('disabled', false);
|
||||||
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -350,6 +564,30 @@
|
||||||
return workingPlan;
|
return workingPlan;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the extra working plan settings.
|
||||||
|
*
|
||||||
|
* @return {Object} Returns the extra working plan settings object.
|
||||||
|
*/
|
||||||
|
WorkingPlan.prototype.getExtraWP = function () {
|
||||||
|
var extraWorkingPlan = {};
|
||||||
|
$('.extra-periods tbody tr').each(function (index, tr) {
|
||||||
|
|
||||||
|
var day = GeneralFunctions.ISO8601DateString($(tr).find('.extra-day').text(), GlobalVariables.dateFormat);
|
||||||
|
|
||||||
|
var start = $(tr).find('.extra-start').text();
|
||||||
|
var end = $(tr).find('.extra-end').text();
|
||||||
|
|
||||||
|
extraWorkingPlan[day] = {
|
||||||
|
start: Date.parse(start).toString('HH:mm'),
|
||||||
|
end: Date.parse(end).toString('HH:mm'),
|
||||||
|
breaks: []
|
||||||
|
};
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
return extraWorkingPlan;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables or disables the timepicker functionality from the working plan input text fields.
|
* Enables or disables the timepicker functionality from the working plan input text fields.
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,4 +18,4 @@ VALUES
|
||||||
('time_format', 'regular'),
|
('time_format', 'regular'),
|
||||||
('require_captcha', '0');
|
('require_captcha', '0');
|
||||||
|
|
||||||
INSERT INTO `ea_migrations` VALUES ('10');
|
INSERT INTO `ea_migrations` VALUES ('11');
|
||||||
|
|
1
src/assets/sql/structure.sql
Normal file → Executable file
1
src/assets/sql/structure.sql
Normal file → Executable file
|
@ -129,6 +129,7 @@ CREATE TABLE IF NOT EXISTS `ea_user_settings` (
|
||||||
`password` VARCHAR(512),
|
`password` VARCHAR(512),
|
||||||
`salt` VARCHAR(512),
|
`salt` VARCHAR(512),
|
||||||
`working_plan` TEXT,
|
`working_plan` TEXT,
|
||||||
|
`extra_working_plan` TEXT,
|
||||||
`notifications` TINYINT(4) DEFAULT '0',
|
`notifications` TINYINT(4) DEFAULT '0',
|
||||||
`google_sync` TINYINT(4) DEFAULT '0',
|
`google_sync` TINYINT(4) DEFAULT '0',
|
||||||
`google_token` TEXT,
|
`google_token` TEXT,
|
||||||
|
|
Loading…
Reference in a new issue