Fix lunch-break guard being skipped on same-day bookings
getAvailableTimes() overloaded $dayStartTime: it starts as the worker's real shift start, but for same-day requests it is overwritten with the earliest bookable slot (next 15-min block + 1 hour). The lunch-break setup further down still read it as the shift start, so $shiftSeconds measured the *remaining* day instead of the whole shift. Once that fell under 6 hours, $lunchRequired went false and the guard was skipped entirely -- every free slot was offered, including ones that leave no room for a lunch break. Observed on prod on 2026-08-21: at 12:17 the cutoff pushed the start to 13:30, so Kateryna's 10:00-18:00 shift measured 4.5h and a 13:30-15:30 booking was accepted even though it consumed the last possible lunch slot. booking_process() re-validates through the same function, so the server-side check agreed. Capture the real shift start in $shiftStartTime before the cutoff runs, and use it for both $shiftSeconds and the computeLunchBreak() call. The latter also fixes a second symptom of the same overload: the lunch window was being clamped to the cutoff rather than to the actual shift. Verified end-to-end against pages/ajax on test: with the bug a slot that destroys the last lunch break is offered, with the fix it is withheld. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VZv7QGLyRYwdD8NyimYbQQ
This commit is contained in:
@@ -622,6 +622,10 @@ class Service_model extends CI_Model {
|
|||||||
$finishTime = new DateTime($selectedDate . ' ' . $schedule->end_time, new DateTimeZone('Europe/Oslo'));
|
$finishTime = new DateTime($selectedDate . ' ' . $schedule->end_time, new DateTimeZone('Europe/Oslo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A műszak valódi kezdete - $dayStartTime-ot a mai napra alább felülírjuk a legkorábban
|
||||||
|
// foglalható időponttal, az ebédszünet számítása viszont a tényleges műszakkal dolgozik.
|
||||||
|
$shiftStartTime = clone $dayStartTime;
|
||||||
|
|
||||||
// --- ÚJ: ma foglalva csak (következő 15 perces blokk + 1 óra) UTÁN legyen időpont ---
|
// --- ÚJ: ma foglalva csak (következő 15 perces blokk + 1 óra) UTÁN legyen időpont ---
|
||||||
if ($selectedDate == date('Y-m-d')) {
|
if ($selectedDate == date('Y-m-d')) {
|
||||||
// használd a helyi (Oslo) időt, ne az esetleges UTC defaultot
|
// használd a helyi (Oslo) időt, ne az esetleges UTC defaultot
|
||||||
@@ -648,7 +652,7 @@ class Service_model extends CI_Model {
|
|||||||
// --- Lunch break setup ---
|
// --- Lunch break setup ---
|
||||||
// Pre-fetch all bookings for the day so we can do hypothetical checks per slot
|
// Pre-fetch all bookings for the day so we can do hypothetical checks per slot
|
||||||
$workerRow = $this->db->query("SELECT lunch_window_start, lunch_window_end, lunch_preferred_time FROM workers WHERE worker_id = ? LIMIT 1", array($worker_id))->row();
|
$workerRow = $this->db->query("SELECT lunch_window_start, lunch_window_end, lunch_preferred_time FROM workers WHERE worker_id = ? LIMIT 1", array($worker_id))->row();
|
||||||
$shiftSeconds = $finishTime->getTimestamp() - $dayStartTime->getTimestamp();
|
$shiftSeconds = $finishTime->getTimestamp() - $shiftStartTime->getTimestamp();
|
||||||
$lunchRequired = $workerRow && $workerRow->lunch_window_start && $workerRow->lunch_window_end && $shiftSeconds >= 6 * 3600;
|
$lunchRequired = $workerRow && $workerRow->lunch_window_start && $workerRow->lunch_window_end && $shiftSeconds >= 6 * 3600;
|
||||||
|
|
||||||
$allBookings = [];
|
$allBookings = [];
|
||||||
@@ -705,7 +709,7 @@ class Service_model extends CI_Model {
|
|||||||
]]);
|
]]);
|
||||||
$canStillBreak = $this->computeLunchBreak(
|
$canStillBreak = $this->computeLunchBreak(
|
||||||
$workerRow->lunch_window_start, $workerRow->lunch_window_end,
|
$workerRow->lunch_window_start, $workerRow->lunch_window_end,
|
||||||
$selectedDate, $hypo, $finishTime, $dayStartTime,
|
$selectedDate, $hypo, $finishTime, $shiftStartTime,
|
||||||
$workerRow->lunch_preferred_time
|
$workerRow->lunch_preferred_time
|
||||||
) !== null;
|
) !== null;
|
||||||
if (!$canStillBreak) continue; // booking this slot would eliminate the only break opportunity
|
if (!$canStillBreak) continue; // booking this slot would eliminate the only break opportunity
|
||||||
|
|||||||
Reference in New Issue
Block a user