mirror of
https://github.com/alextselegidis/easyappointments.git
synced 2024-12-22 22:52:35 +03:00
Merge branch 'master' into hotfix_gdpr
This commit is contained in:
commit
4659f90fc2
9 changed files with 98 additions and 85 deletions
|
@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- #441: Added time format selection
|
||||
- #452: Provide more information when errors occur during the installation.
|
||||
|
||||
## Changed
|
||||
|
||||
- #494: French translation corrections/improvements.
|
||||
|
||||
## Fixed
|
||||
|
||||
- #433: Selected date when editing an appointment
|
||||
|
@ -24,6 +28,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- #455: French Spelling
|
||||
- #459: Aggregate Appointment API crashes when a break was added
|
||||
- #461: Invalid working plan parsing for foreign languages on day view of the default calendar view.
|
||||
- #475: Booking page date selection is broken with any_provider option selected.
|
||||
- #483: In backend, calendar for providers become unselectable if switched to calendar for service.
|
||||
- #491: Replace hardcoded string with translation in appointment details email template.
|
||||
- #495: Database migration fixes (from 1.2.1 to 1.3.x).
|
||||
- #497: Backend settings are not being displayed on page load when the user is not an admin.
|
||||
|
||||
## [1.3.0]
|
||||
|
||||
|
|
|
@ -615,48 +615,9 @@ class Appointments extends CI_Controller {
|
|||
? [$_REQUEST['appointment_id']]
|
||||
: [];
|
||||
|
||||
// Handle the "Any Provider" case.
|
||||
if ($provider_id === ANY_PROVIDER)
|
||||
{
|
||||
$provider_id = $this->_search_any_provider($service_id, $selected_date_string);
|
||||
$provider_list = ($provider_id === ANY_PROVIDER) ? $this->_search_providers_by_service($service_id) : [$provider_id] ;
|
||||
|
||||
if ($provider_id === null) {
|
||||
$current_date = new DateTime($selected_date_string);
|
||||
$current_date->add(new DateInterval('P1D'));
|
||||
|
||||
do
|
||||
{
|
||||
$provider_id = $this->_search_any_provider($service_id, $current_date->format('Y-m-d H:i:s'));
|
||||
|
||||
if ($provider_id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$current_date->add(new DateInterval('P1D'));
|
||||
} while ((int)$current_date->format('d') <= $number_of_days_in_month);
|
||||
}
|
||||
|
||||
if ($provider_id === NULL)
|
||||
{
|
||||
// No provider is available in the selected date.
|
||||
for ($i = 1; $i <= $number_of_days_in_month; $i++)
|
||||
{
|
||||
$current_date = new DateTime($selected_date->format('Y-m') . '-' . $i);
|
||||
$unavailable_dates[] = $current_date->format('Y-m-d');
|
||||
}
|
||||
|
||||
$this->output
|
||||
->set_content_type('application/json')
|
||||
->set_output(json_encode($unavailable_dates));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the provider record.
|
||||
$this->load->model('providers_model');
|
||||
$provider = $this->providers_model->get_row($provider_id);
|
||||
|
||||
// Get the service record.
|
||||
$this->load->model('services_model');
|
||||
|
@ -673,19 +634,29 @@ class Appointments extends CI_Controller {
|
|||
continue;
|
||||
}
|
||||
|
||||
$empty_periods = $this->_get_provider_available_time_periods($provider_id,
|
||||
$service_id,
|
||||
$current_date->format('Y-m-d'), $exclude_appointments);
|
||||
|
||||
$available_hours = $this->_calculate_available_hours($empty_periods, $current_date->format('Y-m-d'),
|
||||
$service['duration'], $manage_mode, $service['availabilities_type']);
|
||||
|
||||
if ($service['attendants_number'] > 1)
|
||||
// Finding at least one slot of availablity
|
||||
foreach ($provider_list as $curr_provider_id)
|
||||
{
|
||||
$available_hours = $this->_get_multiple_attendants_hours($current_date->format('Y-m-d'), $service,
|
||||
$provider);
|
||||
// Get the provider record.
|
||||
$curr_provider = $this->providers_model->get_row($curr_provider_id);
|
||||
|
||||
$empty_periods = $this->_get_provider_available_time_periods($curr_provider_id,
|
||||
$service_id,
|
||||
$current_date->format('Y-m-d'), $exclude_appointments);
|
||||
|
||||
$available_hours = $this->_calculate_available_hours($empty_periods, $current_date->format('Y-m-d'),
|
||||
$service['duration'], $manage_mode, $service['availabilities_type']);
|
||||
if (! empty($available_hours)) break;
|
||||
|
||||
if ($service['attendants_number'] > 1)
|
||||
{
|
||||
$available_hours = $this->_get_multiple_attendants_hours($current_date->format('Y-m-d'), $service,
|
||||
$curr_provider);
|
||||
if (! empty($available_hours)) break;
|
||||
}
|
||||
}
|
||||
|
||||
// No availability amongst all the provider
|
||||
if (empty($available_hours))
|
||||
{
|
||||
$unavailable_dates[] = $current_date->format('Y-m-d');
|
||||
|
@ -1016,7 +987,7 @@ class Appointments extends CI_Controller {
|
|||
|
||||
if ($service['attendants_number'] > 1)
|
||||
{
|
||||
$available_hours = $this->_get_multiple_attendants_hours($this->input->post('selected_date'), $service,
|
||||
$available_hours = $this->_get_multiple_attendants_hours($selected_date, $service,
|
||||
$provider);
|
||||
}
|
||||
|
||||
|
@ -1032,6 +1003,36 @@ class Appointments extends CI_Controller {
|
|||
return $provider_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for any provider that can handle the requested service.
|
||||
*
|
||||
* This method will return the database ID of the providers affected to the requested service.
|
||||
*
|
||||
* @param numeric $service_id The requested service ID.
|
||||
*
|
||||
* @return array Returns the ID of the provider that can provide the requested service.
|
||||
*/
|
||||
protected function _search_providers_by_service($service_id)
|
||||
{
|
||||
$this->load->model('providers_model');
|
||||
$available_providers = $this->providers_model->get_available_providers();
|
||||
$provider_list = array();
|
||||
|
||||
foreach ($available_providers as $provider)
|
||||
{
|
||||
foreach ($provider['services'] as $provider_service_id)
|
||||
{
|
||||
if ($provider_service_id === $service_id)
|
||||
{
|
||||
// Check if the provider is affected to the selected service.
|
||||
$provider_list[] = $provider['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $provider_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the available appointment hours.
|
||||
*
|
||||
|
|
|
@ -56,7 +56,7 @@ $lang['appointment_not_found'] = 'Rendez-vous introuvable !';
|
|||
$lang['appointment_does_not_exist_in_db'] = 'Le rendez-vous demandé n\'existe plus dans la base de données système.';
|
||||
$lang['display_calendar'] = 'Afficher le calendrier.';
|
||||
$lang['calendar'] = 'Calendrier';
|
||||
$lang['users'] = 'Utilisateur';
|
||||
$lang['users'] = 'Utilisateurs';
|
||||
$lang['settings'] = 'Paramètres';
|
||||
$lang['log_out'] = 'Déconnexion';
|
||||
$lang['synchronize'] = 'Synchronisation';
|
||||
|
@ -251,7 +251,7 @@ $lang['december'] = 'Décembre';
|
|||
$lang['previous'] = 'Précédent'; // @TODO check -e form
|
||||
$lang['next'] = 'Suivant'; // @TODO check -e form
|
||||
$lang['now'] = 'Maintenant';
|
||||
$lang['select_time'] = 'Choisir l\'heure';
|
||||
$lang['select_time'] = 'Choisir l\'Heure';
|
||||
$lang['time'] = 'Heure du RDV'; // @TODO to check ; was 'Temps'
|
||||
$lang['hour'] = 'Heure';
|
||||
$lang['minute'] = 'Minute';
|
||||
|
@ -272,11 +272,11 @@ $lang['customer_notifications'] = 'Notifications aux clients';
|
|||
$lang['customer_notifications_hint'] = 'Définit si les clients reçoivent des notifications par email chaque fois qu\'il y a un changement d\'horaire de l\'un de leurs rendez-vous.';
|
||||
$lang['date_format'] = 'Format des Dates';
|
||||
$lang['date_format_hint'] = 'Change le format d\'affichage des dates (D - Jour, M - Mois, Y - Année).';
|
||||
$lang['time_format'] = 'Time Format';
|
||||
$lang['time_format_hint'] = 'Change the time display format (H - Hours, M - Minutes).';
|
||||
$lang['time_format'] = 'Format de l\'Heure';
|
||||
$lang['time_format_hint'] = 'Change le format d\'affichage de l\'Heure (H - Heures, M - Minutes).';
|
||||
$lang['google_analytics_code_hint'] = 'Renseignez l\'ID Google Analytics à utiliser dans la page des réservations.';
|
||||
$lang['availabilities_type'] = 'Availabilities Type';
|
||||
$lang['availabilities_type'] = 'Type de disponibilités';
|
||||
$lang['flexible'] = 'Flexible';
|
||||
$lang['fixed'] = 'Fixed';
|
||||
$lang['attendants_number'] = 'Attendants Number';
|
||||
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.';
|
||||
$lang['fixed'] = 'Fixe';
|
||||
$lang['attendants_number'] = 'Nombre de participants';
|
||||
$lang['reset_working_plan'] = 'Restaurer les valeurs d\'origine du planning de travail.';
|
||||
|
|
|
@ -218,6 +218,9 @@ class Migration_Change_column_types extends CI_Migration {
|
|||
|
||||
$this->db->query('ALTER TABLE `ea_user_settings`
|
||||
ADD CONSTRAINT `ea_user_settings_ibfk_1` FOREIGN KEY (`id_users`) REFERENCES `ea_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE');
|
||||
|
||||
// Change charset of ea_secretaries_providers table for databases created with EA! 1.2.1 version
|
||||
$this->db->query('ALTER TABLE ea_secretaries_providers CONVERT TO CHARACTER SET utf8');
|
||||
}
|
||||
|
||||
public function down()
|
||||
|
|
|
@ -218,6 +218,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {};
|
|||
$('#calendar').fullCalendar('option', 'editable', false);
|
||||
} else {
|
||||
$('#google-sync, #enable-sync, #insert-appointment, #insert-unavailable').prop('disabled', false);
|
||||
$('#calendar').fullCalendar('option', 'selectable', true);
|
||||
$('#calendar').fullCalendar('option', 'editable', true);
|
||||
|
||||
// If the user has already the sync enabled then apply the proper style changes.
|
||||
|
|
|
@ -102,8 +102,8 @@ window.BackendSettings = window.BackendSettings || {};
|
|||
|
||||
if (bindEventHandlers) {
|
||||
_bindEventHandlers();
|
||||
$('#settings-page .nav li').first().addClass('active');
|
||||
$('#settings-page .nav li').first().find('a').trigger('click');
|
||||
var $link = $('#settings-page .nav li').not('.hidden').first().find('a');
|
||||
$link.tab('show');
|
||||
}
|
||||
|
||||
// Apply Privileges
|
||||
|
|
|
@ -102,8 +102,7 @@
|
|||
$('#admins .record-details').find('select').prop('disabled', false);
|
||||
$('#admin-password, #admin-password-confirm').removeClass('required');
|
||||
$('#admin-notifications').prop('disabled', false);
|
||||
|
||||
$('#filter-admins .filter').prop('disabled', true);
|
||||
$('#filter-admins button').prop('disabled', true);
|
||||
$('#filter-admins .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
|
|
|
@ -2,16 +2,16 @@ SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
|||
SET time_zone = "+00:00";
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_appointments` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`book_datetime` DATETIME,
|
||||
`start_datetime` DATETIME,
|
||||
`end_datetime` DATETIME,
|
||||
`notes` TEXT,
|
||||
`hash` TEXT,
|
||||
`is_unavailable` TINYINT(4) DEFAULT '0',
|
||||
`id_users_provider` BIGINT(20) UNSIGNED,
|
||||
`id_users_customer` BIGINT(20) UNSIGNED,
|
||||
`id_services` BIGINT(20) UNSIGNED,
|
||||
`id_users_provider` INT(11),
|
||||
`id_users_customer` INT(11),
|
||||
`id_services` INT(11),
|
||||
`id_google_calendar` TEXT,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `id_users_customer` (`id_users_customer`),
|
||||
|
@ -29,15 +29,15 @@ CREATE TABLE `ea_migrations` (
|
|||
DEFAULT CHARSET = utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_roles` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(256),
|
||||
`slug` VARCHAR(256),
|
||||
`is_admin` TINYINT(4),
|
||||
`appointments` INT(4),
|
||||
`customers` INT(4),
|
||||
`services` INT(4),
|
||||
`users` INT(4),
|
||||
`system_settings` INT(4),
|
||||
`appointments` INT(11),
|
||||
`customers` INT(11),
|
||||
`services` INT(11),
|
||||
`users` INT(11),
|
||||
`system_settings` INT(11),
|
||||
`user_settings` INT(11),
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
|
@ -46,8 +46,8 @@ CREATE TABLE IF NOT EXISTS `ea_roles` (
|
|||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_secretaries_providers` (
|
||||
`id_users_secretary` BIGINT(20) UNSIGNED NOT NULL,
|
||||
`id_users_provider` BIGINT(20) UNSIGNED NOT NULL,
|
||||
`id_users_secretary` INT(11) NOT NULL,
|
||||
`id_users_provider` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`id_users_secretary`, `id_users_provider`),
|
||||
KEY `id_users_secretary` (`id_users_secretary`),
|
||||
KEY `id_users_provider` (`id_users_provider`)
|
||||
|
@ -57,7 +57,7 @@ CREATE TABLE IF NOT EXISTS `ea_secretaries_providers` (
|
|||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_services` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(256),
|
||||
`duration` INT(11),
|
||||
`price` DECIMAL(10, 2),
|
||||
|
@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS `ea_services` (
|
|||
`description` TEXT,
|
||||
`availabilities_type` VARCHAR(32) DEFAULT 'flexible',
|
||||
`attendants_number` INT(11) DEFAULT '1',
|
||||
`id_service_categories` BIGINT(20) UNSIGNED,
|
||||
`id_service_categories` INT(11),
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `id_service_categories` (`id_service_categories`)
|
||||
)
|
||||
|
@ -74,8 +74,8 @@ CREATE TABLE IF NOT EXISTS `ea_services` (
|
|||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_services_providers` (
|
||||
`id_users` BIGINT(20) UNSIGNED NOT NULL,
|
||||
`id_services` BIGINT(20) UNSIGNED NOT NULL,
|
||||
`id_users` INT(11) NOT NULL,
|
||||
`id_services` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`id_users`, `id_services`),
|
||||
KEY `id_services` (`id_services`)
|
||||
)
|
||||
|
@ -84,7 +84,7 @@ CREATE TABLE IF NOT EXISTS `ea_services_providers` (
|
|||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_service_categories` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(256),
|
||||
`description` TEXT,
|
||||
PRIMARY KEY (`id`)
|
||||
|
@ -94,7 +94,7 @@ CREATE TABLE IF NOT EXISTS `ea_service_categories` (
|
|||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_settings` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(512),
|
||||
`value` LONGTEXT,
|
||||
PRIMARY KEY (`id`)
|
||||
|
@ -104,7 +104,7 @@ CREATE TABLE IF NOT EXISTS `ea_settings` (
|
|||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_users` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`first_name` VARCHAR(256),
|
||||
`last_name` VARCHAR(512),
|
||||
`email` VARCHAR(512),
|
||||
|
@ -115,7 +115,7 @@ CREATE TABLE IF NOT EXISTS `ea_users` (
|
|||
`state` VARCHAR(128),
|
||||
`zip_code` VARCHAR(64),
|
||||
`notes` TEXT,
|
||||
`id_roles` BIGINT(20) UNSIGNED NOT NULL,
|
||||
`id_roles` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `id_roles` (`id_roles`)
|
||||
)
|
||||
|
@ -124,7 +124,7 @@ CREATE TABLE IF NOT EXISTS `ea_users` (
|
|||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ea_user_settings` (
|
||||
`id_users` BIGINT(20) UNSIGNED NOT NULL,
|
||||
`id_users` INT(11) NOT NULL,
|
||||
`username` VARCHAR(256),
|
||||
`password` VARCHAR(512),
|
||||
`salt` VARCHAR(512),
|
||||
|
|
|
@ -242,7 +242,7 @@ class Email {
|
|||
'$appointment_service' => $service['name'],
|
||||
'$appointment_provider' => $provider['first_name'] . ' ' . $provider['last_name'],
|
||||
'$appointment_date' => date($date_format . ' ' . $timeFormat, strtotime($appointment['start_datetime'])),
|
||||
'$appointment_duration' => $service['duration'] . ' minutes',
|
||||
'$appointment_duration' => $service['duration'] . ' ' . $this->framework->lang->line('minutes'),
|
||||
'$company_link' => $company['company_link'],
|
||||
'$company_name' => $company['company_name'],
|
||||
'$customer_name' => $customer['first_name'] . ' ' . $customer['last_name'],
|
||||
|
|
Loading…
Reference in a new issue