|null */ public function getForUser(User $user): ?array { $userExtension = trim((string) ($user->pbx_extension ?? '')); $watchedExtensions = app(PbxRoutingService::class)->getWatchedExtensionsForUser($user); $popupRestricted = (bool) ($user->pbx_popup_enabled ?? false) && count($watchedExtensions) > 0; $latest = CommunicationMessage::query() ->whereIn('channel', ['smdr', 'panasonic_csta']) ->where('direction', 'inbound') ->whereNotNull('received_at') ->where('received_at', '>=', now()->subMinutes(8)) ->when($popupRestricted, function ($query) use ($watchedExtensions): void { $query->whereIn('target_extension', $watchedExtensions); }) ->latest('id') ->first(['id', 'phone_number', 'target_extension', 'received_at', 'message_text', 'metadata']); if (! $latest) { return null; } $phone = $this->normalizePhoneDigits((string) ($latest->phone_number ?? '')); if ($phone === '') { $phone = $this->normalizePhoneDigits((string) data_get($latest->metadata, 'smdr.dial_number', '')); } if ($phone === '') { return null; } $rubrica = $this->matchRubricaByPhone($phone); $soggetto = $this->matchSoggetto($rubrica, $phone); return [ 'message_id' => (int) $latest->id, 'phone' => $phone, 'received_at' => optional($latest->received_at)->format('d/m/Y H:i:s'), 'line' => (string) ($latest->message_text ?? ''), 'target_extension' => (string) ($latest->target_extension ?? ''), 'rubrica_id' => (int) ($rubrica?->id ?? 0), 'rubrica_nome' => (string) ($rubrica?->nome_completo ?: $rubrica?->ragione_sociale ?: ''), 'soggetto_id' => (int) ($soggetto?->id ?? 0), 'can_click_to_call' => (bool) ($user->pbx_click_to_call_enabled ?? false) && $userExtension !== '', 'ticket_mobile_url' => TicketMobile::getUrl([ 'live_phone' => $phone, 'live_message_id' => (int) $latest->id, 'live_note' => (string) ($latest->message_text ?? ''), ], panel: 'admin-filament'), 'rubrica_url' => (int) ($rubrica?->id ?? 0) > 0 ? \App\Filament\Pages\Gescon\RubricaUniversaleScheda::getUrl(['record' => (int) $rubrica->id], panel: 'admin-filament') : null, 'estratto_conto_url' => (int) ($soggetto?->id ?? 0) > 0 ? \App\Filament\Pages\Contabilita\EstrattoContoSoggetto::getUrl(['record' => (int) $soggetto->id], panel: 'admin-filament') : null, 'post_it_redirect_url' => TicketMobile::getUrl([ 'live_phone' => $phone, 'live_message_id' => (int) $latest->id, 'live_note' => (string) ($latest->message_text ?? ''), 'live_action' => 'post-it', ], panel: 'admin-filament'), ]; } private function normalizePhoneDigits(string $value): string { return preg_replace('/\D+/', '', $value) ?: ''; } private function matchRubricaByPhone(string $digits): ?RubricaUniversale { if ($digits === '') { return null; } $needle = '%' . $digits . '%'; $tail = strlen($digits) >= 7 ? substr($digits, -7) : $digits; $tailNeedle = '%' . $tail . '%'; return RubricaUniversale::query() ->where(function ($query) use ($needle, $tailNeedle): void { $query->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_cellulare, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$needle]) ->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_ufficio, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$needle]) ->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_casa, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$needle]) ->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_cellulare, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$tailNeedle]) ->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_ufficio, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$tailNeedle]) ->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_casa, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$tailNeedle]); }) ->orderByDesc('updated_at') ->first(); } private function matchSoggetto(?RubricaUniversale $rubrica, string $phone): ?Soggetto { if ($rubrica) { $cf = trim((string) ($rubrica->codice_fiscale ?? '')); if ($cf !== '') { $found = Soggetto::query()->where('codice_fiscale', $cf)->first(); if ($found) { return $found; } } $piva = trim((string) ($rubrica->partita_iva ?? '')); if ($piva !== '') { $found = Soggetto::query()->where('partita_iva', $piva)->first(); if ($found) { return $found; } } } $tail = strlen($phone) >= 7 ? substr($phone, -7) : $phone; if ($tail === '') { return null; } return Soggetto::query()->where('telefono', 'like', '%' . $tail . '%')->first(); } }