Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions application/controllers/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class Services extends EA_Controller
'attendants_number',
'is_private',
'id_service_categories',
'buffer_before',
'buffer_after',
];
public array $optional_service_fields = [
'id_service_categories' => null,
Expand Down
6 changes: 6 additions & 0 deletions application/libraries/Availability.php
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,12 @@ protected function generate_available_hours(string $date, array $service, array

$current_hour = $start_hour;

$buffer_before = new DateInterval('PT' . (int) $service['buffer_before'] . 'M');
$current_hour->add($buffer_before);

$buffer_after = new DateInterval('PT' . (int) $service['buffer_after'] . 'M');
$end_hour->sub($buffer_after);

$diff = $current_hour->diff($end_hour);

while ($diff->h * 60 + $diff->i >= (int) $service['duration'] && $diff->invert === 0) {
Expand Down
55 changes: 55 additions & 0 deletions application/migrations/061_add_buffer_columns_to_service_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php defined('BASEPATH') or exit('No direct script access allowed');

/* ----------------------------------------------------------------------------
* Easy!Appointments - Online Appointment Scheduler
*
* @package EasyAppointments
* @author A.Tselegidis <alextselegidis@gmail.com>
* @copyright Copyright (c) Alex Tselegidis
* @license https://opensource.org/licenses/GPL-3.0 - GPLv3
* @link https://easyappointments.org
* @since v1.5.0
* ---------------------------------------------------------------------------- */

class Migration_Add_buffer_columns_to_service_table extends EA_Migration
{
/**
* Upgrade method.
*/
public function up(): void
{
if (!$this->db->field_exists('buffer_before', 'services')) {
$this->dbforge->add_column('services', [
'buffer_before' => [
'type' => 'INT',
'constraint' => 11,
'null' => true,
],
]);
}

if (!$this->db->field_exists('buffer_after', 'services')) {
$this->dbforge->add_column('services', [
'buffer_after' => [
'type' => 'INT',
'constraint' => 11,
'null' => true,
],
]);
}
}

/**
* Downgrade method.
*/
public function down(): void
{
if ($this->db->field_exists('buffer_before', 'services')) {
$this->dbforge->drop_column('services', 'buffer_before');
}

if ($this->db->field_exists('buffer_after', 'services')) {
$this->dbforge->drop_column('services', 'buffer_after');
}
}
}
3 changes: 1 addition & 2 deletions application/models/Admins_model.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ public function validate(array $admin): void
if (
empty($admin['first_name']) ||
empty($admin['last_name']) ||
empty($admin['email']) ||
empty($admin['phone_number'])
empty($admin['email'])
) {
throw new InvalidArgumentException('Not all required fields are provided: ' . print_r($admin, true));
}
Expand Down
44 changes: 43 additions & 1 deletion application/models/Appointments_model.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,49 @@ protected function insert(array $appointment): int
throw new RuntimeException('Could not insert appointment.');
}

return $this->db->insert_id();
$appointment_id = $this->db->insert_id();

$service = $this->db->get_where('services', ['id' => $appointment['id_services']])->row_array();
if (!$service) {
throw new RuntimeException('Could not find the service for the appointment.');
}

$bufferBefore = $service['buffer_before'];
$bufferAfter = $service['buffer_after'];

if($bufferBefore > 0) {
$bufferBefore = $bufferBefore * 60;
$unavailability['start_datetime'] = date('Y-m-d H:i:s', strtotime($appointment['start_datetime']) - $bufferBefore);
$unavailability['end_datetime'] = $appointment['start_datetime'];
$unavailability['book_datetime'] = $appointment['book_datetime'];
$unavailability['create_datetime'] = $appointment['create_datetime'];
$unavailability['update_datetime'] = $appointment['update_datetime'];
$unavailability['hash'] = random_string('alnum', 12);
$unavailability['is_unavailability'] = true;
$unavailability['id_users_provider'] = $appointment['id_users_provider'];

if (!$this->db->insert('appointments', $unavailability)) {
throw new RuntimeException('Could not insert unavailability.');
}
}

if($bufferAfter > 0) {
$bufferAfter = $bufferAfter * 60;
$unavailability['start_datetime'] = $appointment['end_datetime'];
$unavailability['end_datetime'] = date('Y-m-d H:i:s', strtotime($appointment['end_datetime']) + $bufferAfter);
$unavailability['book_datetime'] = $appointment['book_datetime'];
$unavailability['create_datetime'] = $appointment['create_datetime'];
$unavailability['update_datetime'] = $appointment['update_datetime'];
$unavailability['hash'] = random_string('alnum', 12);
$unavailability['is_unavailability'] = true;
$unavailability['id_users_provider'] = $appointment['id_users_provider'];

if (!$this->db->insert('appointments', $unavailability)) {
throw new RuntimeException('Could not insert unavailability.');
}
}

return $appointment_id;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions application/models/Services_model.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class Services_model extends EA_Model
'attendantsNumber' => 'attendants_number',
'isPrivate' => 'is_private',
'serviceCategoryId' => 'id_service_categories',
'bufferBefore' => 'buffer_before',
'bufferAfter' => 'buffer_after',
];

/**
Expand Down
3 changes: 1 addition & 2 deletions application/views/pages/account.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@
<div class="mb-3">
<label class="form-label" for="phone-number">
<?= lang('phone_number') ?>
<span class="text-danger">*</span>
</label>
<input id="phone-number" class="form-control required">
<input id="phone-number" class="form-control">
</div>

<div class="mb-3">
Expand Down
5 changes: 2 additions & 3 deletions application/views/pages/installation.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,9 @@

<div class="mb-3">
<label class="form-label" for="phone-number">
<?= lang('phone_number') ?>
<span class="text-danger">*</span>
<?= lang('phone_number') ?>
</label>
<input id="phone-number" class="form-control required" maxlength="128">
<input id="phone-number" class="form-control" maxlength="128">
</div>

<div class="mb-3">
Expand Down
16 changes: 16 additions & 0 deletions application/views/pages/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@
disabled>
</div>

<div class="mb-3">
<label class="form-label" for="buffer-before">
<?= lang('buffer-before') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="buffer-before" class="form-control" type="number" disabled>
</div>

<div class="mb-3">
<label class="form-label" for="buffer-after">
<?= lang('buffer-after') ?>
<span class="text-danger" hidden>*</span>
</label>
<input id="buffer-after" class="form-control" type="number" disabled>
</div>

<div class="mb-3">
<label class="form-label" for="price">
<?= lang('price') ?>
Expand Down
4 changes: 4 additions & 0 deletions assets/js/pages/installation.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ App.Pages.Installation = (function () {
let missingRequired = false;

$fields.each((index, field) => {
// Skip phone number field from required check
if ($(field).attr('id') === 'phone-number') {
return;
}
if (!$(field).val()) {
$(field).addClass('is-invalid');
missingRequired = true;
Expand Down
8 changes: 8 additions & 0 deletions assets/js/pages/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ App.Pages.Services = (function () {
const $description = $('#description');
const $filterServices = $('#filter-services');
const $color = $('#color');
const $bufferBefore = $('#buffer-before');
const $bufferAfter = $('#buffer-after');
let filterResults = {};
let filterLimit = 20;

Expand Down Expand Up @@ -110,6 +112,8 @@ App.Pages.Services = (function () {
$serviceCategoryId.val('');
$availabilitiesType.val('flexible');
$attendantsNumber.val('1');
$bufferBefore.val('0');
$bufferAfter.val('0');
});

/**
Expand Down Expand Up @@ -143,6 +147,8 @@ App.Pages.Services = (function () {
attendants_number: $attendantsNumber.val(),
is_private: Number($isPrivate.prop('checked')),
id_service_categories: $serviceCategoryId.val() || undefined,
buffer_before: $bufferBefore.val(),
buffer_after: $bufferAfter.val(),
};

if ($id.val() !== '') {
Expand Down Expand Up @@ -299,6 +305,8 @@ App.Pages.Services = (function () {
$attendantsNumber.val(service.attendants_number);
$isPrivate.prop('checked', service.is_private);
App.Components.ColorSelection.setColor($color, service.color);
$bufferBefore.val(service.buffer_before);
$bufferAfter.val(service.buffer_after);

const serviceCategoryId = service.id_service_categories !== null ? service.id_service_categories : '';
$serviceCategoryId.val(serviceCategoryId);
Expand Down