diff --git a/application/controllers/settings/Business_logic.php b/application/controllers/settings/Business_logic.php new file mode 100644 index 00000000..1142e28e --- /dev/null +++ b/application/controllers/settings/Business_logic.php @@ -0,0 +1,114 @@ + + * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis + * @license https://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link https://easyappointments.org + * @since v1.5.0 + * ---------------------------------------------------------------------------- */ + +/** + * Business logic controller. + * + * Handles general settings related operations. + * + * @package Controllers + */ +class Business_logic extends EA_Controller { + /** + * @var array + */ + protected $permissions; + + /** + * Business_logic constructor. + */ + public function __construct() + { + parent::__construct(); + + $this->load->model('appointments_model'); + $this->load->model('customers_model'); + $this->load->model('services_model'); + $this->load->model('providers_model'); + $this->load->model('roles_model'); + $this->load->model('settings_model'); + + $this->load->library('accounts'); + $this->load->library('google_sync'); + $this->load->library('notifications'); + $this->load->library('synchronization'); + $this->load->library('timezones'); + + $role_slug = session('role_slug'); + + if ($role_slug) + { + $this->permissions = $this->roles_model->get_permissions_by_slug($role_slug); + } + } + + /** + * Render the settings page. + */ + public function index() + { + session(['dest_url' => site_url('services')]); + + if (cannot('view', 'services')) + { + show_error('Forbidden', 403); + } + + $user_id = session('user_id'); + + $role_slug = session('role_slug'); + + $this->load->view('pages/settings/business_logic/business_logic_page', [ + 'page_title' => lang('settings'), + 'active_menu' => PRIV_SYSTEM_SETTINGS, + 'user_display_name' => $this->accounts->get_user_display_name($user_id), + 'timezones' => $this->timezones->to_array(), + 'privileges' => $this->roles_model->get_permissions_by_slug($role_slug), + 'system_settings' => $this->settings_model->get(), + ]); + } + + /** + * Save general settings. + */ + public function save() + { + try + { + if ($this->permissions[PRIV_SYSTEM_SETTINGS]['edit'] == FALSE) + { + throw new Exception('You do not have the required permissions for this task.'); + } + + $settings = json_decode(request('settings', FALSE), TRUE); + + foreach ($settings as $setting) + { + $existing_setting = $this->settings_model->query()->where('name', $setting['name'])->get()->row_array(); + + if ( ! empty($existing_setting)) + { + $setting['id'] = $existing_setting['id']; + } + + $this->settings_model->save($setting); + } + + response(); + } + catch (Throwable $e) + { + json_exception($e); + } + } +} diff --git a/application/views/pages/settings/business_logic/business_logic_page.php b/application/views/pages/settings/business_logic/business_logic_page.php new file mode 100755 index 00000000..c2b00a43 --- /dev/null +++ b/application/views/pages/settings/business_logic/business_logic_page.php @@ -0,0 +1,131 @@ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + +
+
+

+ + + + + + + + + + + + + +
+ +
+ +
+ +
+ +

+
+ + +

+ +

+
+
+
+

