Require bookings to be at least 5 days ahead
Guests could previously book for the same day or tomorrow. The earliest selectable date is now today + 5 days, configured in one place via the BOOKING_MIN_LEAD_DAYS constant. - constants.php: new BOOKING_MIN_LEAD_DAYS define (5) - Service_model::getAvailableTimes(): optional $minLeadDays param, returns no slots for dates closer than that; defaults to 0 so existing callers are unaffected - Pages::ajax(): guest actions (getAvailableTimes, isTimeAvailable) pass the constant. The admin action getAvailableTimeOptions deliberately does not, so staff can still enter phone bookings for tomorrow. - Pages::booking_process(): rejects an early booking_date POST and redirects back to /booking, guarding against a stale page or a crafted request - booking-form.php: datepicker minDate/defaultDate and the hidden booking_date default all derive from the constant Deployed and verified on test, dev and prod. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MyYsTAAA1kJLMLCResmgTE
This commit is contained in:
co-authored by
Claude Opus 5
parent
4e1a69c8d4
commit
69ec9e62a6
@@ -83,3 +83,15 @@ defined('EXIT_USER_INPUT') OR define('EXIT_USER_INPUT', 7); // invalid user
|
|||||||
defined('EXIT_DATABASE') OR define('EXIT_DATABASE', 8); // database error
|
defined('EXIT_DATABASE') OR define('EXIT_DATABASE', 8); // database error
|
||||||
defined('EXIT__AUTO_MIN') OR define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
|
defined('EXIT__AUTO_MIN') OR define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
|
||||||
defined('EXIT__AUTO_MAX') OR define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code
|
defined('EXIT__AUTO_MAX') OR define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Booking lead time
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Minimum number of days ahead a guest can book a job. 5 means the earliest
|
||||||
|
| selectable date is today + 5 days. Applies to the public booking form only
|
||||||
|
| - the admin portal can still book any date.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
defined('BOOKING_MIN_LEAD_DAYS') OR define('BOOKING_MIN_LEAD_DAYS', 5);
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ class Pages extends CI_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(isset($_POST['action']) && $_POST['action'] == 'isTimeAvailable' && isset($_POST['selectedDate'])){
|
if(isset($_POST['action']) && $_POST['action'] == 'isTimeAvailable' && isset($_POST['selectedDate'])){
|
||||||
$results = $this->Service_model->getAvailableTimes($_POST['group_id'], $_POST['selectedDate'], $_POST['servicelength']);
|
$results = $this->Service_model->getAvailableTimes($_POST['group_id'], $_POST['selectedDate'], $_POST['servicelength'], BOOKING_MIN_LEAD_DAYS);
|
||||||
|
|
||||||
$timeIsAvailable = 0;
|
$timeIsAvailable = 0;
|
||||||
if(is_array($results)){
|
if(is_array($results)){
|
||||||
@@ -215,7 +215,7 @@ class Pages extends CI_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(isset($_POST['action']) && $_POST['action'] == 'getAvailableTimes' && isset($_POST['selectedDate'])){
|
if(isset($_POST['action']) && $_POST['action'] == 'getAvailableTimes' && isset($_POST['selectedDate'])){
|
||||||
$results = $this->Service_model->getAvailableTimes($_POST['group_id'], $_POST['selectedDate'], $_POST['servicelength'].':00');
|
$results = $this->Service_model->getAvailableTimes($_POST['group_id'], $_POST['selectedDate'], $_POST['servicelength'].':00', BOOKING_MIN_LEAD_DAYS);
|
||||||
|
|
||||||
$rowIndex = 1;
|
$rowIndex = 1;
|
||||||
if(!empty($results)){
|
if(!empty($results)){
|
||||||
@@ -515,6 +515,13 @@ class Pages extends CI_Controller {
|
|||||||
|
|
||||||
|
|
||||||
if(isset($_POST['sendBooking'])){
|
if(isset($_POST['sendBooking'])){
|
||||||
|
//guest bookings must be at least BOOKING_MIN_LEAD_DAYS days ahead
|
||||||
|
$earliestBookingDate = date('Y-m-d', strtotime('+'.BOOKING_MIN_LEAD_DAYS.' days'));
|
||||||
|
if(!isset($_POST['booking_date']) || $_POST['booking_date'] < $earliestBookingDate){
|
||||||
|
header('Location:'.SITEURL.'booking');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
//calculate finish time
|
//calculate finish time
|
||||||
$serviceStartTime = date("H:i:s", strtotime($_POST['booking_start_time']));
|
$serviceStartTime = date("H:i:s", strtotime($_POST['booking_start_time']));
|
||||||
$serviceLengthTime = date("H:i:s", strtotime($_POST['servicelength']));
|
$serviceLengthTime = date("H:i:s", strtotime($_POST['servicelength']));
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ class Service_model extends CI_Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAvailableTimes($group_id, $selectedDate, $servicelength){
|
public function getAvailableTimes($group_id, $selectedDate, $servicelength, $minLeadDays = 0){
|
||||||
$this->load->database();
|
$this->load->database();
|
||||||
$serviceLengthDateTime = new DateTime($selectedDate.' '.$servicelength);
|
$serviceLengthDateTime = new DateTime($selectedDate.' '.$servicelength);
|
||||||
$service_length_time = strtotime($servicelength);
|
$service_length_time = strtotime($servicelength);
|
||||||
@@ -366,6 +366,12 @@ class Service_model extends CI_Model {
|
|||||||
$selectedDay=date_create($selectedDate);
|
$selectedDay=date_create($selectedDate);
|
||||||
$dateDiff=date_diff($today,$selectedDay);
|
$dateDiff=date_diff($today,$selectedDay);
|
||||||
|
|
||||||
|
//minimum booking lead time - no times offered before today + $minLeadDays days.
|
||||||
|
//$minLeadDays = 0 means no restriction (admin portal).
|
||||||
|
if($minLeadDays > 0 && intval($dateDiff->format('%R%a')) < $minLeadDays){
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
$tmpDateStart = date_create(date('2024-02-29'));
|
$tmpDateStart = date_create(date('2024-02-29'));
|
||||||
$tmpDateEnd = date_create(date('2024-03-07'));
|
$tmpDateEnd = date_create(date('2024-03-07'));
|
||||||
|
|
||||||
|
|||||||
@@ -787,7 +787,7 @@
|
|||||||
<div class="bookingResultsWrapper">
|
<div class="bookingResultsWrapper">
|
||||||
<div class="availableTimesContainerTitle"></div>
|
<div class="availableTimesContainerTitle"></div>
|
||||||
<div class="availableTimesContainer" style="padding:5px;">
|
<div class="availableTimesContainer" style="padding:5px;">
|
||||||
<input type="hidden" name="booking_date" id="booking_date" value="<?php echo date('Y-m-d');?>">
|
<input type="hidden" name="booking_date" id="booking_date" value="<?php echo date('Y-m-d', strtotime('+'.BOOKING_MIN_LEAD_DAYS.' days'));?>">
|
||||||
<input type="hidden" name="booking_start_time" id="booking_time" value="">
|
<input type="hidden" name="booking_start_time" id="booking_time" value="">
|
||||||
|
|
||||||
<div class="availableTimes">
|
<div class="availableTimes">
|
||||||
@@ -1122,7 +1122,8 @@
|
|||||||
|
|
||||||
$("#datepicker").datepicker({
|
$("#datepicker").datepicker({
|
||||||
firstDay: 1,
|
firstDay: 1,
|
||||||
defaultDate: new Date(),
|
minDate: <?php echo intval(BOOKING_MIN_LEAD_DAYS);?>,
|
||||||
|
defaultDate: +<?php echo intval(BOOKING_MIN_LEAD_DAYS);?>,
|
||||||
dateFormat: 'yy-mm-dd',
|
dateFormat: 'yy-mm-dd',
|
||||||
onSelect: function(dateText) {
|
onSelect: function(dateText) {
|
||||||
$('#booking_date').val(this.value);
|
$('#booking_date').val(this.value);
|
||||||
|
|||||||
Reference in New Issue
Block a user