160 lines
6.7 KiB
PHP
160 lines
6.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Admin\HR;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class EmployeeService
|
|
{
|
|
private const ADMIN_ROLES = ['developer', 'owner', 'direktur', 'admin-toko'];
|
|
private const RESTRICTED_ROLES = ['admin-toko', 'direktur'];
|
|
|
|
public function canViewAll(): bool
|
|
{
|
|
return auth()->user()->hasAnyRole(self::ADMIN_ROLES);
|
|
}
|
|
|
|
public function shouldHideAdminBahanBaku(): bool
|
|
{
|
|
return auth()->user()->hasAnyRole(self::RESTRICTED_ROLES);
|
|
}
|
|
|
|
public function getAll(array $filters = []): Collection
|
|
{
|
|
return User::select(['id', 'email', 'username', 'is_active'])
|
|
->where(fn ($q) => $q->whereHas('employee')->orWhereHas('roles', fn ($rq) => $rq->where('name', 'Owner')))
|
|
->with([
|
|
'userProfile' => fn ($q) => $q->select(['id', 'user_id', 'full_name', 'phone_number', 'gender']),
|
|
'employee' => fn ($q) => $q->select(['id', 'user_id', 'join_date', 'employment_status', 'base_salary']),
|
|
'roles' => fn ($q) => $q->select(['id', 'name']),
|
|
])
|
|
->when(! $this->canViewAll(), function ($q) {
|
|
$userRoles = auth()->user()->roles->pluck('name');
|
|
$q->whereHas('roles', fn ($rq) => $rq->whereIn('name', $userRoles));
|
|
})
|
|
->when($this->shouldHideAdminBahanBaku(), fn ($q) => $q->whereDoesntHave('roles', fn ($rq) => $rq->where('name', 'admin-bahan-baku')))
|
|
->when($filters['employment_status'] ?? null, fn ($q, $status) => $q->whereHas('employee', fn ($eq) => $eq->where('employment_status', $status)))
|
|
->when(isset($filters['is_active']) && $filters['is_active'] !== '', fn ($q) => $q->where('is_active', filter_var($filters['is_active'], FILTER_VALIDATE_BOOLEAN)))
|
|
->when($filters['gender'] ?? null, fn ($q, $gender) => $q->whereHas('userProfile', fn ($uq) => $uq->where('gender', $gender)))
|
|
->latest()
|
|
->get();
|
|
}
|
|
|
|
public function paginated(int $perPage = 25, string $search = '', string $sort = 'created_at', string $direction = 'desc', array $filters = []): LengthAwarePaginator
|
|
{
|
|
return User::query()
|
|
->select(['id', 'email', 'username', 'is_active'])
|
|
->where(fn ($q) => $q->whereHas('employee')->orWhereHas('roles', fn ($rq) => $rq->where('name', 'Owner')))
|
|
->with([
|
|
'userProfile' => fn ($q) => $q->select(['id', 'user_id', 'full_name', 'phone_number', 'gender']),
|
|
'employee' => fn ($q) => $q->select(['id', 'user_id', 'join_date', 'employment_status', 'base_salary']),
|
|
'roles' => fn ($q) => $q->select(['id', 'name']),
|
|
])
|
|
->when(! $this->canViewAll(), function ($q) {
|
|
$userRoles = auth()->user()->roles->pluck('name');
|
|
$q->whereHas('roles', fn ($rq) => $rq->whereIn('name', $userRoles));
|
|
})
|
|
->when($this->shouldHideAdminBahanBaku(), fn ($q) => $q->whereDoesntHave('roles', fn ($rq) => $rq->where('name', 'admin-bahan-baku')))
|
|
->when($search, fn ($q) => $q->whereHas('userProfile', fn ($uq) => $uq->where('full_name', 'like', "%{$search}%")))
|
|
->when($filters['employment_status'] ?? null, fn ($q, $status) => $q->whereHas('employee', fn ($eq) => $eq->where('employment_status', $status)))
|
|
->when(isset($filters['is_active']) && $filters['is_active'] !== '', fn ($q) => $q->where('is_active', filter_var($filters['is_active'], FILTER_VALIDATE_BOOLEAN)))
|
|
->when($filters['gender'] ?? null, fn ($q, $gender) => $q->whereHas('userProfile', fn ($uq) => $uq->where('gender', $gender)))
|
|
->orderBy($sort, $direction)
|
|
->paginate($perPage);
|
|
}
|
|
|
|
public function store(array $data): User
|
|
{
|
|
return DB::transaction(function () use ($data) {
|
|
$user = User::create([
|
|
'email' => $data['email'],
|
|
'username' => $data['username'],
|
|
'password' => config('auth.password_default'),
|
|
'is_active' => true,
|
|
]);
|
|
|
|
$user->assignRole($data['role']);
|
|
|
|
$user->userProfile()->create([
|
|
'full_name' => $data['full_name'],
|
|
'phone_number' => $data['phone_number'] ?? null,
|
|
'gender' => $data['gender'] ?? null,
|
|
'birth_date' => $data['birth_date'] ?? null,
|
|
'address' => $data['address'] ?? null,
|
|
]);
|
|
|
|
if ($data['role'] !== 'owner') {
|
|
$user->employee()->create([
|
|
'join_date' => $data['join_date'],
|
|
'resign_date' => $data['resign_date'] ?? null,
|
|
'employment_status' => $data['employment_status'],
|
|
'base_salary' => $data['base_salary'],
|
|
]);
|
|
}
|
|
|
|
return $user;
|
|
});
|
|
}
|
|
|
|
public function update(User $user, array $data): User
|
|
{
|
|
DB::transaction(function () use ($user, $data) {
|
|
$user->update([
|
|
'email' => $data['email'],
|
|
'username' => $data['username'],
|
|
]);
|
|
|
|
$user->syncRoles($data['role']);
|
|
|
|
$user->userProfile()->updateOrCreate([], [
|
|
'full_name' => $data['full_name'],
|
|
'phone_number' => $data['phone_number'] ?? null,
|
|
'gender' => $data['gender'] ?? null,
|
|
'birth_date' => $data['birth_date'] ?? null,
|
|
'address' => $data['address'] ?? null,
|
|
]);
|
|
|
|
if ($data['role'] !== 'owner') {
|
|
$user->employee()->updateOrCreate([], [
|
|
'join_date' => $data['join_date'],
|
|
'resign_date' => $data['resign_date'] ?? null,
|
|
'employment_status' => $data['employment_status'],
|
|
'base_salary' => $data['base_salary'],
|
|
]);
|
|
} else {
|
|
$user->employee()->delete();
|
|
}
|
|
});
|
|
|
|
return $user->fresh(['userProfile', 'employee']);
|
|
}
|
|
|
|
public function destroy(User $user): bool
|
|
{
|
|
return DB::transaction(function () use ($user) {
|
|
$user->employee()->delete();
|
|
$user->userProfile()->delete();
|
|
|
|
return $user->delete();
|
|
});
|
|
}
|
|
|
|
public function toggleActive(User $user): User
|
|
{
|
|
$user->update(['is_active' => ! $user->is_active]);
|
|
|
|
return $user;
|
|
}
|
|
|
|
public function resetPassword(User $user): User
|
|
{
|
|
$defaultPassword = config('auth.password_default');
|
|
$user->update(['password' => $defaultPassword]);
|
|
|
|
return $user;
|
|
}
|
|
}
|