with(['profile', 'employee', 'roles']) ->when($tableQuery['search'] !== '', function ($query) use ($tableQuery): void { $search = $tableQuery['search']; $query->where(function ($query) use ($search): void { $query->where('email', 'like', "%{$search}%") ->orWhere('username', 'like', "%{$search}%") ->orWhereHas('profile', function ($query) use ($search): void { $query->where('full_name', 'like', "%{$search}%") ->orWhere('phone_number', 'like', "%{$search}%"); }); }); }) ->when( $role !== '', fn ($query) => $query->whereHas('roles', fn ($query) => $query->where('name', $role)) ) ->when( $gender !== '', fn ($query) => $query->whereHas('profile', fn ($query) => $query->where('gender', $gender)) ) ->when( $employmentStatus !== '', fn ($query) => $query->whereHas('employee', fn ($query) => $query->where('employment_status', $employmentStatus)) ) ->when( $isActive !== '', fn ($query) => $query->where('is_active', $isActive === '1') ); $this->applySorting($query, $tableQuery['sort'], $tableQuery['direction']); return $query ->paginate(10) ->withQueryString(); } /** * @param array $validated */ public function create(array $validated): void { DB::transaction(function () use ($validated): void { $user = User::create([ 'email' => $validated['email'], 'username' => $validated['username'], 'password' => Hash::make(config('auth.password_default')), ]); UserProfile::create([ 'user_id' => $user->id, 'full_name' => $validated['full_name'], 'phone_number' => $validated['phone_number'], 'gender' => $validated['gender'], 'birth_date' => $validated['birth_date'], 'address' => $validated['address'], ]); $hasEmployee = ! empty($validated['join_date']) && ! empty($validated['employment_status']) && ! empty($validated['base_salary']); if ($hasEmployee) { Employee::create([ 'user_id' => $user->id, 'join_date' => $validated['join_date'], 'employment_status' => $validated['employment_status'], 'base_salary' => $validated['base_salary'], ]); } $user->syncRoles([$validated['role']]); }); } /** * @param array $validated */ public function update(User $user, array $validated): void { $employee = $user->employee; DB::transaction(function () use ($validated, $user, $employee): void { $user->email = $validated['email']; $user->username = $validated['username']; $user->save(); $user->profile()->updateOrCreate( ['user_id' => $user->id], [ 'full_name' => $validated['full_name'], 'phone_number' => $validated['phone_number'], 'gender' => $validated['gender'], 'birth_date' => $validated['birth_date'], 'address' => $validated['address'], ], ); $hasEmployee = ! empty($validated['join_date']) && ! empty($validated['employment_status']) && ! empty($validated['base_salary']); if ($hasEmployee) { if ($employee) { $employee->join_date = $validated['join_date']; $employee->employment_status = $validated['employment_status']; $employee->base_salary = $validated['base_salary']; $employee->save(); } else { Employee::create([ 'user_id' => $user->id, 'join_date' => $validated['join_date'], 'employment_status' => $validated['employment_status'], 'base_salary' => $validated['base_salary'], ]); } } else { if ($employee) { $employee->delete(); } } $user->syncRoles([$validated['role']]); }); } public function toggleStatus(User $user, bool $isActive): void { $user->is_active = $isActive; $user->save(); if (! $isActive) { DB::table('sessions')->where('user_id', $user->id)->delete(); } } public function resetPassword(User $user): void { $user->password = config('auth.password_default'); $user->save(); DB::table('sessions')->where('user_id', $user->id)->delete(); } public function delete(User $user): void { DB::transaction(function () use ($user): void { $user->employee?->delete(); $user->profile?->delete(); $user->delete(); }); } private function applySorting(Builder $query, string $sort, string $direction): void { $employeeSorts = [ 'join_date', 'base_salary', 'employment_status', ]; if (in_array($sort, $employeeSorts, true)) { $query->orderBy( Employee::select($sort) ->whereColumn('employees.user_id', 'users.id') ->limit(1), $direction ); return; } if ($sort === 'full_name') { $query->orderBy( UserProfile::select('full_name') ->whereColumn('user_profiles.user_id', 'users.id') ->limit(1), $direction ); return; } if ($sort === 'email') { $query->orderBy('email', $direction); return; } $query->latest(); } }