netgescon-day0/app/Filament/Pages/Fornitore/RubricaClienti.php

249 lines
8.4 KiB
PHP

<?php
namespace App\Filament\Pages\Fornitore;
use App\Filament\Pages\Fornitore\Concerns\ResolvesOperatoreContext;
use App\Models\Fornitore;
use App\Models\TicketIntervento;
use App\Models\User;
use BackedEnum;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use UnitEnum;
class RubricaClienti extends Page
{
use ResolvesOperatoreContext;
protected static ?string $navigationLabel = 'Rubrica clienti';
protected static ?string $title = 'Rubrica clienti fornitore';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-phone';
protected static UnitEnum|string|null $navigationGroup = 'Fornitore';
protected static ?int $navigationSort = 3;
protected static ?string $slug = 'fornitore/rubrica-clienti';
protected string $view = 'filament.pages.fornitore.rubrica-clienti';
public ?int $fornitoreId = null;
public ?string $fornitoreLabel = null;
public bool $missingAdminContext = false;
public string $search = '';
/** @var array<int, array<string, mixed>> */
public array $rows = [];
/** @var array<string, mixed>|null */
public ?array $googleWorkspaceStatus = null;
public static function canAccess(): bool
{
$user = Auth::user();
return $user instanceof User
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'fornitore']);
}
public function mount(): void
{
[$fornitore] = $this->resolveOperatoreContext(allowAdminWithoutSupplier: true);
if (! $fornitore instanceof Fornitore) {
$this->missingAdminContext = true;
return;
}
$this->fornitoreId = (int) $fornitore->id;
$this->fornitoreLabel = $this->getFornitoreLabel($fornitore);
$this->googleWorkspaceStatus = $this->resolveGoogleWorkspaceStatus($fornitore);
$this->refreshRows();
}
public function updatedSearch(): void
{
$this->refreshRows();
}
public function refreshRows(): void
{
if (! $this->fornitoreId) {
$this->rows = [];
return;
}
$term = Str::lower(trim($this->search));
$items = TicketIntervento::query()
->with(['ticket.stabile', 'ticket.soggettoRichiedente', 'ticket.apertoDaUser'])
->where('fornitore_id', $this->fornitoreId)
->latest('updated_at')
->limit(250)
->get();
$grouped = [];
foreach ($items as $intervento) {
$contact = $this->resolveCallerDataForRubrica($intervento);
$key = $contact['identity_key'];
if ($key === '') {
$key = 'ticket-' . (int) $intervento->ticket_id;
}
if ($term !== '') {
$haystack = Str::lower(implode(' ', [
$contact['contatto'],
$contact['telefono'],
$contact['email'],
$contact['stabile'],
$contact['origine'],
]));
if (! Str::contains($haystack, $term)) {
continue;
}
}
if (! isset($grouped[$key])) {
$grouped[$key] = [
'contatto' => $contact['contatto'],
'telefono' => $contact['telefono'],
'email' => $contact['email'],
'stabile' => $contact['stabile'],
'origine' => $contact['origine'],
'rubrica_url' => $contact['rubrica_url'],
'rubrica_label' => $contact['rubrica_label'],
'ultimo_ticket_id' => (int) $intervento->ticket_id,
'ultima_scheda_url' => TicketInterventoScheda::getUrl(['record' => (int) $intervento->id], panel: 'admin-filament'),
'updated_at' => optional($intervento->updated_at)->format('d/m/Y H:i') ?: '-',
'totale_interventi' => 1,
];
continue;
}
$grouped[$key]['totale_interventi']++;
}
$this->rows = array_values($grouped);
}
public function getLavorazioniUrl(): string
{
return LavorazioniOperative::getUrl(['fornitore' => (int) $this->fornitoreId], panel: 'admin-filament');
}
public function getProdottiUrl(): string
{
return ProdottiCatalogo::getUrl(['fornitore' => (int) $this->fornitoreId], panel: 'admin-filament');
}
public function getGoogleConnectUrl(): string
{
return route('oauth.google.redirect', [
'account_key' => 'fornitore-' . (int) ($this->fornitoreId ?? 0),
'label' => trim((string) ($this->fornitoreLabel ?? '')) ?: ('Fornitore #' . (int) ($this->fornitoreId ?? 0)),
'return_to' => request()->getRequestUri(),
]);
}
public function getGoogleDisconnectUrl(): string
{
return route('oauth.google.disconnect', [
'account_key' => 'fornitore-' . (int) ($this->fornitoreId ?? 0),
'return_to' => request()->getRequestUri(),
]);
}
/**
* @return array<string, string>
*/
protected function resolveCallerDataForRubrica(TicketIntervento $intervento): array
{
$ticket = $intervento->ticket;
$parsed = $this->extractCallerData((string) ($ticket?->descrizione ?? ''));
$contatto = $parsed['contatto'];
$telefono = $parsed['telefono'];
$email = '';
$origine = 'Descrizione ticket';
$rubricaUrl = null;
$rubricaLabel = '';
if ($ticket?->soggettoRichiedente) {
$soggetto = $ticket->soggettoRichiedente;
$contatto = trim((string) ($soggetto->ragione_sociale ?: trim(($soggetto->nome ?? '') . ' ' . ($soggetto->cognome ?? '')))) ?: $contatto;
$telefono = trim((string) ($soggetto->telefono ?? '')) ?: $telefono;
$email = trim((string) ($soggetto->email ?? ''));
$origine = 'Richiedente ticket';
$rubricaUrl = $this->buildRubricaUrlForCurrentUser((int) $soggetto->id);
$rubricaLabel = trim((string) ($soggetto->categoria ?? ''));
} elseif ($ticket?->apertoDaUser) {
$contatto = trim((string) ($ticket->apertoDaUser->name ?? '')) ?: $contatto;
$email = trim((string) ($ticket->apertoDaUser->email ?? ''));
$origine = 'Utente apertura ticket';
}
$identityKey = '';
if ($ticket?->soggetto_richiedente_id) {
$identityKey = 'soggetto-' . (int) $ticket->soggetto_richiedente_id;
} elseif ($email !== '') {
$identityKey = 'email-' . Str::lower($email);
} elseif ($telefono !== '') {
$identityKey = 'phone-' . preg_replace('/\D+/', '', $telefono);
}
return [
'contatto' => $contatto !== '' ? $contatto : 'Contatto non identificato',
'telefono' => $telefono,
'email' => $email,
'origine' => $origine,
'stabile' => (string) ($ticket?->stabile?->denominazione ?? '-'),
'rubrica_url' => $rubricaUrl,
'rubrica_label' => $rubricaLabel,
'identity_key' => $identityKey,
];
}
protected function buildRubricaUrlForCurrentUser(int $rubricaId): ?string
{
$user = Auth::user();
if (! $user instanceof User) {
return null;
}
if ($user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore'])) {
return \App\Filament\Pages\Gescon\RubricaUniversaleScheda::getUrl(['record' => $rubricaId], panel: 'admin-filament');
}
return null;
}
/**
* @return array<string, mixed>|null
*/
protected function resolveGoogleWorkspaceStatus(Fornitore $fornitore): ?array
{
$amministratore = $fornitore->amministratore;
if (! $amministratore) {
return null;
}
$oauth = (array) (($amministratore->impostazioni['google']['oauth'] ?? null) ?: []);
return [
'connected' => (bool) ($oauth['connected'] ?? false),
'email' => (string) ($oauth['email'] ?? ''),
'name' => (string) ($oauth['name'] ?? ''),
'connected_at' => (string) ($oauth['connected_at'] ?? ''),
];
}
}