Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Zap Availability
laraveljutsu/zap
claude-code
schedule
calendar
management
laravel
booking

This skill covers checking availability, retrieving bookable slots, and querying schedules in Laravel Zap.

Install
php artisan boost:add-skill laraveljutsu/zap

Save this content to: .claude/skills/zap-availability/SKILL.md

# Laravel Zap - Availability & Bookable Slots

This skill covers checking availability, retrieving bookable slots, and querying schedules in Laravel Zap.

## Checking Bookability

### Check if Bookable on a Date

```php
// Check if there is at least one bookable slot on the day
// Parameters: date, slot duration in minutes
$isBookable = $doctor->isBookableAt('2025-01-15', 60);

// With buffer time (minutes between slots)
$isBookable = $doctor->isBookableAt('2025-01-15', 60, 15);
```

### Check Specific Time Range

```php
// Check if a specific time range is bookable
$isBookable = $doctor->isBookableAtTime('2025-01-15', '09:00', '09:30');
```

## Getting Bookable Slots

```php
// Get all bookable slots for a date
// Parameters: date, slot duration (minutes), buffer (minutes)
$slots = $doctor->getBookableSlots('2025-01-15', 60, 15);

// Returns array of slots:
// [
//     ['start_time' => '09:00', 'end_time' => '10:00', 'is_available' => true, 'buffer_minutes' => 15],
//     ['start_time' => '10:15', 'end_time' => '11:15', 'is_available' => false, 'buffer_minutes' => 15],
//     ...
// ]
```

Bookable slots are generated based on:
1. Availability schedules (defines when the resource CAN be booked)
2. Appointment, blocked, and custom schedules (defines when slots are NOT available)

## Finding Next Available Slot

```php
// Find the next available slot starting from a date
$nextSlot = $doctor->getNextBookableSlot('2025-01-15', 60, 15);

// Returns: ['start_time' => '09:00', 'end_time' => '10:00', 'is_available' => true, 'date' => '2025-01-15', 'buffer_minutes' => 15]

// Start from today
$nextSlot = $doctor->getNextBookableSlot(null, 60);
```

The method searches up to 365 days in the future to cover all recurring frequencies.

## Querying Schedules

### By Date

```php
// Get schedules for a specific date
$schedules = $doctor->schedulesForDate('2025-01-15')->get();

// Get schedules within a date range
$schedules = $doctor->schedulesForDateRange('2025-01-01', '2025-01-31')->get();
```

### By Type

```php
// Get only appointment schedules
$appointments = $doctor->appointmentSchedules()->get();

// Get only availability schedules
$availabilities = $doctor->availabilitySchedules()->get();

// Get only blocked schedules
$blocked = $doctor->blockedSchedules()->get();

// Get schedules of a specific type
$schedules = $doctor->schedulesOfType('appointment')->get();
```

### By State

```php
// Get only active schedules
$active = $doctor->activeSchedules()->get();

// Get recurring schedules
$recurring = $doctor->recurringSchedules()->get();

// Get all schedules
$all = $doctor->schedules()->get();
```

### Query Builder Scopes

The Schedule model provides these query scopes:

```php
use Zap\Models\Schedule;

Schedule::active()->get();                          // Only active schedules
Schedule::recurring()->get();                       // Only recurring schedules
Schedule::ofType(ScheduleTypes::APPOINTMENT)->get(); // By type
Schedule::availability()->get();                    // Availability schedules
Schedule::appointments()->get();                    // Appointment schedules
Schedule::blocked()->get();                         // Blocked schedules
Schedule::forDate('2025-01-15')->get();             // For specific date
Schedule::forDateRange('2025-01-01', '2025-01-31')->get(); // For date range
```

## Total Scheduled Time

```php
// Get total scheduled time in minutes for a date range
$totalMinutes = $doctor->getTotalScheduledTime('2025-01-01', '2025-12-31');
```

## Checking for Schedules

```php
// Check if the model has any schedules
$hasSchedules = $doctor->hasSchedules();

// Check if the model has any active schedules
$hasActive = $doctor->hasActiveSchedules();
```

## Real-World Example: Doctor Appointment System