+ + + + + +
+ +
+ +
+ + + + + + + + + + + +
+
+
+
+
+
+
+ + diff --git a/assets/js/backend_settings_business_logic.js b/assets/js/backend_settings_business_logic.js new file mode 100644 index 00000000..0df56dcc --- /dev/null +++ b/assets/js/backend_settings_business_logic.js @@ -0,0 +1,137 @@ +/* ---------------------------------------------------------------------------- + * Easy!Appointments - Open Source Web Scheduler + * + * @package EasyAppointments + * @author A.Tselegidis + * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link http://easyappointments.org + * @since v1.0.0 + * ---------------------------------------------------------------------------- */ + +window.BackendSettingsBusinessLogic = window.BackendSettingsBusinessLogic || {}; + +/** + * Backend Settings + * + * Contains the functionality of the backend settings page. Can either work for system or user settings, + * but the actions allowed to the user are restricted to his role (only admin has full privileges). + * + * @module BackendSettingsBusinessLogic + */ +(function (exports) { + 'use strict'; + + // Constants + exports.SETTINGS_SYSTEM = 'SETTINGS_SYSTEM'; + + /** + * Use this WorkingPlan class instance to perform actions on the page's working plan tables. + * + * @type {WorkingPlan} + */ + exports.wp = {}; + + /** + * Tab settings object. + * + * @type {Object} + */ + var settings = {}; + + /** + * Initialize Page + * + * @param {bool} defaultEventHandlers Optional (true), determines whether to bind the default event handlers. + */ + exports.initialize = function (defaultEventHandlers) { + defaultEventHandlers = defaultEventHandlers || true; + + // Apply setting values from database. + var workingPlan = {}; + + GlobalVariables.settings.system.forEach(function (setting) { + $('input[data-field="' + setting.name + '"]').val(setting.value); + $('select[data-field="' + setting.name + '"]').val(setting.value); + + if (setting.name === 'company_working_plan') { + workingPlan = $.parseJSON(setting.value); + } + }); + + exports.wp = new WorkingPlan(); + exports.wp.setup(workingPlan); + exports.wp.timepickers(false); + + // Set default settings helper. + settings = new SystemSettingsBusinessLogicHelper(); + + if (defaultEventHandlers) { + bindEventHandlers(); + var $link = $('#settings-page .nav li').not('.d-none').first().find('a'); + $link.tab('show'); + } + + // Apply Privileges + if (GlobalVariables.user.privileges.system_settings.edit === false) { + $('#business-logic').find('select, input, textarea').prop('readonly', true); + $('#business-logic').find('button').prop('disabled', true); + } + + Backend.placeFooterToBottom(); + }; + + /** + * Bind the backend/settings default event handlers. + * + * This method depends on the backend/settings html, so do not use this method on a different page. + */ + function bindEventHandlers() { + exports.wp.bindEventHandlers(); + + /** + * Event: Save Settings Button "Click" + * + * Store the setting changes into the database. + */ + $('.save-settings').on('click', function () { + var data = settings.get(); + settings.save(data); + }); + + /** + * Event: Apply Global Working Plan + */ + $('#apply-global-working-plan').on('click', function () { + var buttons = [ + { + text: EALang.cancel, + click: function () { + $('#message-box').dialog('close'); + } + }, + { + text: 'OK', + click: function () { + var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_apply_global_working_plan'; + + var data = { + csrfToken: GlobalVariables.csrfToken, + working_plan: JSON.stringify(exports.wp.get()) + }; + + $.post(url, data) + .done(function () { + Backend.displayNotification(EALang.working_plans_got_updated); + }) + .always(function () { + $('#message-box').dialog('close'); + }); + } + } + ]; + + GeneralFunctions.displayMessageBox(EALang.working_plan, EALang.overwrite_existing_working_plans, buttons); + }); + } +})(window.BackendSettingsBusinessLogic); diff --git a/assets/js/backend_settings_business_logic_helper.js b/assets/js/backend_settings_business_logic_helper.js new file mode 100644 index 00000000..5cf47377 --- /dev/null +++ b/assets/js/backend_settings_business_logic_helper.js @@ -0,0 +1,123 @@ +/* ---------------------------------------------------------------------------- + * Easy!Appointments - Open Source Web Scheduler + * + * @package EasyAppointments + * @author A.Tselegidis + * @copyright Copyright (c) 2013 - 2020, Alex Tselegidis + * @license http://opensource.org/licenses/GPL-3.0 - GPLv3 + * @link http://easyappointments.org + * @since v1.0.0 + * ---------------------------------------------------------------------------- */ + +(function () { + 'use strict'; + + /** + * "System Settings" Tab Helper Class + * + * @class SystemSettingsBusinessLogicHelper + */ + var SystemSettingsBusinessLogicHelper = function () {}; + + /** + * Save the system settings. + * + * This method is run after changes are detected on the tab input fields. + * + * @param {Array} settings Contains the system settings data. + */ + SystemSettingsBusinessLogicHelper.prototype.save = function (settings) { + if (!this.validate()) { + return; // Validation failed, do not proceed. + } + + var url = GlobalVariables.baseUrl + '/index.php/backend_api/ajax_save_settings'; + + var data = { + csrfToken: GlobalVariables.csrfToken, + settings: JSON.stringify(settings), + type: BackendSettingsBusinessLogic.SETTINGS_SYSTEM + }; + + $.post(url, data).done(function () { + Backend.displayNotification(EALang.settings_saved); + + // Update the logo title on the header. + $('#header-logo span').text($('#company-name').val()); + + // Update book_advance_timeout preview + var totalMinutes = $('#book-advance-timeout').val(); + var hours = Math.floor(totalMinutes / 60); + var minutes = totalMinutes % 60; + $('#book-advance-timeout-helper').text( + EALang.book_advance_timeout_hint.replace( + '{$limit}', + ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2) + ) + ); + + // We need to refresh the working plan. + var workingPlan = BackendSettingsBusinessLogic.wp.get(); + BackendSettingsBusinessLogic.wp.setup(workingPlan); + BackendSettingsBusinessLogic.wp.timepickers(false); + }); + }; + + /** + * Prepare the system settings array. + * + * This method uses the DOM elements of the backend/settings page, so it can't be used in another page. + * + * @return {Array} Returns the system settings array. + */ + SystemSettingsBusinessLogicHelper.prototype.get = function () { + var settings = []; + + // Business Logic Tab + + settings.push({ + name: 'company_working_plan', + value: JSON.stringify(BackendSettingsBusinessLogic.wp.get()) + }); + + settings.push({ + name: 'book_advance_timeout', + value: $('#book-advance-timeout').val() + }); + + return settings; + }; + + /** + * Validate the settings data. + * + * If the validation fails then display a message to the user. + * + * @return {Boolean} Returns the validation result. + */ + SystemSettingsBusinessLogicHelper.prototype.validate = function () { + $('#business-logic .has-error').removeClass('has-error'); + + try { + // Validate required fields. + var missingRequired = false; + $('#business-logic .required').each(function (index, requiredField) { + if (!$(requiredField).val()) { + $(requiredField).closest('.form-group').addClass('has-error'); + missingRequired = true; + } + }); + + if (missingRequired) { + throw new Error(EALang.fields_are_required); + } + + return true; + } catch (error) { + Backend.displayNotification(error.message); + return false; + } + }; + + window.SystemSettingsBusinessLogicHelper = SystemSettingsBusinessLogicHelper; +})();