ShiftAssignmentStatus::class, 'cancellation_source' => CancellationSource::class, 'auto_approved' => 'boolean', 'assigned_at' => 'datetime', 'approved_at' => 'datetime', 'cancelled_at' => 'datetime', 'checked_in_at' => 'datetime', 'checked_out_at' => 'datetime', 'hours_expected' => 'decimal:2', 'hours_completed' => 'decimal:2', ]; } public function shift(): BelongsTo { return $this->belongsTo(Shift::class); } public function person(): BelongsTo { return $this->belongsTo(Person::class); } public function timeSlot(): BelongsTo { return $this->belongsTo(TimeSlot::class); } public function assignedByUser(): BelongsTo { return $this->belongsTo(User::class, 'assigned_by'); } public function approvedByUser(): BelongsTo { return $this->belongsTo(User::class, 'approved_by'); } public function cancelledByUser(): BelongsTo { return $this->belongsTo(User::class, 'cancelled_by'); } public function scopeActive(Builder $query): Builder { return $query->whereIn('status', [ ShiftAssignmentStatus::PENDING_APPROVAL, ShiftAssignmentStatus::APPROVED, ]); } public function scopeForStatus(Builder $query, ShiftAssignmentStatus $status): Builder { return $query->where('status', $status); } public function isCancellable(): bool { return $this->status->canTransitionTo(ShiftAssignmentStatus::CANCELLED); } public function isApprovable(): bool { return $this->status->canTransitionTo(ShiftAssignmentStatus::APPROVED); } }