Merge branch 'master' into hotfix_gdpr

This commit is contained in:
alext 2018-06-03 16:53:06 +02:00
commit 4659f90fc2
9 changed files with 98 additions and 85 deletions

View file

@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- #441: Added time format selection - #441: Added time format selection
- #452: Provide more information when errors occur during the installation. - #452: Provide more information when errors occur during the installation.
## Changed
- #494: French translation corrections/improvements.
## Fixed ## Fixed
- #433: Selected date when editing an appointment - #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 - #455: French Spelling
- #459: Aggregate Appointment API crashes when a break was added - #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. - #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] ## [1.3.0]

View file

@ -615,48 +615,9 @@ class Appointments extends CI_Controller {
? [$_REQUEST['appointment_id']] ? [$_REQUEST['appointment_id']]
: []; : [];
// Handle the "Any Provider" case. $provider_list = ($provider_id === ANY_PROVIDER) ? $this->_search_providers_by_service($service_id) : [$provider_id] ;
if ($provider_id === ANY_PROVIDER)
{
$provider_id = $this->_search_any_provider($service_id, $selected_date_string);
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'); $this->load->model('providers_model');
$provider = $this->providers_model->get_row($provider_id);
// Get the service record. // Get the service record.
$this->load->model('services_model'); $this->load->model('services_model');
@ -673,19 +634,29 @@ class Appointments extends CI_Controller {
continue; continue;
} }
$empty_periods = $this->_get_provider_available_time_periods($provider_id, // Finding at least one slot of availablity
$service_id, foreach ($provider_list as $curr_provider_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)
{ {
$available_hours = $this->_get_multiple_attendants_hours($current_date->format('Y-m-d'), $service, // Get the provider record.
$provider); $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)) if (empty($available_hours))
{ {
$unavailable_dates[] = $current_date->format('Y-m-d'); $unavailable_dates[] = $current_date->format('Y-m-d');
@ -1016,7 +987,7 @@ class Appointments extends CI_Controller {
if ($service['attendants_number'] > 1) 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); $provider);
} }
@ -1032,6 +1003,36 @@ class Appointments extends CI_Controller {
return $provider_id; 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. * Calculate the available appointment hours.
* *

View file

@ -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['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['display_calendar'] = 'Afficher le calendrier.';
$lang['calendar'] = 'Calendrier'; $lang['calendar'] = 'Calendrier';
$lang['users'] = 'Utilisateur'; $lang['users'] = 'Utilisateurs';
$lang['settings'] = 'Paramètres'; $lang['settings'] = 'Paramètres';
$lang['log_out'] = 'Déconnexion'; $lang['log_out'] = 'Déconnexion';
$lang['synchronize'] = 'Synchronisation'; $lang['synchronize'] = 'Synchronisation';
@ -251,7 +251,7 @@ $lang['december'] = 'Décembre';
$lang['previous'] = 'Précédent'; // @TODO check -e form $lang['previous'] = 'Précédent'; // @TODO check -e form
$lang['next'] = 'Suivant'; // @TODO check -e form $lang['next'] = 'Suivant'; // @TODO check -e form
$lang['now'] = 'Maintenant'; $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['time'] = 'Heure du RDV'; // @TODO to check ; was 'Temps'
$lang['hour'] = 'Heure'; $lang['hour'] = 'Heure';
$lang['minute'] = 'Minute'; $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['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'] = 'Format des Dates';
$lang['date_format_hint'] = 'Change le format d\'affichage des dates (D - Jour, M - Mois, Y - Année).'; $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'] = 'Format de l\'Heure';
$lang['time_format_hint'] = 'Change the time display format (H - Hours, M - Minutes).'; $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['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['flexible'] = 'Flexible';
$lang['fixed'] = 'Fixed'; $lang['fixed'] = 'Fixe';
$lang['attendants_number'] = 'Attendants Number'; $lang['attendants_number'] = 'Nombre de participants';
$lang['reset_working_plan'] = 'Reset the working plan back to the default values.'; $lang['reset_working_plan'] = 'Restaurer les valeurs d\'origine du planning de travail.';

View file

@ -218,6 +218,9 @@ class Migration_Change_column_types extends CI_Migration {
$this->db->query('ALTER TABLE `ea_user_settings` $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'); 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() public function down()

View file

@ -218,6 +218,7 @@ window.BackendCalendarDefaultView = window.BackendCalendarDefaultView || {};
$('#calendar').fullCalendar('option', 'editable', false); $('#calendar').fullCalendar('option', 'editable', false);
} else { } else {
$('#google-sync, #enable-sync, #insert-appointment, #insert-unavailable').prop('disabled', false); $('#google-sync, #enable-sync, #insert-appointment, #insert-unavailable').prop('disabled', false);
$('#calendar').fullCalendar('option', 'selectable', true);
$('#calendar').fullCalendar('option', 'editable', true); $('#calendar').fullCalendar('option', 'editable', true);
// If the user has already the sync enabled then apply the proper style changes. // If the user has already the sync enabled then apply the proper style changes.

View file

@ -102,8 +102,8 @@ window.BackendSettings = window.BackendSettings || {};
if (bindEventHandlers) { if (bindEventHandlers) {
_bindEventHandlers(); _bindEventHandlers();
$('#settings-page .nav li').first().addClass('active'); var $link = $('#settings-page .nav li').not('.hidden').first().find('a');
$('#settings-page .nav li').first().find('a').trigger('click'); $link.tab('show');
} }
// Apply Privileges // Apply Privileges

View file

@ -102,8 +102,7 @@
$('#admins .record-details').find('select').prop('disabled', false); $('#admins .record-details').find('select').prop('disabled', false);
$('#admin-password, #admin-password-confirm').removeClass('required'); $('#admin-password, #admin-password-confirm').removeClass('required');
$('#admin-notifications').prop('disabled', false); $('#admin-notifications').prop('disabled', false);
$('#filter-admins button').prop('disabled', true);
$('#filter-admins .filter').prop('disabled', true);
$('#filter-admins .results').css('color', '#AAA'); $('#filter-admins .results').css('color', '#AAA');
}); });

View file

@ -2,16 +2,16 @@ SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00"; SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `ea_appointments` ( 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, `book_datetime` DATETIME,
`start_datetime` DATETIME, `start_datetime` DATETIME,
`end_datetime` DATETIME, `end_datetime` DATETIME,
`notes` TEXT, `notes` TEXT,
`hash` TEXT, `hash` TEXT,
`is_unavailable` TINYINT(4) DEFAULT '0', `is_unavailable` TINYINT(4) DEFAULT '0',
`id_users_provider` BIGINT(20) UNSIGNED, `id_users_provider` INT(11),
`id_users_customer` BIGINT(20) UNSIGNED, `id_users_customer` INT(11),
`id_services` BIGINT(20) UNSIGNED, `id_services` INT(11),
`id_google_calendar` TEXT, `id_google_calendar` TEXT,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `id_users_customer` (`id_users_customer`), KEY `id_users_customer` (`id_users_customer`),
@ -29,15 +29,15 @@ CREATE TABLE `ea_migrations` (
DEFAULT CHARSET = utf8; DEFAULT CHARSET = utf8;
CREATE TABLE IF NOT EXISTS `ea_roles` ( 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), `name` VARCHAR(256),
`slug` VARCHAR(256), `slug` VARCHAR(256),
`is_admin` TINYINT(4), `is_admin` TINYINT(4),
`appointments` INT(4), `appointments` INT(11),
`customers` INT(4), `customers` INT(11),
`services` INT(4), `services` INT(11),
`users` INT(4), `users` INT(11),
`system_settings` INT(4), `system_settings` INT(11),
`user_settings` INT(11), `user_settings` INT(11),
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) )
@ -46,8 +46,8 @@ CREATE TABLE IF NOT EXISTS `ea_roles` (
CREATE TABLE IF NOT EXISTS `ea_secretaries_providers` ( CREATE TABLE IF NOT EXISTS `ea_secretaries_providers` (
`id_users_secretary` BIGINT(20) UNSIGNED NOT NULL, `id_users_secretary` INT(11) NOT NULL,
`id_users_provider` BIGINT(20) UNSIGNED NOT NULL, `id_users_provider` INT(11) NOT NULL,
PRIMARY KEY (`id_users_secretary`, `id_users_provider`), PRIMARY KEY (`id_users_secretary`, `id_users_provider`),
KEY `id_users_secretary` (`id_users_secretary`), KEY `id_users_secretary` (`id_users_secretary`),
KEY `id_users_provider` (`id_users_provider`) 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` ( 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), `name` VARCHAR(256),
`duration` INT(11), `duration` INT(11),
`price` DECIMAL(10, 2), `price` DECIMAL(10, 2),
@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS `ea_services` (
`description` TEXT, `description` TEXT,
`availabilities_type` VARCHAR(32) DEFAULT 'flexible', `availabilities_type` VARCHAR(32) DEFAULT 'flexible',
`attendants_number` INT(11) DEFAULT '1', `attendants_number` INT(11) DEFAULT '1',
`id_service_categories` BIGINT(20) UNSIGNED, `id_service_categories` INT(11),
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `id_service_categories` (`id_service_categories`) 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` ( CREATE TABLE IF NOT EXISTS `ea_services_providers` (
`id_users` BIGINT(20) UNSIGNED NOT NULL, `id_users` INT(11) NOT NULL,
`id_services` BIGINT(20) UNSIGNED NOT NULL, `id_services` INT(11) NOT NULL,
PRIMARY KEY (`id_users`, `id_services`), PRIMARY KEY (`id_users`, `id_services`),
KEY `id_services` (`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` ( 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), `name` VARCHAR(256),
`description` TEXT, `description` TEXT,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
@ -94,7 +94,7 @@ CREATE TABLE IF NOT EXISTS `ea_service_categories` (
CREATE TABLE IF NOT EXISTS `ea_settings` ( 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), `name` VARCHAR(512),
`value` LONGTEXT, `value` LONGTEXT,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
@ -104,7 +104,7 @@ CREATE TABLE IF NOT EXISTS `ea_settings` (
CREATE TABLE IF NOT EXISTS `ea_users` ( 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), `first_name` VARCHAR(256),
`last_name` VARCHAR(512), `last_name` VARCHAR(512),
`email` VARCHAR(512), `email` VARCHAR(512),
@ -115,7 +115,7 @@ CREATE TABLE IF NOT EXISTS `ea_users` (
`state` VARCHAR(128), `state` VARCHAR(128),
`zip_code` VARCHAR(64), `zip_code` VARCHAR(64),
`notes` TEXT, `notes` TEXT,
`id_roles` BIGINT(20) UNSIGNED NOT NULL, `id_roles` INT(11) NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `id_roles` (`id_roles`) KEY `id_roles` (`id_roles`)
) )
@ -124,7 +124,7 @@ CREATE TABLE IF NOT EXISTS `ea_users` (
CREATE TABLE IF NOT EXISTS `ea_user_settings` ( CREATE TABLE IF NOT EXISTS `ea_user_settings` (
`id_users` BIGINT(20) UNSIGNED NOT NULL, `id_users` INT(11) NOT NULL,
`username` VARCHAR(256), `username` VARCHAR(256),
`password` VARCHAR(512), `password` VARCHAR(512),
`salt` VARCHAR(512), `salt` VARCHAR(512),

View file

@ -242,7 +242,7 @@ class Email {
'$appointment_service' => $service['name'], '$appointment_service' => $service['name'],
'$appointment_provider' => $provider['first_name'] . ' ' . $provider['last_name'], '$appointment_provider' => $provider['first_name'] . ' ' . $provider['last_name'],
'$appointment_date' => date($date_format . ' ' . $timeFormat, strtotime($appointment['start_datetime'])), '$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_link' => $company['company_link'],
'$company_name' => $company['company_name'], '$company_name' => $company['company_name'],
'$customer_name' => $customer['first_name'] . ' ' . $customer['last_name'], '$customer_name' => $customer['first_name'] . ' ' . $customer['last_name'],