```php
use Zap\Facades\Zap;

// 1. Set up doctor's office hours
Zap::for($doctor)
    ->named('Office Hours')
    ->availability()
    ->forYear(2025)
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
    ->addPeriod('09:00', '12:00')
    ->addPeriod('14:00', '17:00')
    ->save();

// 2. Block lunch time
Zap::for($doctor)
    ->named('Lunch Break')
    ->blocked()
    ->forYear(2025)
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
    ->addPeriod('12:00', '13:00')
    ->save();

// 3. Get available slots for booking
$slots = $doctor->getBookableSlots('2025-01-15', 60, 15);

// 4. Check if specific time is available before booking
if ($doctor->isBookableAtTime('2025-01-15', '10:00', '11:00')) {
    // Book the appointment
    Zap::for($doctor)
        ->named('Patient Consultation')
        ->appointment()
        ->from('2025-01-15')
        ->addPeriod('10:00', '11:00')
        ->withMetadata(['patient_id' => $patientId])
        ->save();
}

// 5. Find next available slot for a patient
$nextSlot = $doctor->getNextBookableSlot(now()->format('Y-m-d'), 60);
```

## Real-World Example: Meeting Room Booking

```php
// Room availability
Zap::for($room)
    ->named('Conference Room A')
    ->availability()
    ->weekDays(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'], '08:00', '18:00')
    ->forYear(2025)
    ->save();

// Get available slots
$slots = $room->getBookableSlots('2025-03-15', 60);

// Book meeting
Zap::for($room)
    ->named('Board Meeting')
    ->appointment()
    ->from('2025-03-15')
    ->addPeriod('09:00', '11:00')
    ->withMetadata(['organizer' => '[email protected]'])
    ->save();
```

## Buffer Time Configuration

Buffer time adds spacing between slots:

```php
// In config/zap.php
'time_slots' => [
    'buffer_minutes' => 15, // Default buffer between slots
],

// Or per-call
$slots = $doctor->getBookableSlots('2025-01-15', 60, 15); // 15 min buffer
```

With a 15-minute buffer and 60-minute slots:
- Slot 1: 09:00 - 10:00
- Slot 2: 10:15 - 11:15 (15 min buffer after slot 1)
- Slot 3: 11:30 - 12:30

Laravel Zap - Availability & Bookable Slots

This skill covers checking availability, retrieving bookable slots, and querying schedules in Laravel Zap.

Checking Bookability

Check if Bookable on a Date

// Check if there is at least one bookable slot on the day
// Parameters: date, slot duration in minutes
$isBookable = $doctor->isBookableAt('2025-01-15', 60);

// With buffer time (minutes between slots)
$isBookable = $doctor->isBookableAt('2025-01-15', 60, 15);

Check Specific Time Range

// Check if a specific time range is bookable
$isBookable = $doctor->isBookableAtTime('2025-01-15', '09:00', '09:30');

Getting Bookable Slots

// Get all bookable slots for a date
// Parameters: date, slot duration (minutes), buffer (minutes)
$slots = $doctor->getBookableSlots('2025-01-15', 60, 15);

// Returns array of slots:
// [
//     ['start_time' => '09:00', 'end_time' => '10:00', 'is_available' => true, 'buffer_minutes' => 15],
//     ['start_time' => '10:15', 'end_time' => '11:15', 'is_available' => false, 'buffer_minutes' => 15],
//     ...
// ]

Bookable slots are generated based on:

  1. Availability schedules (defines when the resource CAN be booked)
  2. Appointment, blocked, and custom schedules (defines when slots are NOT available)

Finding Next Available Slot

// Find the next available slot starting from a date
$nextSlot = $doctor->getNextBookableSlot('2025-01-15', 60, 15);

// Returns: ['start_time' => '09:00', 'end_time' => '10:00', 'is_available' => true, 'date' => '2025-01-15', 'buffer_minutes' => 15]

// Start from today
$nextSlot = $doctor->getNextBookableSlot(null, 60);

The method searches up to 365 days in the future to cover all recurring frequencies.

Querying Schedules

By Date

// Get schedules for a specific date
$schedules = $doctor->schedulesForDate('2025-01-15')->get();

// Get schedules within a date range
$schedules = $doctor->schedulesForDateRange('2025-01-01', '2025-01-31')->get();

