217 lines
7.9 KiB
PHP
217 lines
7.9 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources\Feedback\Pages;
|
|
|
|
use App\Filament\Resources\Feedback\FeedbackResource;
|
|
use App\Models\Department;
|
|
use App\Services\ClosingService;
|
|
use App\Services\TransferService;
|
|
use Filament\Actions\Action;
|
|
use Filament\Actions\DeleteAction;
|
|
use Filament\Forms\Components\FileUpload;
|
|
use Filament\Forms\Components\Select;
|
|
use Filament\Forms\Components\Textarea;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Resources\Pages\EditRecord;
|
|
use Illuminate\Contracts\View\View;
|
|
use Illuminate\Support\Facades\App;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class EditFeedback extends EditRecord
|
|
{
|
|
protected static string $resource = FeedbackResource::class;
|
|
|
|
protected function getHeaderActions(): array
|
|
{
|
|
return [
|
|
$this->transferDepartmentAction(),
|
|
$this->closeTicketAction(),
|
|
DeleteAction::make(),
|
|
];
|
|
}
|
|
|
|
protected function transferDepartmentAction(): Action
|
|
{
|
|
return Action::make('transferDepartment')
|
|
->label(__('feedback.transfer_department'))
|
|
->icon('heroicon-o-arrows-right-left')
|
|
->color('warning')
|
|
->visible(fn (): bool => auth()->user()->hasPermissionTo('transfer-department'))
|
|
->form([
|
|
Select::make('to_department_id')
|
|
->label(__('feedback.target_department'))
|
|
->options(Department::pluck('name', 'id')->toArray())
|
|
->required()
|
|
->searchable(),
|
|
Select::make('new_assignee_id')
|
|
->label(__('feedback.assign_to_optional'))
|
|
->options(function (\Filament\Forms\Get $get) {
|
|
$deptId = $get('to_department_id');
|
|
if (! $deptId) {
|
|
return [];
|
|
}
|
|
$dept = Department::with('manager')->find($deptId);
|
|
|
|
return \App\Models\User::pluck('name', 'id')->toArray();
|
|
})
|
|
->searchable()
|
|
->nullable(),
|
|
Textarea::make('reason')
|
|
->label(__('feedback.reason'))
|
|
->required()
|
|
->rows(3),
|
|
FileUpload::make('transfer_attachments')
|
|
->label(__('app.attachments'))
|
|
->multiple()
|
|
->disk('public')
|
|
->directory('feedback-attachments')
|
|
->acceptedFileTypes(['image/jpeg', 'image/png', 'application/pdf', 'video/mp4', 'video/quicktime'])
|
|
->maxSize(51200) // 50MB in KB
|
|
->columnSpanFull(),
|
|
])
|
|
->action(function (array $data): void {
|
|
$feedback = $this->getRecord();
|
|
$toDepartment = Department::findOrFail($data['to_department_id']);
|
|
$sender = auth()->user();
|
|
|
|
$transferService = App::make(TransferService::class);
|
|
$log = $transferService->transfer(
|
|
$feedback,
|
|
$toDepartment,
|
|
$data['reason'],
|
|
$sender,
|
|
$data['new_assignee_id'] ?? null,
|
|
);
|
|
|
|
if (! empty($data['transfer_attachments'])) {
|
|
$disk = Storage::disk('public');
|
|
foreach ($data['transfer_attachments'] as $path) {
|
|
if (! $disk->exists($path)) {
|
|
continue;
|
|
}
|
|
|
|
$feedback->attachments()->create([
|
|
'uuid' => (string) \Illuminate\Support\Str::uuid(),
|
|
'user_id' => $sender->id,
|
|
'name' => basename($path),
|
|
'path' => $path,
|
|
'disk' => 'public',
|
|
'collection' => 'general',
|
|
'mime_type' => $disk->mimeType($path),
|
|
'size' => $disk->size($path),
|
|
]);
|
|
}
|
|
}
|
|
|
|
Notification::make()
|
|
->title(__('feedback.transferred_successfully'))
|
|
->success()
|
|
->send();
|
|
|
|
$this->redirect($this->getResource()::getUrl('edit', ['record' => $feedback]));
|
|
});
|
|
}
|
|
|
|
protected function closeTicketAction(): Action
|
|
{
|
|
return Action::make('closeTicket')
|
|
->label(__('feedback.close_ticket'))
|
|
->icon('heroicon-o-check-circle')
|
|
->color('success')
|
|
->visible(fn (): bool => $this->getRecord()->status !== 'closed' && auth()->user()->hasPermissionTo('close-ticket'))
|
|
->requiresConfirmation()
|
|
->modalHeading(__('feedback.close_ticket'))
|
|
->modalDescription(__('feedback.close_confirm'))
|
|
->modalSubmitActionLabel(__('feedback.close_submit'))
|
|
->action(function (): void {
|
|
$feedback = $this->getRecord();
|
|
$actor = auth()->user();
|
|
|
|
$closingService = App::make(ClosingService::class);
|
|
|
|
try {
|
|
$closingService->close($feedback, $actor);
|
|
|
|
Notification::make()
|
|
->title(__('feedback.closed_successfully'))
|
|
->success()
|
|
->send();
|
|
|
|
$this->redirect($this->getResource()::getUrl('edit', ['record' => $feedback]));
|
|
} catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) {
|
|
Notification::make()
|
|
->title($e->getMessage())
|
|
->danger()
|
|
->send();
|
|
} catch (\Illuminate\Validation\ValidationException $e) {
|
|
Notification::make()
|
|
->title($e->getMessage())
|
|
->danger()
|
|
->send();
|
|
}
|
|
});
|
|
}
|
|
|
|
public function getFooter(): ?View
|
|
{
|
|
return view('filament.resources.feedback.edit-footer');
|
|
}
|
|
|
|
protected array $pendingAttachments = [];
|
|
protected string $pendingCollection = 'general';
|
|
|
|
protected function mutateFormDataBeforeSave(array $data): array
|
|
{
|
|
if (($data['is_general'] ?? false) === true) {
|
|
$data['customer_product_id'] = null;
|
|
}
|
|
|
|
$this->pendingAttachments = $data['attachments'] ?? [];
|
|
$this->pendingCollection = $data['attachment_collection'] ?? 'general';
|
|
|
|
unset($data['is_general'], $data['attachment_collection'], $data['attachments']);
|
|
|
|
$newStatus = $data['status'] ?? null;
|
|
if ($newStatus === 'closed' && $this->getRecord()->status !== 'closed') {
|
|
$closingService = App::make(ClosingService::class);
|
|
$closingService->close($this->getRecord(), auth()->user());
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
protected function afterSave(): void
|
|
{
|
|
if (empty($this->pendingAttachments)) {
|
|
return;
|
|
}
|
|
|
|
$disk = Storage::disk('public');
|
|
$feedback = $this->getRecord();
|
|
|
|
foreach ($this->pendingAttachments as $path) {
|
|
if (! $disk->exists($path)) {
|
|
continue;
|
|
}
|
|
|
|
$feedback->attachments()->create([
|
|
'uuid' => (string) \Illuminate\Support\Str::uuid(),
|
|
'user_id' => auth()->id(),
|
|
'name' => basename($path),
|
|
'path' => $path,
|
|
'disk' => 'public',
|
|
'collection' => $this->pendingCollection,
|
|
'mime_type' => $disk->mimeType($path),
|
|
'size' => $disk->size($path),
|
|
]);
|
|
}
|
|
}
|
|
|
|
protected function mutateFormDataBeforeFill(array $data): array
|
|
{
|
|
$data['is_general'] = $data['customer_product_id'] === null;
|
|
|
|
return $data;
|
|
}
|
|
}
|