Initial commit
This commit is contained in:
commit
c909d539bc
7178 files changed
+756624
No files matched your search
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ExternalBusyWindow;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class AvailabilityService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $tz = 'Europe/London',
|
||||
private readonly int $bufferMins = 40
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Check if a single slot (date + time) is blocked by external busy windows,
|
||||
* considering a travel buffer before start and after end.
|
||||
*/
|
||||
public function isSlotBlockedByExternalBusy(string $dateYmd, string $timeHi, int $durationMins = 60): bool
|
||||
{
|
||||
// Build slot window in UTC
|
||||
$slotStartLocal = Carbon::createFromFormat('Y-m-d H:i', "{$dateYmd} {$timeHi}", $this->tz);
|
||||
$slotStartUtc = $slotStartLocal->clone()->utc();
|
||||
$slotEndUtc = $slotStartUtc->clone()->addMinutes($durationMins);
|
||||
|
||||
// Expand comparison bounds by buffer
|
||||
$slotStartMinusBuffer = $slotStartUtc->clone()->subMinutes($this->bufferMins);
|
||||
$slotEndPlusBuffer = $slotEndUtc->clone()->addMinutes($this->bufferMins);
|
||||
|
||||
// Overlap: busyStart < slotEnd+buffer AND busyEnd > slotStart-buffer
|
||||
return ExternalBusyWindow::query()
|
||||
->where('starts_at', '<', $slotEndPlusBuffer)
|
||||
->where('ends_at', '>', $slotStartMinusBuffer)
|
||||
->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* For block-booking: given a set of future candidate dates for a given time,
|
||||
* return the subset that are blocked (with reasons).
|
||||
*
|
||||
* @param array<string> $dateListYmd e.g. ['2025-10-27','2025-11-03', ...]
|
||||
* @return array<int, array{date:string, blocked:bool}>
|
||||
*/
|
||||
public function checkSeriesConflicts(array $dateListYmd, string $timeHi, int $durationMins = 60): array
|
||||
{
|
||||
$results = [];
|
||||
foreach ($dateListYmd as $ymd) {
|
||||
$blocked = $this->isSlotBlockedByExternalBusy($ymd, $timeHi, $durationMins);
|
||||
$results[] = [
|
||||
'date' => $ymd,
|
||||
'blocked' => $blocked,
|
||||
];
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user