FilamentF
Filament13mo ago
Raven

Validation for overlapping date/time fields

Hello! I've got a TimeLog resource which is for users to clock in and clock out. How do I make sure that the clock_in and clock_out timestamps are not overlapping with any other entry in the database for that user? I've got a validation rule right now that I'm applying to both of the timestamp fields, but I don't like how messy it is and was wondering if there's a better way:
$noOverlappingClocks = fn(Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) {
    $userId = $get('user_id');
    $clockIn = $get('clock_in');
    $clockOut = $get('clock_out');

    if ($clockIn && $clockOut) {
        $overlap = TimeLog::query()
            ->where('user_id', $userId)
            ->where(function ($query) use ($clockIn, $clockOut) {
                $query->whereBetween('clock_in', [$clockIn, $clockOut])
                    ->orWhereBetween('clock_out', [$clockIn, $clockOut])
                    ->orWhere(function ($query) use ($clockIn, $clockOut) {
                        $query->where('clock_in', '<', $clockIn)
                            ->where('clock_out', '>', $clockOut);
                    });
            })
            ->exists();

        if ($overlap) {
            $fail("The provided time log overlaps with an existing entry.");
        }
    }
};


It also does error when editing an existing entry even tho it only "overlaps" with itself.
Solution
Laracasts
Was this page helpful?