By Type

// Get only appointment schedules
$appointments = $doctor->appointmentSchedules()->get();

// Get only availability schedules
$availabilities = $doctor->availabilitySchedules()->get();

// Get only blocked schedules
$blocked = $doctor->blockedSchedules()->get();

// Get schedules of a specific type
$schedules = $doctor->schedulesOfType('appointment')->get();

By State

// Get only active schedules
$active = $doctor->activeSchedules()->get();

// Get recurring schedules
$recurring = $doctor->recurringSchedules()->get();

// Get all schedules
$all = $doctor->schedules()->get();

Query Builder Scopes

The Schedule model provides these query scopes:

use Zap\Models\Schedule;

Schedule::active()->get();                          // Only active schedules
Schedule::recurring()->get();                       // Only recurring schedules
Schedule::ofType(ScheduleTypes::APPOINTMENT)->get(); // By type
Schedule::availability()->get();                    // Availability schedules
Schedule::appointments()->get();                    // Appointment schedules
Schedule::blocked()->get();                         // Blocked schedules
Schedule::forDate('2025-01-15')->get();             // For specific date
Schedule::forDateRange('2025-01-01', '2025-01-31')->get(); // For date range

Total Scheduled Time

// Get total scheduled time in minutes for a date range
$totalMinutes = $doctor->getTotalScheduledTime('2025-01-01', '2025-12-31');

Checking for Schedules

// Check if the model has any schedules
$hasSchedules = $doctor->hasSchedules();

// Check if the model has any active schedules
$hasActive = $doctor->hasActiveSchedules();

Real-World Example: Doctor Appointment System

use Zap\Facades\Zap;

// 1. Set up doctor's office hours
Zap::for($doctor)
    ->named('Office Hours')
    ->availability()
    ->forYear(2025)
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
    ->addPeriod('09:00', '12:00')
    ->addPeriod('14:00', '17:00')
    ->save();

// 2. Block lunch time
Zap::for($doctor)
    ->named('Lunch Break')
    ->blocked()
    ->forYear(2025)
    ->weekly(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
    ->addPeriod('12:00', '13:00')
    ->save();

// 3. Get available slots for booking
$slots = $doctor->getBookableSlots('2025-01-15', 60, 15);

// 4. Check if specific time is available before booking
if ($doctor->isBookableAtTime('2025-01-15', '10:00', '11:00')) {
    // Book the appointment
    Zap::for($doctor)
        ->named('Patient Consultation')
        ->appointment()
        ->from('2025-01-15')
        ->addPeriod('10:00', '11:00')
        ->withMetadata(['patient_id' => $patientId])
        ->save();
}

// 5. Find next available slot for a patient
$nextSlot = $doctor->getNextBookableSlot(now()->format('Y-m-d'), 60);

Real-World Example: Meeting Room Booking

// Room availability
Zap::for($room)
    ->named('Conference Room A')
    ->availability()
    ->weekDays(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'], '08:00', '18:00')
    ->forYear(2025)
    ->save();

// Get available slots
$slots = $room->getBookableSlots('2025-03-15', 60);

// Book meeting
Zap::for($room)
    ->named('Board Meeting')
    ->appointment()
    ->from('2025-03-15')
    ->addPeriod('09:00', '11:00')
    ->withMetadata(['organizer' => '[email protected]'])
    ->save();

Buffer Time Configuration

Buffer time adds spacing between slots:

// In config/zap.php
'time_slots' => [
    'buffer_minutes' => 15, // Default buffer between slots
],

// Or per-call
$slots = $doctor->getBookableSlots('2025-01-15', 60, 15); // 15 min buffer

With a 15-minute buffer and 60-minute slots:

  • Slot 1: 09:00 - 10:00
  • Slot 2: 10:15 - 11:15 (15 min buffer after slot 1)
  • Slot 3: 11:30 - 12:30
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
vento/laravel-airbrake
wfeller/laravel-batch
maco-studios/mage-os-installer
busarm/armie
siberfx/laravel-logger
kfteam1991/dcat-admin
dashed/dashed-laposta
dashed/dashed-ecommerce-montaportal
dashed/dashed-ecommerce-etsy
neohq/string-blade-compiler
log1x/acf-composer
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager