|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; $candidates = CommunicationMessage::query() ->whereIn('channel', ['smdr', 'panasonic_csta']) ->where('direction', 'inbound') ->whereNotNull('received_at') ->where('received_at', '>=', now()->subMinutes(8)) ->where(function ($query): void { $query->whereNull('metadata->outcome') ->orWhere(function ($inner): void { $inner->where('metadata->outcome', 'not like', '%miss%') ->where('metadata->outcome', 'not like', '%no_answer%'); }); }) ->where(function ($query): void { $query->whereNull('message_text') ->orWhere('message_text', 'not like', '%persa%'); }) ->when($popupRestricted, function ($query) use ($watchedExtensions): void { $query->whereIn('target_extension', $watchedExtensions); }) ->latest('received_at') ->limit(30) ->get(['id', 'channel', 'status', 'phone_number', 'target_extension', 'received_at', 'message_text', 'metadata']); $latest = $candidates ->sortByDesc(function (CommunicationMessage $message): int { $metadata = is_array($message->metadata) ? $message->metadata : []; $eventType = strtolower(trim((string) ($metadata['event_type'] ?? ''))); $endedAt = trim((string) ($metadata['ended_at'] ?? '')); $isActiveCsta = (string) $message->channel === 'panasonic_csta' && (string) ($message->status ?? '') !== 'completed' && $endedAt === '' && ! in_array($eventType, ['connectioncleared', 'cleared', 'released'], true); if ($isActiveCsta) { return 5000000000 + (int) ($message->received_at?->getTimestamp() ?? 0); } $isRecentCsta = (string) $message->channel === 'panasonic_csta' && (int) ($message->received_at?->getTimestamp() ?? 0) >= now()->subSeconds(45)->getTimestamp(); if ($isRecentCsta) { return 4000000000 + (int) ($message->received_at?->getTimestamp() ?? 0); } return 1000000000 + (int) ($message->received_at?->getTimestamp() ?? 0); }) ->first(); 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 { return app(RubricaPhoneLookupService::class)->findByPhone($digits); } 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(); } }