159 lines
4.7 KiB
PHP
159 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Requests;
|
|
|
|
use App\Models\RequestComment;
|
|
use App\Models\ServiceRequest;
|
|
use App\Models\Status;
|
|
use App\Services\NotificationService;
|
|
use App\Services\RequestService;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Component;
|
|
|
|
#[Layout('layouts.app')]
|
|
class RequestShowPage extends Component
|
|
{
|
|
public ServiceRequest $request;
|
|
|
|
public string $commentBody = '';
|
|
|
|
public bool $commentInternal = false;
|
|
|
|
public string $nextStatusId = '';
|
|
|
|
public ?int $rating = null;
|
|
|
|
public string $ratingComment = '';
|
|
|
|
public function mount(ServiceRequest $request): void
|
|
{
|
|
Gate::authorize('view', $request);
|
|
$this->request = $request->load([
|
|
'type',
|
|
'priority',
|
|
'status',
|
|
'client',
|
|
'assignee',
|
|
'equipment.category',
|
|
'comments.user',
|
|
'attachments.user',
|
|
]);
|
|
}
|
|
|
|
public function addComment(NotificationService $notificationService): void
|
|
{
|
|
Gate::authorize('update', $this->request);
|
|
|
|
$data = $this->validate([
|
|
'commentBody' => ['required', 'string', 'max:5000'],
|
|
'commentInternal' => ['nullable', 'boolean'],
|
|
]);
|
|
|
|
if (($data['commentInternal'] ?? false) && !auth()->user()->isStaff()) {
|
|
abort(403);
|
|
}
|
|
|
|
$comment = $this->request->comments()->create([
|
|
'user_id' => auth()->id(),
|
|
'body' => $data['commentBody'],
|
|
'is_internal' => (bool) ($data['commentInternal'] ?? false),
|
|
]);
|
|
|
|
$this->commentBody = '';
|
|
$this->commentInternal = false;
|
|
|
|
$notificationService->notifyCommentAdded($this->request->fresh(['assignee', 'client']), auth()->user());
|
|
|
|
session()->flash('success', 'Комментарий добавлен.');
|
|
|
|
$this->request->refresh();
|
|
}
|
|
|
|
public function deleteComment(int $commentId): void
|
|
{
|
|
$comment = RequestComment::query()->findOrFail($commentId);
|
|
|
|
abort_unless($comment->user_id === auth()->id(), 403);
|
|
|
|
$comment->delete();
|
|
session()->flash('success', 'Комментарий удален.');
|
|
$this->request->refresh();
|
|
}
|
|
|
|
public function changeStatus(RequestService $requestService): void
|
|
{
|
|
Gate::authorize('update', $this->request);
|
|
|
|
if ($this->nextStatusId === '') {
|
|
return;
|
|
}
|
|
|
|
$target = Status::query()->findOrFail($this->nextStatusId);
|
|
|
|
$allowed = $requestService->allowedTransitions($this->request->fresh('status'), auth()->user());
|
|
|
|
if (!in_array($target->slug, $allowed, true)) {
|
|
abort(422, 'Переход статуса недоступен.');
|
|
}
|
|
|
|
$requestService->changeStatus($this->request, $target, auth()->user());
|
|
|
|
$this->nextStatusId = '';
|
|
session()->flash('success', 'Статус обновлен.');
|
|
$this->request->refresh();
|
|
}
|
|
|
|
public function submitRating(): void
|
|
{
|
|
Gate::authorize('rate', $this->request);
|
|
|
|
$data = $this->validate([
|
|
'rating' => ['required', 'integer', 'between:1,5'],
|
|
'ratingComment' => ['nullable', 'string', 'max:2000'],
|
|
]);
|
|
|
|
$this->request->update([
|
|
'client_rating' => $data['rating'],
|
|
'client_comment' => $data['ratingComment'] ?? null,
|
|
]);
|
|
|
|
session()->flash('success', 'Спасибо за оценку заявки.');
|
|
$this->request->refresh();
|
|
}
|
|
|
|
private function allowedStatuses()
|
|
{
|
|
$requestService = app(RequestService::class);
|
|
|
|
$slugs = $requestService->allowedTransitions($this->request->fresh('status'), auth()->user());
|
|
|
|
return Status::query()->whereIn('slug', $slugs)->orderBy('sort_order')->get();
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$isClient = auth()->user()->isClient();
|
|
|
|
$comments = $this->request->comments()
|
|
->with('user')
|
|
->when($isClient, fn ($q) => $q->where('is_internal', false))
|
|
->latest()
|
|
->get();
|
|
|
|
return view('livewire.requests.request-show-page', [
|
|
'allowedStatuses' => $this->allowedStatuses(),
|
|
'comments' => $comments,
|
|
'activity' => $this->request->id
|
|
? \App\Models\ActivityLog::query()
|
|
->where('model_type', ServiceRequest::class)
|
|
->where('model_id', $this->request->id)
|
|
->with('user')
|
|
->latest('created_at')
|
|
->limit(20)
|
|
->get()
|
|
: collect(),
|
|
])->title("Заявка {$this->request->ticket_number}");
|
|
}
|
|
}
|