dstpabuaran.com/app/Services/Admin/HR/LeaveRequestService.php
Yoga Pangestu 22c9a4cf2a feat: add notification highlight feature to various services and frontend components
- Updated paginated methods in multiple services to accept a highlight parameter for filtering results.
- Modified notification URLs to include the highlight parameter for specific entity IDs.
- Enhanced frontend components to display a message when filtered by notification, with an option to show all entries.
- Implemented mark as read functionality in the notification bell component upon clicking a notification.
- Updated multiple index pages to handle the highlight prop and display relevant messages.
2026-08-15 00:11:40 +07:00

156 lines
5.6 KiB
PHP

<?php
namespace App\Services\Admin\HR;
use App\Concerns\HasRoleChecks;
use App\Enums\LeaveRequestStatus;
use App\Enums\Role;
use App\Models\LeaveRequest;
use App\Services\NotificationService;
use Carbon\Carbon;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
class LeaveRequestService
{
use HasRoleChecks;
public function paginated(int $perPage = 25, string $search = '', string $sort = 'created_at', string $direction = 'desc', array $filters = [], ?int $highlight = null): LengthAwarePaginator
{
return LeaveRequest::query()
->select(['id', 'employee_id', 'start_date', 'end_date', 'total_days', 'status', 'created_at'])
->with(['employee.user.userProfile'])
->when($highlight, fn ($q) => $q->where('id', $highlight))
->when(! self::hasAnyRole([Role::DEVELOPER, Role::OWNER, Role::DIREKTUR, Role::ADMIN_TOKO]), fn ($q) => $q->whereHas('employee', fn ($eq) => $eq->where('user_id', auth()->id())))
->when($search, fn ($q) => $q->whereHas('employee.user.userProfile', fn ($uq) => $uq->where('full_name', 'like', "%{$search}%")))
->when($filters['status'] ?? null, function ($query, $status) {
$query->where('status', $status);
})
->orderBy($sort, $direction)
->paginate($perPage);
}
public function store(array $data): LeaveRequest
{
$leaveRequest = DB::transaction(function () use ($data) {
$employee = auth()->user()->employee;
if (! $employee) {
throw ValidationException::withMessages([
'employee' => 'Anda tidak terdaftar sebagai karyawan.',
]);
}
$startDate = new Carbon($data['start_date']);
$endDate = new Carbon($data['end_date']);
$totalDays = $startDate->diffInDays($endDate) + 1;
return LeaveRequest::create([
'employee_id' => $employee->id,
'start_date' => $data['start_date'],
'end_date' => $data['end_date'],
'total_days' => $totalDays,
'status' => LeaveRequestStatus::PENDING,
]);
});
$leaveRequest->load('employee.user');
NotificationService::notify(
roles: [Role::OWNER, Role::DEVELOPER, Role::DIREKTUR, Role::ADMIN_TOKO],
title: 'Pengajuan Cuti Baru',
body: "Pengajuan cuti {$leaveRequest->total_days} hari oleh ".auth()->user()->full_name.'.',
url: route('admin.hr.leave-requests.index', ['highlight' => $leaveRequest->id]),
additionalUser: $leaveRequest->employee->user ?? null,
);
return $leaveRequest;
}
public function update(LeaveRequest $leaveRequest, array $data): LeaveRequest
{
if (! $this->canModify($leaveRequest)) {
throw ValidationException::withMessages([
'employee' => 'Anda tidak memiliki akses untuk mengubah cuti ini.',
]);
}
return DB::transaction(function () use ($leaveRequest, $data) {
$startDate = new Carbon($data['start_date']);
$endDate = new Carbon($data['end_date']);
$totalDays = $startDate->diffInDays($endDate) + 1;
$leaveRequest->update([
'start_date' => $data['start_date'],
'end_date' => $data['end_date'],
'total_days' => $totalDays,
]);
return $leaveRequest;
});
}
public function destroy(LeaveRequest $leaveRequest): bool
{
if (! $this->canModify($leaveRequest)) {
throw ValidationException::withMessages([
'employee' => 'Anda tidak memiliki akses untuk menghapus cuti ini.',
]);
}
return $leaveRequest->delete();
}
public function approve(LeaveRequest $leaveRequest): LeaveRequest
{
$leaveRequest->update([
'status' => LeaveRequestStatus::APPROVED,
'verified_by_id' => auth()->id(),
'verified_at' => now(),
]);
$employeeUser = $leaveRequest->employee->user ?? null;
NotificationService::notify(
roles: [Role::OWNER, Role::DEVELOPER, Role::DIREKTUR, Role::ADMIN_TOKO],
title: 'Cuti Disetujui',
body: "Cuti {$leaveRequest->employee->name} telah disetujui oleh ".auth()->user()->full_name.'.',
url: route('admin.hr.leave-requests.index', ['highlight' => $leaveRequest->id]),
additionalUser: $employeeUser,
);
return $leaveRequest;
}
public function reject(LeaveRequest $leaveRequest): LeaveRequest
{
$leaveRequest->update([
'status' => LeaveRequestStatus::REJECTED,
'verified_by_id' => auth()->id(),
'verified_at' => now(),
]);
$employeeUser = $leaveRequest->employee->user ?? null;
NotificationService::notify(
roles: [Role::OWNER, Role::DEVELOPER, Role::DIREKTUR, Role::ADMIN_TOKO],
title: 'Cuti Ditolak',
body: "Cuti {$leaveRequest->employee->name} telah ditolak oleh ".auth()->user()->full_name.'.',
url: route('admin.hr.leave-requests.index', ['highlight' => $leaveRequest->id]),
additionalUser: $employeeUser,
);
return $leaveRequest;
}
private function canModify(LeaveRequest $leaveRequest): bool
{
if (self::hasAnyRole([Role::DEVELOPER, Role::OWNER])) {
return true;
}
return $leaveRequest->employee->user_id === auth()->id();
}
}