API Reference

Querying & Metadata

Querying schedules and managing metadata effectively.

Basic Queries

Query by Date

// Get schedules for specific date
$todaySchedules = $user->schedulesForDate(today());

// Get schedules for date range
$weekSchedules = $user->schedulesForDateRange('2025-03-11', '2025-03-17');

// Get schedules for current month
$monthSchedules = $user->schedulesForDateRange(
    now()->startOfMonth(),
    now()->endOfMonth()
);

Query by Status

// Get active schedules
$activeSchedules = Schedule::active()->get();

// Get schedules for specific model
$userSchedules = Schedule::where('schedulable_id', $user->id)
    ->where('schedulable_type', User::class)
    ->get();

Advanced Querying

Time-Based Queries

// Schedules with periods in specific time range
$schedules = Schedule::active()
    ->forDate('2025-03-15')
    ->whereHas('periods', function ($query) {
        $query->whereBetween('start_time', ['09:00', '17:00']);
    })
    ->get();

// Morning schedules only
$morningSchedules = Schedule::whereHas('periods', function ($query) {
    $query->where('start_time', '<', '12:00');
})->get();

Filtering by Metadata

// Find schedules with specific metadata
$consultations = Schedule::whereJsonContains('metadata->type', 'consultation')->get();

// Find high-priority schedules
$urgent = Schedule::whereJsonContains('metadata->priority', 'high')->get();

// Find schedules by location
$roomA = Schedule::whereJsonContains('metadata->location', 'Conference Room A')->get();

Working with Metadata

Adding Metadata

$schedule = Zap::for($user)
    ->named('Client Meeting')
    ->from('2025-03-15')
    ->addPeriod('14:00', '16:00')
    ->withMetadata([
        'location' => 'Conference Room A',
        'priority' => 'high',
        'attendees' => ['john@example.com', 'jane@example.com'],
        'client_id' => 123,
        'project' => 'Website Redesign'
    ])
    ->save();

Accessing Metadata

// Get specific metadata values
$location = $schedule->metadata['location'] ?? 'Not specified';
$priority = $schedule->metadata['priority'] ?? 'normal';
$attendees = $schedule->metadata['attendees'] ?? [];

// Check if metadata key exists
if (isset($schedule->metadata['client_id'])) {
    $client = Client::find($schedule->metadata['client_id']);
}

Updating Metadata

// Update existing metadata
$schedule->update([
    'metadata' => array_merge($schedule->metadata, [
        'status' => 'confirmed',
        'notes' => 'Client confirmed attendance'
    ])
]);

// Replace all metadata
$schedule->update([
    'metadata' => [
        'new_location' => 'Virtual Meeting',
        'platform' => 'Zoom'
    ]
]);

Relationship Queries

Using Model relationships

// Get user's appointments only
$appointments = $user->appointmentSchedules()
    ->with('periods')
    ->get();

// Get user's availability
$availability = $user->availabilitySchedules()
    ->where('date_from', '<=', today())
    ->where('date_to', '>=', today())
    ->get();

// Get blocked schedules
$blocked = $user->blockedSchedules()
    ->forDate(today())
    ->get();

Eager Loading

// Load schedules with periods
$schedules = Schedule::with('periods')
    ->where('schedulable_id', $user->id)
    ->get();

// Load schedules with model
$schedules = Schedule::with('schedulable')
    ->forDate(today())
    ->get();

Real-World Example: Employee Management

// Query employee schedules with metadata
$employee = User::find(1);

// Get this week's shifts with location info
$shifts = $employee->schedules()
    ->forDateRange(now()->startOfWeek(), now()->endOfWeek())
    ->whereJsonContains('metadata->type', 'shift')
    ->get()
    ->map(function ($schedule) {
        return [
            'name' => $schedule->name,
            'date' => $schedule->date_from,
            'periods' => $schedule->periods->pluck(['start_time', 'end_time']),
            'location' => $schedule->metadata['location'] ?? 'Main Office',
            'department' => $schedule->metadata['department'] ?? 'General'
        ];
    });

// Find vacation requests
$vacations = $employee->blockedSchedules()
    ->whereJsonContains('metadata->type', 'vacation')
    ->where('date_from', '>=', today())
    ->orderBy('date_from')
    ->get();

// Get overtime schedules
$overtime = $employee->schedules()
    ->whereHas('periods', function ($query) {
        $query->where('start_time', '<', '09:00')
              ->orWhere('end_time', '>', '17:00');
    })
    ->whereJsonContains('metadata->overtime', true)
    ->get();