85 lines
2.5 KiB
PHP
85 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Enums\ApprovalStatus;
|
|
use App\Enums\TravelStatus;
|
|
use App\Jobs\SendApprovalDecisionEmail;
|
|
use App\Jobs\SendApprovalRequestEmail;
|
|
use App\Models\TravelRequest;
|
|
use App\Models\TravelRequestApproval;
|
|
use App\Models\User;
|
|
|
|
class ApprovalService
|
|
{
|
|
public function submit(TravelRequest $travelRequest): void
|
|
{
|
|
$workflow = $travelRequest->workflow;
|
|
|
|
if (! $workflow) {
|
|
return;
|
|
}
|
|
|
|
$steps = $workflow->steps()->orderBy('order')->get();
|
|
|
|
foreach ($steps as $index => $step) {
|
|
TravelRequestApproval::create([
|
|
'travel_request_id' => $travelRequest->id,
|
|
'approval_step_id' => $step->id,
|
|
'approver_id' => null,
|
|
'status' => $index === 0 ? ApprovalStatus::Pending->value : null,
|
|
'comments' => null,
|
|
'acted_at' => null,
|
|
]);
|
|
}
|
|
|
|
$travelRequest->update([
|
|
'status' => TravelStatus::Pending,
|
|
'submitted_at' => now(),
|
|
]);
|
|
|
|
SendApprovalRequestEmail::dispatch($travelRequest, $steps->first()->role);
|
|
}
|
|
|
|
public function approve(TravelRequestApproval $approval, User $approver, ?string $comments): void
|
|
{
|
|
$approval->update([
|
|
'status' => ApprovalStatus::Approved,
|
|
'approver_id' => $approver->id,
|
|
'comments' => $comments,
|
|
'acted_at' => now(),
|
|
]);
|
|
|
|
$travelRequest = $approval->travelRequest;
|
|
|
|
$nextApproval = TravelRequestApproval::query()
|
|
->where('travel_request_id', $travelRequest->id)
|
|
->whereNull('status')
|
|
->with('step')
|
|
->orderBy('id')
|
|
->first();
|
|
|
|
if ($nextApproval) {
|
|
$nextApproval->update(['status' => ApprovalStatus::Pending->value]);
|
|
SendApprovalRequestEmail::dispatch($travelRequest, $nextApproval->step->role);
|
|
} else {
|
|
$travelRequest->update(['status' => TravelStatus::Approved]);
|
|
SendApprovalDecisionEmail::dispatch($travelRequest);
|
|
}
|
|
}
|
|
|
|
public function reject(TravelRequestApproval $approval, User $approver, ?string $comments): void
|
|
{
|
|
$approval->update([
|
|
'status' => ApprovalStatus::Rejected,
|
|
'approver_id' => $approver->id,
|
|
'comments' => $comments,
|
|
'acted_at' => now(),
|
|
]);
|
|
|
|
$approval->travelRequest->update(['status' => TravelStatus::Rejected]);
|
|
|
|
SendApprovalDecisionEmail::dispatch($approval->travelRequest);
|
|
}
|
|
}
|