'datetime', 'suspended_until' => 'datetime', 'lifted_at' => 'datetime', 'is_permanent' => 'boolean', 'is_active' => 'boolean', ]; public function user(): BelongsTo { return $this->belongsTo(User::class); } public function suspendedBy(): BelongsTo { return $this->belongsTo(User::class, 'suspended_by'); } public function liftedBy(): BelongsTo { return $this->belongsTo(User::class, 'lifted_by'); } /** * Check if the suspension is currently active */ public function isCurrentlyActive(): bool { if (!$this->is_active) { return false; } if ($this->is_permanent) { return true; } if ($this->suspended_until && Carbon::now()->isAfter($this->suspended_until)) { return false; } return true; } /** * Lift the suspension */ public function lift(int $liftedBy): void { $this->update([ 'is_active' => false, 'lifted_at' => now(), 'lifted_by' => $liftedBy, ]); } /** * Get active suspension for a user */ public static function getActiveSuspension(int $userId): ?self { return static::where('user_id', $userId) ->where('is_active', true) ->where(function ($query) { $query->where('is_permanent', true) ->orWhere('suspended_until', '>', now()) ->orWhereNull('suspended_until'); }) ->first(); } /** * Check if a user is suspended */ public static function isUserSuspended(int $userId): bool { $suspension = static::getActiveSuspension($userId); return $suspension && $suspension->isCurrentlyActive(); } /** * Suspend a user */ public static function suspendUser( int $userId, string $reason, int $suspendedBy, bool $isPermanent = false, ?Carbon $suspendedUntil = null, ?string $notes = null ): self { // Deactivate any existing suspensions static::where('user_id', $userId) ->where('is_active', true) ->update(['is_active' => false]); return static::create([ 'user_id' => $userId, 'reason' => $reason, 'notes' => $notes, 'is_permanent' => $isPermanent, 'suspended_at' => now(), 'suspended_until' => $suspendedUntil, 'suspended_by' => $suspendedBy, 'is_active' => true, ]); } }