netgescon-day0/app/Filament/Pages/Supporto/TicketScheda.php

280 lines
8.4 KiB
PHP

<?php
namespace App\Filament\Pages\Supporto;
use App\Models\Fornitore;
use App\Models\Ticket;
use App\Models\TicketAttachment;
use App\Models\TicketIntervento;
use App\Models\User;
use App\Support\StabileContext;
use BackedEnum;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use Livewire\WithFileUploads;
use UnitEnum;
class TicketScheda extends Page
{
use WithFileUploads;
protected static ?string $navigationLabel = 'Ticket Scheda';
protected static ?string $title = 'Scheda Ticket';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-ticket';
protected static UnitEnum|string|null $navigationGroup = 'Supporto';
protected static ?int $navigationSort = 27;
protected static ?string $slug = 'supporto/ticket-scheda';
protected static bool $shouldRegisterNavigation = true;
protected string $view = 'filament.pages.supporto.ticket-scheda';
public ?int $ticketId = null;
public ?string $notaInterna = null;
public ?int $fornitoreId = null;
public ?string $noteAssegnazione = null;
/** @var array<int,mixed> */
public array $nuoviAllegati = [];
public ?string $descrizioneAllegati = null;
/** @var array<int,array{id:int,nome:string}> */
public array $fornitoriOptions = [];
public static function canAccess(): bool
{
$user = Auth::user();
return $user instanceof User
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
}
public function mount(): void
{
$this->ticketId = (int) request()->query('ticket', 0) ?: null;
$this->redirect(
TicketGestione::getUrl(
parameters: [
'ticket' => $this->ticketId,
'tab' => 'scheda',
],
panel: 'admin-filament'
),
navigate: true
);
}
public function getTicketGestioneUrl(): string
{
return TicketGestione::getUrl(panel: 'admin-filament');
}
public function getTicketMobileUrl(): string
{
return TicketMobile::getUrl(panel: 'admin-filament');
}
public function getTicketProperty(): ?Ticket
{
if (! $this->ticketId) {
return null;
}
$user = Auth::user();
if (! $user instanceof User) {
return null;
}
$stabileId = StabileContext::resolveActiveStabileId($user);
if (! $stabileId) {
return null;
}
return Ticket::query()
->with([
'stabile:id,denominazione',
'categoriaTicket:id,nome',
'assegnatoAFornitore:id,ragione_sociale,nome,cognome',
'attachments.user:id,name',
'messages.user:id,name',
'interventi.fornitore:id,ragione_sociale,nome,cognome',
'interventi.creatoDaUser:id,name',
])
->where('stabile_id', $stabileId)
->find($this->ticketId);
}
public function assegnaFornitore(): void
{
$ticket = $this->ticket;
if (! $ticket) {
Notification::make()->title('Ticket non trovato')->danger()->send();
return;
}
$this->validate([
'fornitoreId' => ['required', 'integer', 'exists:fornitori,id'],
'noteAssegnazione' => ['nullable', 'string', 'max:4000'],
]);
$ticket->update([
'assegnato_a_fornitore_id' => $this->fornitoreId,
'stato' => in_array($ticket->stato, ['Aperto'], true) ? 'Preso in Carico' : $ticket->stato,
]);
if (Schema::hasTable('ticket_interventi')) {
$ultimo = TicketIntervento::query()
->where('ticket_id', $ticket->id)
->where('fornitore_id', $this->fornitoreId)
->latest('id')
->first();
if (! $ultimo) {
TicketIntervento::query()->create([
'ticket_id' => $ticket->id,
'fornitore_id' => $this->fornitoreId,
'creato_da_user_id' => Auth::id(),
'stato' => 'assegnato',
'note_amministratore' => $this->noteAssegnazione,
]);
}
}
if (filled($this->noteAssegnazione)) {
$ticket->messages()->create([
'user_id' => Auth::id(),
'messaggio' => 'Assegnazione fornitore: ' . trim((string) $this->noteAssegnazione),
]);
}
Notification::make()
->title('Fornitore assegnato')
->success()
->send();
$this->noteAssegnazione = null;
}
public function aggiungiNotaInterna(): void
{
$ticket = $this->ticket;
if (! $ticket) {
Notification::make()->title('Ticket non trovato')->danger()->send();
return;
}
$this->validate([
'notaInterna' => ['required', 'string', 'max:5000'],
]);
$ticket->messages()->create([
'user_id' => Auth::id(),
'messaggio' => trim((string) $this->notaInterna),
]);
$this->notaInterna = null;
Notification::make()
->title('Nota aggiunta')
->success()
->send();
}
public function caricaAllegati(): void
{
$ticket = $this->ticket;
if (! $ticket) {
Notification::make()->title('Ticket non trovato')->danger()->send();
return;
}
if (! Schema::hasTable('ticket_attachments')) {
Notification::make()
->title('Tabella allegati non pronta')
->danger()
->send();
return;
}
$this->validate([
'nuoviAllegati' => ['required', 'array', 'max:8'],
'nuoviAllegati.*' => ['file', 'max:10240', 'mimes:jpg,jpeg,png,webp,pdf,doc,docx,xls,xlsx,txt'],
'descrizioneAllegati' => ['nullable', 'string', 'max:500'],
]);
$saved = 0;
foreach ($this->nuoviAllegati as $file) {
if (! is_object($file) || ! method_exists($file, 'store')) {
continue;
}
$path = $file->store('ticket-scheda/' . $ticket->id, 'public');
TicketAttachment::query()->create([
'ticket_id' => $ticket->id,
'ticket_update_id' => null,
'user_id' => Auth::id(),
'file_path' => $path,
'original_file_name' => (string) $file->getClientOriginalName(),
'mime_type' => (string) $file->getClientMimeType(),
'size' => (int) $file->getSize(),
'description' => $this->descrizioneAllegati ?: 'Allegato da scheda ticket',
]);
$saved++;
}
$this->nuoviAllegati = [];
$this->descrizioneAllegati = null;
Notification::make()
->title('Allegati caricati')
->body('Caricati ' . $saved . ' allegati.')
->success()
->send();
}
private function loadFornitoriOptions(): void
{
$user = Auth::user();
if (! $user instanceof User) {
$this->fornitoriOptions = [];
return;
}
$stabileId = StabileContext::resolveActiveStabileId($user);
if (! $stabileId) {
$this->fornitoriOptions = [];
return;
}
$stabile = \App\Models\Stabile::query()->find($stabileId);
$adminId = (int) ($stabile->amministratore_id ?? 0);
$query = Fornitore::query()->orderBy('ragione_sociale')->orderBy('cognome')->orderBy('nome');
if ($adminId > 0) {
$query->where(function ($q) use ($adminId): void {
$q->where('amministratore_id', $adminId)->orWhereNull('amministratore_id');
});
}
$this->fornitoriOptions = $query->limit(400)->get()->map(function (Fornitore $f): array {
$label = trim((string) ($f->ragione_sociale ?: trim(($f->nome ?? '') . ' ' . ($f->cognome ?? ''))));
return [
'id' => (int) $f->id,
'nome' => $label !== '' ? $label : ('Fornitore #' . $f->id),
];
})->all();
}
}