282 lines
9.2 KiB
PHP
282 lines
9.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin\Hr;
|
|
|
|
use App\Enums\EmploymentStatus;
|
|
use App\Enums\Gender;
|
|
use App\Http\Controllers\Concerns\ParsesDataTableQuery;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Admin\Hr\EmployeeRequest;
|
|
use App\Models\Employee;
|
|
use App\Models\User;
|
|
use App\Models\UserProfile;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class EmployeeController extends Controller
|
|
{
|
|
use ParsesDataTableQuery;
|
|
|
|
public function index(Request $request): Response
|
|
{
|
|
$tableQuery = $this->parseDataTableQuery($request);
|
|
$search = $tableQuery['search'];
|
|
$sort = $tableQuery['sort'];
|
|
$direction = $tableQuery['direction'];
|
|
|
|
$employmentStatus = $request->string('employment_status')->toString();
|
|
|
|
$query = User::query()
|
|
->with(['profile', 'employee'])
|
|
->whereHas('employee')
|
|
->when($search !== '', function ($query) use ($search): void {
|
|
$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(
|
|
$employmentStatus !== '',
|
|
fn ($query) => $query->whereHas('employee', fn ($query) => $query->where('employment_status', $employmentStatus))
|
|
);
|
|
|
|
$this->applySorting($query, $sort, $direction);
|
|
|
|
$employees = $query
|
|
->paginate(10)
|
|
->withQueryString()
|
|
->through(fn (User $user) => $this->transformEmployee($user));
|
|
|
|
return Inertia::render('admin/hr/employees/Index', [
|
|
'employees' => $employees,
|
|
'filters' => $this->dataTableFilters($tableQuery, [
|
|
'employment_status' => $employmentStatus,
|
|
]),
|
|
'employmentStatuses' => EmploymentStatus::selectOptions(),
|
|
]);
|
|
}
|
|
|
|
public function create(): Response
|
|
{
|
|
return Inertia::render('admin/hr/employees/Create', [
|
|
'genders' => Gender::selectOptions(),
|
|
'employmentStatuses' => EmploymentStatus::selectOptions(),
|
|
]);
|
|
}
|
|
|
|
public function store(EmployeeRequest $request): RedirectResponse
|
|
{
|
|
$validated = $request->validated();
|
|
|
|
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'],
|
|
]);
|
|
|
|
Employee::create([
|
|
'user_id' => $user->id,
|
|
'join_date' => $validated['join_date'],
|
|
'employment_status' => $validated['employment_status'],
|
|
'base_salary' => $validated['base_salary'],
|
|
]);
|
|
});
|
|
|
|
Inertia::flash('success', 'Pegawai berhasil ditambahkan.');
|
|
|
|
return redirect()->route('admin.hr.employees.index');
|
|
}
|
|
|
|
public function edit(User $user): Response
|
|
{
|
|
$user->load(['profile', 'employee']);
|
|
|
|
return Inertia::render('admin/hr/employees/Edit', [
|
|
'genders' => Gender::selectOptions(),
|
|
'employmentStatuses' => EmploymentStatus::selectOptions(),
|
|
'employee' => $this->transformEmployeeForForm($user),
|
|
]);
|
|
}
|
|
|
|
public function update(EmployeeRequest $request, User $user): RedirectResponse
|
|
{
|
|
$validated = $request->validated();
|
|
$employee = $user->employee;
|
|
|
|
DB::transaction(function () use ($validated, $user, $employee): void {
|
|
$user->email = $validated['email'];
|
|
$user->username = $validated['username'];
|
|
$user->save();
|
|
|
|
$profile = $user->profile;
|
|
$profile->full_name = $validated['full_name'];
|
|
$profile->phone_number = $validated['phone_number'];
|
|
$profile->gender = $validated['gender'];
|
|
$profile->birth_date = $validated['birth_date'];
|
|
$profile->address = $validated['address'];
|
|
$profile->save();
|
|
|
|
$employee->join_date = $validated['join_date'];
|
|
$employee->employment_status = $validated['employment_status'];
|
|
$employee->base_salary = $validated['base_salary'];
|
|
$employee->save();
|
|
});
|
|
|
|
Inertia::flash('success', 'Data pegawai berhasil diperbarui.');
|
|
|
|
return redirect()->route('admin.hr.employees.index');
|
|
}
|
|
|
|
public function toggleStatus(Request $request, User $user): RedirectResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'is_active' => ['required', 'boolean'],
|
|
]);
|
|
|
|
$user->is_active = $validated['is_active'];
|
|
$user->save();
|
|
|
|
if (! $validated['is_active']) {
|
|
DB::table('sessions')->where('user_id', $user->id)->delete();
|
|
}
|
|
|
|
Inertia::flash('success', 'Status pegawai berhasil diperbarui.');
|
|
|
|
return back();
|
|
}
|
|
|
|
public function resetPassword(User $user): RedirectResponse
|
|
{
|
|
$user->password = config('auth.password_default');
|
|
$user->save();
|
|
|
|
DB::table('sessions')->where('user_id', $user->id)->delete();
|
|
|
|
Inertia::flash('success', 'Kata sandi berhasil direset. Pengguna telah logout dari semua sesi.');
|
|
|
|
return back();
|
|
}
|
|
|
|
public function destroy(User $user): RedirectResponse
|
|
{
|
|
DB::transaction(function () use ($user): void {
|
|
$user->employee?->delete();
|
|
$user->profile?->delete();
|
|
$user->delete();
|
|
});
|
|
|
|
Inertia::flash('success', 'Pegawai berhasil dihapus.');
|
|
|
|
return redirect()->route('admin.hr.employees.index');
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function transformEmployeeForForm(User $user): array
|
|
{
|
|
$employee = $user->employee;
|
|
$profile = $user->profile;
|
|
|
|
return [
|
|
'id' => $user->id,
|
|
'email' => $user->email,
|
|
'username' => $user->username,
|
|
'full_name' => $profile->full_name,
|
|
'phone_number' => $profile->phone_number,
|
|
'gender' => $profile->gender?->value,
|
|
'birth_date' => $profile->birth_date?->format('Y-m-d'),
|
|
'address' => $profile->address,
|
|
'join_date' => $employee->join_date?->format('Y-m-d'),
|
|
'employment_status' => $employee->employment_status?->value,
|
|
'base_salary' => $employee->base_salary,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function transformEmployee(User $user): array
|
|
{
|
|
$employee = $user->employee;
|
|
$profile = $user->profile;
|
|
|
|
return [
|
|
'id' => $user->id,
|
|
'join_date' => $employee->join_date_formatted,
|
|
'resign_date' => $employee->resign_date_formatted,
|
|
'employment_status' => $employee->employment_status?->value,
|
|
'employment_status_label' => $employee->employment_status?->label(),
|
|
'base_salary' => $employee->base_salary,
|
|
'base_salary_formatted' => $employee->base_salary_formatted,
|
|
'email' => $user->email,
|
|
'username' => $user->username,
|
|
'is_active' => $user->is_active,
|
|
'full_name' => $profile->full_name,
|
|
'phone_number' => $profile->phone_number,
|
|
'gender' => $profile->gender?->value,
|
|
'gender_label' => $profile->gender?->label(),
|
|
'birth_date' => $profile->birth_date_formatted,
|
|
'address' => $profile->address,
|
|
];
|
|
}
|
|
}
|