netgescon-day0/app/Filament/Pages/Strumenti/PostIt.php

817 lines
30 KiB
PHP
Executable File

<?php
namespace App\Filament\Pages\Strumenti;
use App\Models\ChiamataPostIt;
use App\Models\Fornitore;
use App\Models\RubricaUniversale;
use App\Models\Stabile;
use App\Models\Ticket;
use App\Models\User;
use App\Services\Anagrafiche\RubricaPhoneLookupService;
use App\Support\PhoneNumber;
use App\Support\StabileContext;
use BackedEnum;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Database\QueryException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use UnitEnum;
class PostIt extends Page
{
protected static ?string $title = 'Post-it';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-document-text';
protected static ?string $slug = 'strumenti/post-it';
protected static bool $shouldRegisterNavigation = true;
protected static UnitEnum|string|null $navigationGroup = 'Strumenti';
protected static ?int $navigationSort = 10;
protected string $view = 'filament.pages.strumenti.post-it';
public ?string $telefono = null;
public ?string $nomeChiamante = null;
public ?string $ricercaChiamante = null;
public string $direzione = 'in_arrivo';
public ?string $esito = null;
public ?string $oggetto = null;
public ?string $nota = null;
public string $priorita = 'Media';
public ?int $rubricaId = null;
public ?int $stabileId = null;
public ?int $focusPostItId = null;
public ?int $selectedPostItId = null;
public string $assegnazioneTipo = 'operatore';
public ?int $assegnazioneUserId = null;
public ?int $assegnazioneFornitoreId = null;
public ?int $selectedSuggerimentoId = null;
public bool $disableAutoStabileAssociation = false;
/** @var \Illuminate\Support\Collection<int, RubricaUniversale> */
public $suggerimentiRubrica;
public function mount(): void
{
$this->priorita = 'Media';
$this->direzione = 'in_arrivo';
$this->suggerimentiRubrica = collect();
$focus = (int) request()->query('focus_post_it', 0);
$this->focusPostItId = $focus > 0 ? $focus : null;
$this->selectedPostItId = $this->focusPostItId;
$this->applyQueryPrefill();
}
public function getGestionePostItUrl(): string
{
return PostItGestione::getUrl(panel: 'admin-filament');
}
public function getGestioneTicketUrl(): string
{
return \App\Filament\Pages\Supporto\TicketGestione::getUrl(panel: 'admin-filament');
}
public function selectPostIt(int $postItId): void
{
$this->selectedPostItId = $postItId;
$this->loadSelectedPostItAssignment();
}
public function assegnaPostIt(): void
{
if (! $this->isPostItTableReady()) {
return;
}
$postIt = $this->selectedPostIt;
if (! $postIt) {
Notification::make()->title('Seleziona prima un Post-it')->warning()->send();
return;
}
$this->validate([
'assegnazioneTipo' => ['required', 'in:operatore,collaboratore,fornitore'],
'assegnazioneUserId' => ['nullable', 'integer', 'exists:users,id'],
'assegnazioneFornitoreId' => ['nullable', 'integer', 'exists:fornitori,id'],
]);
$payload = [
'assegnazione_tipo' => $this->assegnazioneTipo,
'assegnato_a_user_id' => null,
'assegnato_a_fornitore_id' => null,
];
if (in_array($this->assegnazioneTipo, ['operatore', 'collaboratore'], true)) {
if (! $this->assegnazioneUserId) {
Notification::make()->title('Seleziona un utente')->warning()->send();
return;
}
$payload['assegnato_a_user_id'] = $this->assegnazioneUserId;
}
if ($this->assegnazioneTipo === 'fornitore') {
if (! $this->assegnazioneFornitoreId) {
Notification::make()->title('Seleziona un fornitore')->warning()->send();
return;
}
$payload['assegnato_a_fornitore_id'] = $this->assegnazioneFornitoreId;
}
$postIt->update($payload);
if ($postIt->ticket) {
$ticketPayload = [];
if ($this->assegnazioneTipo === 'fornitore') {
$ticketPayload['assegnato_a_fornitore_id'] = $this->assegnazioneFornitoreId;
$ticketPayload['assegnato_a_user_id'] = null;
} else {
$ticketPayload['assegnato_a_user_id'] = $this->assegnazioneUserId;
}
if ($ticketPayload !== []) {
$postIt->ticket->update($ticketPayload);
}
if (method_exists($postIt->ticket, 'messages') && Schema::hasTable('ticket_messages')) {
$postIt->ticket->messages()->create([
'user_id' => Auth::id(),
'messaggio' => 'Assegnazione da Post-it: ' . $this->getSelectedAssignmentLabel(),
]);
}
}
Notification::make()->title('Assegnazione Post-it aggiornata')->success()->send();
$this->selectedPostItId = (int) $postIt->id;
}
public function isPostItTableReady(): bool
{
return Schema::hasTable('chiamate_post_it');
}
public function isPostItAssignmentReady(): bool
{
return $this->isPostItTableReady()
&& Schema::hasColumn('chiamate_post_it', 'assegnazione_tipo')
&& Schema::hasColumn('chiamate_post_it', 'assegnato_a_user_id')
&& Schema::hasColumn('chiamate_post_it', 'assegnato_a_fornitore_id');
}
public function updatedRicercaChiamante(?string $value): void
{
$query = trim((string) $value);
if ($query === '') {
$this->suggerimentiRubrica = collect();
$this->selectedSuggerimentoId = null;
return;
}
$this->suggerimentiRubrica = $this->searchRubrica($query);
if ($this->selectedSuggerimentoId && ! $this->suggerimentiRubrica->contains('id', $this->selectedSuggerimentoId)) {
$this->selectedSuggerimentoId = null;
}
}
public function updatedTelefono(?string $value): void
{
$input = trim((string) $value);
if ($input === '') {
$this->rubricaId = null;
$this->stabileId = null;
return;
}
$match = $this->findRubricaByPhone($input);
if (! $match) {
return;
}
$this->rubricaId = $match->id;
$this->selectedSuggerimentoId = $match->id;
if (blank($this->nomeChiamante)) {
$this->nomeChiamante = $match->nome_completo ?: $match->ragione_sociale;
}
if (! $this->disableAutoStabileAssociation) {
$stabile = Stabile::query()->where('rubrica_id', $match->id)->first();
if ($stabile) {
$this->stabileId = $stabile->id;
}
}
if (blank($this->ricercaChiamante)) {
$this->ricercaChiamante = $match->nome_completo ?: $match->ragione_sociale;
}
}
public function selezionaSuggerimentoRubrica(int $rubricaId): void
{
$match = $this->suggerimentiRubrica->firstWhere('id', $rubricaId);
if (! $match) {
$match = RubricaUniversale::query()->find($rubricaId);
}
if (! $match) {
return;
}
$this->selectedSuggerimentoId = (int) $match->id;
$this->rubricaId = (int) $match->id;
$this->nomeChiamante = $match->nome_completo ?: $match->ragione_sociale;
$this->telefono = $match->telefono_cellulare ?: ($match->telefono_ufficio ?: $match->telefono_casa);
$this->ricercaChiamante = $match->nome_completo ?: ($match->ragione_sociale ?: '');
if (! $this->disableAutoStabileAssociation) {
$stabile = Stabile::query()->where('rubrica_id', $match->id)->first();
$this->stabileId = $stabile?->id;
}
$this->suggerimentiRubrica = $this->searchRubrica((string) $this->ricercaChiamante);
}
public function salvaPostIt(): void
{
if (! $this->isPostItTableReady()) {
Notification::make()
->title('Tabella chiamate non pronta')
->body('Esegui prima le migrazioni per usare il nuovo Post-it chiamate.')
->danger()
->send();
return;
}
$this->validate([
'telefono' => ['nullable', 'string', 'max:32'],
'nomeChiamante' => ['nullable', 'string', 'max:255'],
'direzione' => ['required', 'in:in_arrivo,in_uscita,persa'],
'esito' => ['nullable', 'string', 'max:255'],
'oggetto' => ['required', 'string', 'max:255'],
'nota' => ['required', 'string'],
'priorita' => ['required', 'in:Bassa,Media,Alta,Urgente'],
'rubricaId' => ['nullable', 'integer', 'exists:rubrica_universale,id'],
'stabileId' => ['nullable', 'integer', 'exists:stabili,id'],
]);
try {
$this->createPostItRecord();
} catch (QueryException $e) {
Notification::make()
->title('Tabella chiamate non pronta')
->body('Esegui prima le migrazioni per usare il nuovo Post-it chiamate.')
->danger()
->send();
return;
}
$this->resetFormState();
Notification::make()
->title('Post-it salvato')
->success()
->send();
}
public function salvaEConvertiInTicket(): void
{
if (! $this->isPostItTableReady()) {
$this->creaTicketDirettoDaForm();
return;
}
$this->validate([
'telefono' => ['nullable', 'string', 'max:32'],
'nomeChiamante' => ['nullable', 'string', 'max:255'],
'direzione' => ['required', 'in:in_arrivo,in_uscita,persa'],
'esito' => ['nullable', 'string', 'max:255'],
'oggetto' => ['required', 'string', 'max:255'],
'nota' => ['required', 'string'],
'priorita' => ['required', 'in:Bassa,Media,Alta,Urgente'],
'rubricaId' => ['nullable', 'integer', 'exists:rubrica_universale,id'],
'stabileId' => ['required', 'integer', 'exists:stabili,id'],
]);
try {
$postIt = $this->createPostItRecord();
} catch (QueryException) {
Notification::make()
->title('Tabella chiamate non pronta')
->body('Esegui prima le migrazioni per usare il nuovo Post-it chiamate.')
->danger()
->send();
return;
}
$this->convertiInTicket((int) $postIt->id);
$this->resetFormState();
}
public function convertiInTicket(int $postItId): void
{
if (! $this->isPostItTableReady()) {
Notification::make()
->title('Tabella chiamate non pronta')
->body('Esegui prima le migrazioni per usare la gestione Post-it.')
->danger()
->send();
return;
}
$postIt = ChiamataPostIt::query()->find($postItId);
if (! $postIt) {
return;
}
if ($postIt->ticket_id) {
Notification::make()->title('Gia convertito in ticket')->warning()->send();
return;
}
if (! $postIt->stabile_id) {
Notification::make()
->title('Stabile mancante')
->body('Associa prima uno stabile al Post-it per poter creare il ticket.')
->danger()
->send();
return;
}
$ticket = Ticket::query()->create([
'stabile_id' => $postIt->stabile_id,
'aperto_da_user_id' => Auth::id(),
'assegnato_a_user_id' => $postIt->assegnazione_tipo !== 'fornitore' ? $postIt->assegnato_a_user_id : null,
'assegnato_a_fornitore_id' => $postIt->assegnazione_tipo === 'fornitore' ? $postIt->assegnato_a_fornitore_id : null,
'titolo' => $postIt->oggetto ?: ('Chiamata da ' . ($postIt->nome_chiamante ?: 'Contatto sconosciuto')),
'descrizione' => trim(($postIt->nota ?? '') . "\n\nRiferimento chiamata: #{$postIt->id}"),
'data_apertura' => now(),
'stato' => 'Aperto',
'priorita' => $postIt->priorita,
]);
$postIt->ticket_id = $ticket->id;
$postIt->stato = 'ticket';
$postIt->save();
Notification::make()
->title('Ticket creato')
->body("Ticket #{$ticket->id} creato dal Post-it #{$postIt->id}")
->success()
->send();
}
public function chiudiPostIt(int $postItId): void
{
if (! $this->isPostItTableReady()) {
return;
}
$postIt = ChiamataPostIt::query()->find($postItId);
if (! $postIt) {
return;
}
$postIt->stato = 'chiusa';
$postIt->save();
Notification::make()
->title('Post-it chiuso')
->success()
->send();
}
public function getRecentiProperty()
{
if (! $this->isPostItTableReady()) {
return collect();
}
try {
$items = ChiamataPostIt::query()
->with(['rubrica', 'stabile', 'ticket', 'creatoDa', 'assegnatoAUser:id,name', 'assegnatoAFornitore:id,ragione_sociale,nome,cognome'])
->orderByDesc('chiamata_il')
->limit(60)
->get();
$grouped = $items
->groupBy(fn(ChiamataPostIt $item): string => $this->buildRecenteGroupKey($item))
->map(function (Collection $group): array {
/** @var ChiamataPostIt $primary */
$primary = $group->first();
$callerLabel = $this->resolveRecenteCallerLabel($group);
$phoneLabel = $this->resolveRecentePhoneLabel($group);
return [
'primary' => $primary,
'items' => $group->values(),
'count' => $group->count(),
'caller_label' => $callerLabel,
'phone' => $phoneLabel,
'latest_at' => optional($primary->chiamata_il)->format('d/m/Y H:i'),
'contains_selected' => $this->selectedPostItId
? $group->contains(fn(ChiamataPostIt $item) : bool => (int) $item->id === (int) $this->selectedPostItId)
: false,
];
})
->values();
if (! $this->selectedPostItId && $grouped->isNotEmpty()) {
$first = $grouped->first();
$this->selectedPostItId = (int) ($this->focusPostItId ?: ($first['primary']->id ?? 0));
$this->loadSelectedPostItAssignment();
}
return $grouped;
} catch (QueryException) {
return collect();
}
}
public function getSelectedPostItProperty(): ?ChiamataPostIt
{
if (! $this->isPostItTableReady() || ! $this->selectedPostItId) {
return null;
}
return ChiamataPostIt::query()
->with(['stabile', 'ticket', 'assegnatoAUser:id,name', 'assegnatoAFornitore:id,ragione_sociale,nome,cognome'])
->find($this->selectedPostItId);
}
public function getOperatoriOptionsProperty(): array
{
return User::query()
->role(['super-admin', 'admin', 'amministratore'])
->orderBy('name')
->limit(100)
->pluck('name', 'id')
->map(fn($name): string => (string) $name)
->all();
}
public function getCollaboratoriOptionsProperty(): array
{
$adminId = $this->resolveCurrentAmministratoreId();
return User::query()
->whereHas('roles', function ($q): void {
$q->where('name', 'collaboratore');
})
->when($adminId > 0, function ($query) use ($adminId): void {
$query->whereHas('stabiliAssegnati', function ($inner) use ($adminId): void {
$inner->where('amministratore_id', $adminId);
});
})
->orderBy('name')
->limit(150)
->pluck('name', 'id')
->map(fn($name): string => (string) $name)
->all();
}
public function getFornitoriOptionsProperty(): array
{
$adminId = $this->resolveCurrentAmministratoreId();
return Fornitore::query()
->when($adminId > 0, fn($query) => $query->where('amministratore_id', $adminId))
->orderByRaw("COALESCE(ragione_sociale, CONCAT(COALESCE(nome, ''), ' ', COALESCE(cognome, '')))")
->limit(150)
->get(['id', 'ragione_sociale', 'nome', 'cognome'])
->mapWithKeys(function (Fornitore $fornitore): array {
$label = trim((string) ($fornitore->ragione_sociale ?: (($fornitore->nome ?? '') . ' ' . ($fornitore->cognome ?? ''))));
return [(int) $fornitore->id => ($label !== '' ? $label : ('Fornitore #' . $fornitore->id))];
})
->all();
}
private function creaTicketDirettoDaForm(): void
{
$this->validate([
'telefono' => ['nullable', 'string', 'max:32'],
'nomeChiamante' => ['nullable', 'string', 'max:255'],
'oggetto' => ['required', 'string', 'max:255'],
'nota' => ['required', 'string'],
'priorita' => ['required', 'in:Bassa,Media,Alta,Urgente'],
'stabileId' => ['required', 'integer', 'exists:stabili,id'],
]);
$ticket = Ticket::query()->create([
'stabile_id' => $this->stabileId,
'aperto_da_user_id' => Auth::id(),
'titolo' => $this->oggetto ?: ('Chiamata da ' . ($this->nomeChiamante ?: 'Contatto sconosciuto')),
'descrizione' => trim(($this->nota ?? '') . "\n\nOrigine: Ticket diretto da Post-it (tabella chiamate non disponibile)"),
'data_apertura' => now(),
'stato' => 'Aperto',
'priorita' => $this->priorita,
]);
Notification::make()
->title('Ticket creato senza tabella Post-it')
->body('Ticket #' . $ticket->id . ' creato. Appena pronta la tabella chiamate, potrai usare la gestione Post-it completa.')
->warning()
->send();
$this->resetFormState();
}
private function findRubricaByPhone(string $value): ?RubricaUniversale
{
return app(RubricaPhoneLookupService::class)->findByPhone($value);
}
private function createPostItRecord(): ChiamataPostIt
{
return ChiamataPostIt::query()->create([
'telefono' => $this->telefono ? PhoneNumber::toE164Italy($this->telefono) ?? $this->telefono : null,
'nome_chiamante' => $this->nomeChiamante,
'direzione' => $this->direzione,
'esito' => $this->esito,
'oggetto' => $this->oggetto,
'nota' => $this->nota,
'priorita' => $this->priorita,
'stato' => 'post_it',
'rubrica_id' => $this->rubricaId,
'stabile_id' => $this->stabileId,
'creato_da_user_id' => Auth::id(),
'chiamata_il' => now(),
]);
}
private function applyQueryPrefill(): void
{
$source = trim((string) request()->query('source', ''));
$this->disableAutoStabileAssociation = request()->boolean('lock_stabile') || $source === 'topbar_live_call';
$telefono = trim((string) request()->query('telefono', ''));
$nome = trim((string) request()->query('nome', ''));
$nota = trim((string) request()->query('nota', ''));
$oggetto = trim((string) request()->query('oggetto', ''));
$direzione = trim((string) request()->query('direzione', ''));
$rubricaId = (int) request()->query('rubrica_id', 0);
if ($telefono !== '') {
$this->telefono = $telefono;
}
if ($nome !== '') {
$this->nomeChiamante = $nome;
$this->ricercaChiamante = $nome;
}
if ($nota !== '') {
$this->nota = $nota;
}
if ($oggetto !== '') {
$this->oggetto = $oggetto;
}
if (in_array($direzione, ['in_arrivo', 'in_uscita', 'persa'], true)) {
$this->direzione = $direzione;
}
if ($rubricaId > 0) {
$rubrica = RubricaUniversale::query()->find($rubricaId);
if ($rubrica) {
$this->rubricaId = (int) $rubrica->id;
if ($this->nomeChiamante === null || trim((string) $this->nomeChiamante) === '') {
$this->nomeChiamante = $rubrica->nome_completo ?: $rubrica->ragione_sociale;
}
}
}
if ($this->disableAutoStabileAssociation) {
$this->stabileId = null;
}
if ($source === 'topbar_live_call' && $telefono !== '') {
$this->hydrateRubricaForPhonePrefill($telefono, $nome);
if ($this->nota === null || trim((string) $this->nota) === '') {
$this->nota = 'Chiamata in ingresso da ' . $telefono;
}
if ($this->oggetto === null || trim((string) $this->oggetto) === '') {
$this->oggetto = 'Chiamata in arrivo da valutare';
}
}
}
private function hydrateRubricaForPhonePrefill(string $phone, string $name = ''): void
{
$match = $this->findRubricaByPhone($phone);
if (! $match && $this->canCreateRubricaDraftFromPhone($phone)) {
$match = $this->createRubricaDraftFromPhone($phone, $name);
}
if (! $match) {
return;
}
$this->rubricaId = (int) $match->id;
if ($this->nomeChiamante === null || trim((string) $this->nomeChiamante) === '') {
$this->nomeChiamante = $match->nome_completo ?: $match->ragione_sociale;
}
if ($this->ricercaChiamante === null || trim((string) $this->ricercaChiamante) === '') {
$this->ricercaChiamante = $match->nome_completo ?: ($match->ragione_sociale ?: '');
}
}
private function canCreateRubricaDraftFromPhone(string $phone): bool
{
$digits = preg_replace('/\D+/', '', $phone) ?: '';
return strlen($digits) >= 6;
}
private function createRubricaDraftFromPhone(string $phone, string $name = ''): ?RubricaUniversale
{
$digits = preg_replace('/\D+/', '', $phone) ?: '';
if ($digits === '') {
return null;
}
$normalizedPhone = PhoneNumber::toE164Italy($phone) ?? $digits;
$adminId = $this->resolveCurrentAmministratoreId();
$cleanName = trim($name);
$payload = [
'amministratore_id' => $adminId > 0 ? $adminId : null,
'tipo_contatto' => str_contains($cleanName, ' ') ? 'persona_fisica' : 'persona_giuridica',
'telefono_cellulare' => $normalizedPhone,
'categoria' => 'altro',
'stato' => 'attivo',
'data_inserimento' => now()->toDateString(),
'data_ultima_modifica' => now()->toDateString(),
'creato_da' => Auth::id(),
'modificato_da' => Auth::id(),
'note_segreteria' => 'Bozza creata dal box Post-it in topbar per una chiamata in ingresso.',
];
if ($cleanName !== '' && str_contains($cleanName, ' ')) {
$parts = preg_split('/\s+/', $cleanName) ?: [];
$payload['nome'] = array_shift($parts) ?: null;
$payload['cognome'] = $parts !== [] ? implode(' ', $parts) : null;
} elseif ($cleanName !== '') {
$payload['ragione_sociale'] = $cleanName;
} else {
$payload['ragione_sociale'] = 'Contatto ' . $digits;
}
return RubricaUniversale::query()->create($payload);
}
private function buildRecenteGroupKey(ChiamataPostIt $item): string
{
$phone = preg_replace('/\D+/', '', (string) ($item->telefono ?? '')) ?: '';
if ($phone !== '') {
return 'phone:' . $phone;
}
if ((int) ($item->rubrica_id ?? 0) > 0) {
return 'rubrica:' . (int) $item->rubrica_id;
}
return 'caller:' . mb_strtolower(trim((string) ($item->nome_chiamante ?? 'sconosciuto')));
}
private function resolveRecenteCallerLabel(Collection $group): string
{
foreach ($group as $item) {
if ($item instanceof ChiamataPostIt && $item->rubrica) {
return $item->rubrica->nome_completo ?: ($item->rubrica->ragione_sociale ?: 'Contatto');
}
}
foreach ($group as $item) {
$label = trim((string) ($item->nome_chiamante ?? ''));
if ($label !== '' && ! $this->isGenericRecenteCallerLabel($label, (string) ($item->telefono ?? ''))) {
return $label;
}
}
return 'Contatto non in Rubrica';
}
private function resolveRecentePhoneLabel(Collection $group): string
{
foreach ($group as $item) {
$phone = trim((string) ($item->telefono ?? ''));
if ($phone !== '') {
return $phone;
}
}
return '';
}
private function isGenericRecenteCallerLabel(string $label, string $phone = ''): bool
{
$normalizedLabel = mb_strtolower(trim($label));
if ($normalizedLabel === '' || in_array($normalizedLabel, ['chiamante non identificato', 'contatto non in rubrica'], true)) {
return true;
}
$labelDigits = preg_replace('/\D+/', '', $label) ?: '';
$phoneDigits = preg_replace('/\D+/', '', $phone) ?: '';
return $labelDigits !== '' && $phoneDigits !== '' && $labelDigits === $phoneDigits;
}
private function loadSelectedPostItAssignment(): void
{
$postIt = $this->selectedPostIt;
if (! $postIt) {
return;
}
$this->assegnazioneTipo = (string) ($postIt->assegnazione_tipo ?: 'operatore');
$this->assegnazioneUserId = (int) ($postIt->assegnato_a_user_id ?? 0) ?: null;
$this->assegnazioneFornitoreId = (int) ($postIt->assegnato_a_fornitore_id ?? 0) ?: null;
}
private function getSelectedAssignmentLabel(): string
{
return match ($this->assegnazioneTipo) {
'fornitore' => 'fornitore #' . (int) ($this->assegnazioneFornitoreId ?? 0),
'collaboratore' => 'collaboratore #' . (int) ($this->assegnazioneUserId ?? 0),
default => 'operatore #' . (int) ($this->assegnazioneUserId ?? 0),
};
}
private function resolveCurrentAmministratoreId(): int
{
$user = Auth::user();
if (! $user instanceof User) {
return 0;
}
if ($user->amministratore) {
return (int) $user->amministratore->id;
}
$stabile = StabileContext::getActiveStabile($user);
return (int) ($stabile?->amministratore_id ?? 0);
}
private function resetFormState(): void
{
$this->telefono = null;
$this->nomeChiamante = null;
$this->ricercaChiamante = null;
$this->direzione = 'in_arrivo';
$this->esito = null;
$this->oggetto = null;
$this->nota = null;
$this->priorita = 'Media';
$this->rubricaId = null;
$this->stabileId = null;
$this->selectedSuggerimentoId = null;
$this->suggerimentiRubrica = collect();
}
/**
* @return Collection<int, RubricaUniversale>
*/
private function searchRubrica(string $value): Collection
{
$query = trim($value);
if ($query === '') {
return collect();
}
$digits = preg_replace('/\D+/', '', $query) ?: '';
$needleText = '%' . mb_strtolower($query) . '%';
$needleDigits = '%' . $digits . '%';
return RubricaUniversale::query()
->where(function ($q) use ($needleText, $needleDigits, $digits): void {
$q->orWhereRaw("LOWER(COALESCE(nome, '')) LIKE ?", [$needleText])
->orWhereRaw("LOWER(COALESCE(cognome, '')) LIKE ?", [$needleText])
->orWhereRaw("LOWER(COALESCE(ragione_sociale, '')) LIKE ?", [$needleText])
->orWhereRaw("LOWER(COALESCE(email, '')) LIKE ?", [$needleText]);
if ($digits !== '') {
$q->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_cellulare, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$needleDigits])
->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_ufficio, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$needleDigits])
->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_casa, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", [$needleDigits]);
}
})
->limit(8)
->get();
}
public static function canAccess(): bool
{
$user = Auth::user();
return $user instanceof User
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
}
}