135 lines
4.5 KiB
PHP
135 lines
4.5 KiB
PHP
<?php
|
|
namespace App\Support\Livewire;
|
|
|
|
use App\Models\RubricaUniversale;
|
|
use BackedEnum;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Str;
|
|
|
|
trait SupportsRubricaLookup
|
|
{
|
|
/**
|
|
* Normalizza input Livewire eterogenei in una stringa di ricerca stabile.
|
|
*/
|
|
protected function normalizeRubricaLookupText($value): string
|
|
{
|
|
if (is_array($value)) {
|
|
$value = Arr::first(Arr::flatten($value));
|
|
}
|
|
|
|
if ($value instanceof BackedEnum) {
|
|
$value = $value->value;
|
|
}
|
|
|
|
if (! is_scalar($value) && $value !== null) {
|
|
return '';
|
|
}
|
|
|
|
return trim((string) ($value ?? ''));
|
|
}
|
|
|
|
protected function normalizeRubricaLookupId($value): ?int
|
|
{
|
|
$normalized = $this->normalizeRubricaLookupText($value);
|
|
if ($normalized === '' || ! is_numeric($normalized)) {
|
|
return null;
|
|
}
|
|
|
|
$id = (int) $normalized;
|
|
return $id > 0 ? $id : null;
|
|
}
|
|
|
|
protected function formatRubricaLookupLabel(?RubricaUniversale $rubrica): string
|
|
{
|
|
if (! $rubrica instanceof RubricaUniversale) {
|
|
return '';
|
|
}
|
|
|
|
$label = trim((string) ($rubrica->ragione_sociale ?: $rubrica->nome_completo));
|
|
return $label !== '' ? $label : ('Rubrica #' . (int) $rubrica->id);
|
|
}
|
|
|
|
/**
|
|
* Mappa una riga rubrica in un payload leggero e riusabile nelle dropdown live.
|
|
*
|
|
* @return array<string,mixed>
|
|
*/
|
|
protected function mapRubricaLookupRow(RubricaUniversale $rubrica): array
|
|
{
|
|
$phone = trim((string) ($rubrica->telefono_ufficio ?: $rubrica->telefono_cellulare ?: $rubrica->telefono_casa));
|
|
|
|
return [
|
|
'id' => (int) $rubrica->id,
|
|
'label' => $this->formatRubricaLookupLabel($rubrica),
|
|
'email' => trim((string) ($rubrica->email ?? '')),
|
|
'phone' => $phone,
|
|
'category' => (string) ($rubrica->categoria ?? ''),
|
|
'note' => Str::limit(trim((string) ($rubrica->note ?? '')), 100),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Ricerca libera su rubrica con deduplica label e fallback sulla selezione corrente.
|
|
*
|
|
* @param array<int,string> $categories
|
|
* @return array<int,array<string,mixed>>
|
|
*/
|
|
protected function searchRubricaLookupMatches(string $raw, ?int $selectedId = null, array $categories = ['assicurazione', 'fornitore', 'altro'], int $limit = 12): array
|
|
{
|
|
$raw = $this->normalizeRubricaLookupText($raw);
|
|
|
|
if ($raw === '') {
|
|
if (($selectedId ?? 0) > 0) {
|
|
$selected = RubricaUniversale::query()->find($selectedId);
|
|
return $selected instanceof RubricaUniversale ? [$this->mapRubricaLookupRow($selected)] : [];
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
$needle = '%' . mb_strtolower($raw) . '%';
|
|
$digits = preg_replace('/\D+/', '', $raw) ?: '';
|
|
$seen = [];
|
|
$rows = [];
|
|
|
|
$matches = RubricaUniversale::query()
|
|
->whereNull('deleted_at')
|
|
->whereIn('categoria', $categories)
|
|
->where(function ($query) use ($needle, $digits): void {
|
|
$query->whereRaw("LOWER(COALESCE(ragione_sociale, '')) LIKE ?", [$needle])
|
|
->orWhereRaw("LOWER(COALESCE(nome, '')) LIKE ?", [$needle])
|
|
->orWhereRaw("LOWER(COALESCE(cognome, '')) LIKE ?", [$needle])
|
|
->orWhereRaw("LOWER(COALESCE(email, '')) LIKE ?", [$needle])
|
|
->orWhereRaw("LOWER(COALESCE(note, '')) LIKE ?", [$needle]);
|
|
|
|
if ($digits !== '') {
|
|
$query->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_ufficio, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", ['%' . $digits . '%'])
|
|
->orWhereRaw("REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE(telefono_cellulare, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '') LIKE ?", ['%' . $digits . '%']);
|
|
}
|
|
})
|
|
->orderBy('ragione_sociale')
|
|
->orderBy('cognome')
|
|
->orderBy('nome')
|
|
->limit(80)
|
|
->get();
|
|
|
|
foreach ($matches as $rubrica) {
|
|
$row = $this->mapRubricaLookupRow($rubrica);
|
|
$key = mb_strtolower(trim((string) $row['label']));
|
|
|
|
if ($key === '' || isset($seen[$key])) {
|
|
continue;
|
|
}
|
|
|
|
$seen[$key] = true;
|
|
$rows[] = $row;
|
|
|
|
if (count($rows) >= $limit) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
}
|