|
|
@@ -0,0 +1,90 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Services;
|
|
|
+
|
|
|
+use App\Enums\SupportRequestStatusEnum;
|
|
|
+use App\Mail\SupportRequestAlert;
|
|
|
+use App\Models\SupportRequest;
|
|
|
+use Illuminate\Pagination\LengthAwarePaginator;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+use Illuminate\Support\Facades\Mail;
|
|
|
+
|
|
|
+class SupportRequestService
|
|
|
+{
|
|
|
+ public function paginate(
|
|
|
+ ?string $status = null,
|
|
|
+ ?string $search = null,
|
|
|
+ int $page = 1,
|
|
|
+ int $perPage = 10,
|
|
|
+ ): LengthAwarePaginator {
|
|
|
+ return SupportRequest::query()
|
|
|
+ ->with('handler:id,name')
|
|
|
+ ->when($status, fn ($query) => $query->where('status', $status))
|
|
|
+ ->when($search, function ($query) use ($search) {
|
|
|
+ $query->where(function ($sub) use ($search) {
|
|
|
+ $sub->where('title', 'like', "%{$search}%")
|
|
|
+ ->orWhere('name', 'like', "%{$search}%")
|
|
|
+ ->orWhere('email', 'like', "%{$search}%");
|
|
|
+ });
|
|
|
+ })
|
|
|
+ ->orderByRaw("CASE status WHEN 'pending' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'resolved' THEN 2 ELSE 3 END")
|
|
|
+ ->orderBy('created_at', 'desc')
|
|
|
+ ->paginate($perPage, ['*'], 'page', $page);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function findById(int $id): ?SupportRequest
|
|
|
+ {
|
|
|
+ return SupportRequest::with('handler')->find($id);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function create(array $data): SupportRequest
|
|
|
+ {
|
|
|
+ $data['status'] ??= SupportRequestStatusEnum::PENDING->value;
|
|
|
+
|
|
|
+ $supportRequest = SupportRequest::create($data);
|
|
|
+
|
|
|
+ $this->sendAlert($supportRequest);
|
|
|
+
|
|
|
+ return $supportRequest;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function updateStatus(int $id, string $status, ?int $handledBy = null): ?SupportRequest
|
|
|
+ {
|
|
|
+ $supportRequest = $this->findById($id);
|
|
|
+
|
|
|
+ if (! $supportRequest) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ $payload = ['status' => $status];
|
|
|
+
|
|
|
+ if ($status === SupportRequestStatusEnum::IN_PROGRESS->value && ! $supportRequest->handled_by) {
|
|
|
+ $payload['handled_by'] = $handledBy;
|
|
|
+ }
|
|
|
+
|
|
|
+ $payload['resolved_at'] = $status === SupportRequestStatusEnum::RESOLVED->value ? now() : null;
|
|
|
+
|
|
|
+ $supportRequest->update($payload);
|
|
|
+
|
|
|
+ return $supportRequest->fresh('handler');
|
|
|
+ }
|
|
|
+
|
|
|
+ private function sendAlert(SupportRequest $supportRequest): void
|
|
|
+ {
|
|
|
+ $recipient = config('services.support.email');
|
|
|
+
|
|
|
+ if (! $recipient) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ Mail::to($recipient)->send(new SupportRequestAlert($supportRequest));
|
|
|
+ } catch (\Throwable $e) {
|
|
|
+ // Alerta é best-effort: o registro no backoffice continua sendo a fonte da verdade.
|
|
|
+ Log::error('Support request alert email failed', [
|
|
|
+ 'support_request_id' => $supportRequest->id,
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|