*/ use HasFactory, HasUuids, Notifiable; /** * @var list */ protected $fillable = [ 'workspace_id', 'invited_by', 'email', 'token', 'role', 'status', 'expires_at', 'accepted_at', ]; /** * @return array */ protected function casts(): array { return [ 'role' => WorkspaceRole::class, 'status' => InviteStatus::class, 'expires_at' => 'datetime', 'accepted_at' => 'datetime', ]; } protected static function booted(): void { static::creating(function (WorkspaceInvite $invite) { if (empty($invite->token)) { $invite->token = Str::random(64); } if (empty($invite->expires_at)) { $invite->expires_at = now()->addDays(7); } }); } public function workspace(): BelongsTo { return $this->belongsTo(Workspace::class); } public function inviter(): BelongsTo { return $this->belongsTo(User::class, 'invited_by'); } public function scopePending(Builder $query): Builder { return $query->where('status', InviteStatus::Pending); } public function scopeValid(Builder $query): Builder { return $query->pending()->where('expires_at', '>', now()); } public function isExpired(): bool { return $this->expires_at->isPast(); } public function isPending(): bool { return $this->status === InviteStatus::Pending; } public function isValid(): bool { return $this->isPending() && ! $this->isExpired(); } public function accept(User $user): void { $this->workspace->members()->attach($user->id, [ 'role' => $this->role, ]); $this->update([ 'status' => InviteStatus::Accepted, 'accepted_at' => now(), ]); } public function cancel(): void { $this->update(['status' => InviteStatus::Cancelled]); } public function routeNotificationForMail(): string { return $this->email; } }